Flask First-Timer

123
Test Slide. Thanks C J SS

Transcript of Flask First-Timer

Page 1: Flask First-Timer

Test Slide. Thanks C J SS

Page 2: Flask First-Timer

The year was 1994. I was a student at UIC. There was a buzz in the lab where I work. Mosaic had been out for 6 months. Now there was a new version of BBEdit out that had support for HTML. I already wanted to learn perl so I thought this would be a great opportunity to write a perl CGI program for the Daleks game.

1994

Page 3: Flask First-Timer

The year was 1994. I was a student at UIC. There was a buzz in the lab where I work. Mosaic had been out for 6 months. Now there was a new version of BBEdit out that had support for HTML. I already wanted to learn perl so I thought this would be a great opportunity to write a perl CGI program for the Daleks game.

buzz

Page 4: Flask First-Timer

The year was 1994. I was a student at UIC. There was a buzz in the lab where I work. Mosaic had been out for 6 months. Now there was a new version of BBEdit out that had support for HTML. I already wanted to learn perl so I thought this would be a great opportunity to write a perl CGI program for the Daleks game.

Mosaic

Page 5: Flask First-Timer

The year was 1994. I was a student at UIC. There was a buzz in the lab where I work. Mosaic had been out for 6 months. Now there was a new version of BBEdit out that had support for HTML. I already wanted to learn perl so I thought this would be a great opportunity to write a perl CGI program for the Daleks game.

BBEdit

Page 6: Flask First-Timer

The year was 1994. I was a student at UIC. There was a buzz in the lab where I work. Mosaic had been out for 6 months. Now there was a new version of BBEdit out that had support for HTML. I already wanted to learn perl so I thought this would be a great opportunity to write a perl CGI program for the Daleks game.

HTML

Page 7: Flask First-Timer

The year was 1994. I was a student at UIC. There was a buzz in the lab where I work. Mosaic had been out for 6 months. Now there was a new version of BBEdit out that had support for HTML. I already wanted to learn perl so I thought this would be a great opportunity to write a perl CGI program for the Daleks game.

perl

Page 8: Flask First-Timer

The year was 1994. I was a student at UIC. There was a buzz in the lab where I work. Mosaic had been out for 6 months. Now there was a new version of BBEdit out that had support for HTML. I already wanted to learn perl so I thought this would be a great opportunity to write a perl CGI program for the Daleks game.

daleks

Page 9: Flask First-Timer

If you don't know the Daleks game, it's a simple game where you're on a grid you avoid the killer robots by making them run into each other. You make a move, and then the computers make a move. It's a great game with which to learn a new language or new environment. Since I didn't know how to save data on the server I passed the entire board as the part of the query string.

 

http://www.isaacsukin.com/news/2012/01/daleks-robot-puzzle-game

Page 10: Flask First-Timer

If you don't know the Daleks game, it's a simple game where you're on a grid you avoid the killer robots by making them run into each other. You make a move, and then the computers make a move. It's a great game with which to learn a new language or new environment. Since I didn't know how to save data on the server I passed the entire board as the part of the query string.

sessions

Page 11: Flask First-Timer

If you don't know the Daleks game, it's a simple game where you're on a grid you avoid the killer robots by making them run into each other. You make a move, and then the computers make a move. It's a great game with which to learn a new language or new environment. Since I didn't know how to save data on the server I passed the entire board as the part of the query string.

http://example.com/cgi-bin/robots.pl?board=..R..X..RR.R

Page 12: Flask First-Timer

Since I didn't understand forms yet, all commands were simple anchor tags:

<a href="/cgi-bin/robots.pl?board=.R.X..&command=left">Move Left</a>

<a href="/cgi-bin/robots.pl?board=.R.X..&command=right">Move Right</a>

<a href="/cgi-bin/robots.pl?board=.R.X..&command=NewGame">New Game</a>

Page 13: Flask First-Timer

The program worked great, and we enjoyed playing it. I learned perl and HTML and CGI programming at the same time. I also learned that it caused someone else's server to run out of disk space. Another student decided he wanted to learn how to write a web crawler. He'd search for links on a page, log each one to a file, and then follow them. His crawler found my robots program, and got addicted. Happily playing game after game and logging each move until it ran out of disk space. Oops!

Page 14: Flask First-Timer

The program worked great, and we enjoyed playing it. I learned perl and HTML and CGI programming at the same time. I also learned that it caused someone else's server to run out of disk space. Another student decided he wanted to learn how to write a web crawler. He'd search for links on a page, log each one to a file, and then follow them. His crawler found my robots program, and got addicted. Happily playing game after game and logging each move until it ran out of disk space. Oops!

learned

Page 15: Flask First-Timer

The program worked great, and we enjoyed playing it. I learned perl and HTML and CGI programming at the same time. I also learned that it caused someone else's server to run out of disk space. Another student decided he wanted to learn how to write a web crawler. He'd search for links on a page, log each one to a file, and then follow them. His crawler found my robots program, and got addicted. Happily playing game after game and logging each move until it ran out of disk space. Oops!

disk space

Page 16: Flask First-Timer

The program worked great, and we enjoyed playing it. I learned perl and HTML and CGI programming at the same time. I also learned that it caused someone else's server to run out of disk space. Another student decided he wanted to learn how to write a web crawler. He'd search for links on a page, log each one to a file, and then follow them. His crawler found my robots program, and got addicted. Happily playing game after game and logging each move until it ran out of disk space. Oops!

crawler

Page 17: Flask First-Timer

Hello. My name is Aijaz, and I've been breaking things on the web since 1994. This is a story about how I wound up where I am today, with Flask, and what I learned along the way.

Oops!

Page 18: Flask First-Timer

Hello. My name is Aijaz, and I've been breaking things on the web since 1994. This is a story about how I wound up where I am today, with Flask, and what I learned along the way.

/index.htmlHello

Page 19: Flask First-Timer

Hello. My name is Aijaz, and I've been breaking things on the web since 1994. This is a story about how I wound up where I am today, with Flask, and what I learned along the way.

@_aijaz_

Page 20: Flask First-Timer

I started my professional career in 1995 as a call processing developer at Motorola. If you used a cell phone in the late 1990s, chances are you were running my code. After about 5 years, I quit and started my own Web Hosting and Application Development company. When it became obvious that that wasn't sustainable, I moved to the financial industry and started working at Citadel, in this very building. 8 years later, I decided to switch careers and become an iOS developer. I'm currently working for FastModel Sports where I write iOS apps for NBA and NCAA basketball coaches. But today I want to talk to about the web.

/about/

Page 21: Flask First-Timer

I started my professional career in 1995 as a call processing developer at Motorola. If you used a cell phone in the late 1990s, chances are you were running my code. After about 5 years, I quit and started my own Web Hosting and Application Development company. When it became obvious that that wasn't sustainable, I moved to the financial industry and started working at Citadel, in this very building. 8 years later, I decided to switch careers and become an iOS developer. I'm currently working for FastModel Sports where I write iOS apps for NBA and NCAA basketball coaches. But today I want to talk to about the web.

Page 22: Flask First-Timer

I started my professional career in 1995 as a call processing developer at Motorola. If you used a cell phone in the late 1990s, chances are you were running my code. After about 5 years, I quit and started my own Web Hosting and Application Development company. When it became obvious that that wasn't sustainable, I moved to the financial industry and started working at Citadel, in this very building. 8 years later, I decided to switch careers and become an iOS developer. I'm currently working for FastModel Sports where I write iOS apps for NBA and NCAA basketball coaches. But today I want to talk to about the web.

Page 23: Flask First-Timer

I started my professional career in 1995 as a call processing developer at Motorola. If you used a cell phone in the late 1990s, chances are you were running my code. After about 5 years, I quit and started my own Web Hosting and Application Development company. When it became obvious that that wasn't sustainable, I moved to the financial industry and started working at Citadel, in this very building. 8 years later, I decided to switch careers and become an iOS developer. I'm currently working for FastModel Sports where I write iOS apps for NBA and NCAA basketball coaches. But today I want to talk to about the web.

Page 24: Flask First-Timer

I started my professional career in 1995 as a call processing developer at Motorola. If you used a cell phone in the late 1990s, chances are you were running my code. After about 5 years, I quit and started my own Web Hosting and Application Development company. When it became obvious that that wasn't sustainable, I moved to the financial industry and started working at Citadel, in this very building. 8 years later, I decided to switch careers and become an iOS developer. I'm currently working for FastModel Sports where I write iOS apps for NBA and NCAA basketball coaches. But today I want to talk to about the web.

Page 25: Flask First-Timer

You already know about robots.pl. Perl, CGI. using cgi-lib.pl

1994

Page 26: Flask First-Timer

I was asked to make a website - we called them homepages back then - for a Muslim organization. That was the first time I became a webmaster. This was the website in all its mid 1990s glory.

1995

Page 27: Flask First-Timer

- Gratuitous Landing page CHECK - Drop shadow? CHECK- Emboss and beveled text? CHECK- Arbitrary perspective? CHECK- HTML image maps? CHECK- Custom horizontal rules? CHECK- Text rendered as an image because the browsers couldn't handle the formatting? CHECK- The only thing it's missing is a lovingly rendered page curl effect. And maybe a lens flare or three.

Page 28: Flask First-Timer

At that time it was not possible to display Arabic text in the browser, but I had a ton of text that needed to be displayed. I could scan the text from print, but I didn't have too much disk space on my hosted account. So I went to Boutell.com, downloaded his gd C library. Then I modified it so it could convert ascii text to scanned bitmaps, and joined those bitmaps to create gifs on the fly. Right to left, proportional widths. This way, a large image like this, instead of taking 100K would only be 400 bytes. Of all the things I've ever done on the web, this is the one I'm most proud of. Because it was new.

arabic

Page 29: Flask First-Timer

At that time it was not possible to display Arabic text in the browser, but I had a ton of text that needed to be displayed. I could scan the text from print, but I didn't have too much disk space on my hosted account. So I went to Boutell.com, downloaded his gd C library. Then I modified it so it could convert ascii text to scanned bitmaps, and joined those bitmaps to create gifs on the fly. Right to left, proportional widths. This way, a large image like this, instead of taking 100K would only be 400 bytes. Of all the things I've ever done on the web, this is the one I'm most proud of. Because it was new.

arabic

Page 30: Flask First-Timer

At that time it was not possible to display Arabic text in the browser, but I had a ton of text that needed to be displayed. I could scan the text from print, but I didn't have too much disk space on my hosted account. So I went to Boutell.com, downloaded his gd C library. Then I modified it so it could convert ascii text to scanned bitmaps, and joined those bitmaps to create gifs on the fly. Right to left, proportional widths. This way, a large image like this, instead of taking 100K would only be 400 bytes. Of all the things I've ever done on the web, this is the one I'm most proud of. Because it was new.

scan

Page 31: Flask First-Timer

At that time it was not possible to display Arabic text in the browser, but I had a ton of text that needed to be displayed. I could scan the text from print, but I didn't have too much disk space on my hosted account. So I went to Boutell.com, downloaded his gd C library. Then I modified it so it could convert ascii text to scanned bitmaps, and joined those bitmaps to create gifs on the fly. Right to left, proportional widths. This way, a large image like this, instead of taking 100K would only be 400 bytes. Of all the things I've ever done on the web, this is the one I'm most proud of. Because it was new.

disk space

Page 32: Flask First-Timer

At that time it was not possible to display Arabic text in the browser, but I had a ton of text that needed to be displayed. I could scan the text from print, but I didn't have too much disk space on my hosted account. So I went to Boutell.com, downloaded his gd C library. Then I modified it so it could convert ascii text to scanned bitmaps, and joined those bitmaps to create gifs on the fly. Right to left, proportional widths. This way, a large image like this, instead of taking 100K would only be 400 bytes. Of all the things I've ever done on the web, this is the one I'm most proud of. Because it was new.

Boutell.com

Page 33: Flask First-Timer

At that time it was not possible to display Arabic text in the browser, but I had a ton of text that needed to be displayed. I could scan the text from print, but I didn't have too much disk space on my hosted account. So I went to Boutell.com, downloaded his gd C library. Then I modified it so it could convert ascii text to scanned bitmaps, and joined those bitmaps to create gifs on the fly. Right to left, proportional widths. This way, a large image like this, instead of taking 100K would only be 400 bytes. Of all the things I've ever done on the web, this is the one I'm most proud of. Because it was new.

gd

Page 34: Flask First-Timer

At that time it was not possible to display Arabic text in the browser, but I had a ton of text that needed to be displayed. I could scan the text from print, but I didn't have too much disk space on my hosted account. So I went to Boutell.com, downloaded his gd C library. Then I modified it so it could convert ascii text to scanned bitmaps, and joined those bitmaps to create gifs on the fly. Right to left, proportional widths. This way, a large image like this, instead of taking 100K would only be 400 bytes. Of all the things I've ever done on the web, this is the one I'm most proud of. Because it was new.

scanned chars

Page 35: Flask First-Timer

At that time it was not possible to display Arabic text in the browser, but I had a ton of text that needed to be displayed. I could scan the text from print, but I didn't have too much disk space on my hosted account. So I went to Boutell.com, downloaded his gd C library. Then I modified it so it could convert ascii text to scanned bitmaps, and joined those bitmaps to create gifs on the fly. Right to left, proportional widths. This way, a large image like this, instead of taking 100K would only be 400 bytes. Of all the things I've ever done on the web, this is the one I'm most proud of. Because it was new.

scanned chars

Page 36: Flask First-Timer

At that time it was not possible to display Arabic text in the browser, but I had a ton of text that needed to be displayed. I could scan the text from print, but I didn't have too much disk space on my hosted account. So I went to Boutell.com, downloaded his gd C library. Then I modified it so it could convert ascii text to scanned bitmaps, and joined those bitmaps to create gifs on the fly. This way, a large image like this, instead of taking 100K would only be 400 bytes. Of all the things I've ever done on the web, this is the one I'm most proud of. Because it was new.

a.outvoid main(int argc, char ** argv){ gdImagePtr im, im2; FILE *out; //... printf("Content-type: image/gif\n\n");

/* Allocate the image: with a horiz padding */ im = gdImageCreate(MAXWIDTH + 10, height * 52); // ... /* Output the image to stdout. */ gdImageInterlace(im, 1); gdImageGif(im, stdout);

/* Destroy the image in memory. */ gdImageDestroy(im);}

Page 37: Flask First-Timer

At that time it was not possible to display Arabic text in the browser, but I had a ton of text that needed to be displayed. I could scan the text from print, but I didn't have too much disk space on my hosted account. So I went to Boutell.com, downloaded his gd C library. Then I modified it so it could convert ascii text to scanned bitmaps, and joined those bitmaps to create gifs on the fly. This way, a large image like this, instead of taking 100K would only be 400 bytes. Of all the things I've ever done on the web, this is the one I'm most proud of. Because it was new.

tiny

Page 38: Flask First-Timer

At that time it was not possible to display Arabic text in the browser, but I had a ton of text that needed to be displayed. I could scan the text from print, but I didn't have too much disk space on my hosted account. So I went to Boutell.com, downloaded his gd C library. Then I modified it so it could convert ascii text to scanned bitmaps, and joined those bitmaps to create gifs on the fly. This way, a large image like this, instead of taking 100K would only be 400 bytes. Of all the things I've ever done on the web, this is the one I'm most proud of. Because it was new.

proud

Page 39: Flask First-Timer

I got a chance to take a "Webmastering" class. Even though the title was cheesy, this was one of the best classes I ever took. They spent an entire day talking about how Apache Modules worked and how they were written with the HTTP specification in mind. Even though I really didn't want to write Apache Modules in C, I finally really understood how the different components worked together.

1998

Page 40: Flask First-Timer

I got a chance to take a "Webmastering" class. Even though the title was cheesy, this was one of the best classes I ever took. They spent an entire day talking about how Apache Modules worked and how they were written with the HTTP specification in mind. Even though I really didn't want to write Apache Modules in C, I finally really understood how the different components worked together.

webmastering

Page 41: Flask First-Timer

I got a chance to take a "Webmastering" class. Even though the title was cheesy, this was one of the best classes I ever took. They spent an entire day talking about how Apache Modules worked and how they were written with the HTTP specification in mind. Even though I really didn't want to write Apache Modules in C, I finally really understood how the different components worked together.

apache modules

Page 42: Flask First-Timer

And when Modperl came along, I was able to create complex websites that were more than single form-based pages. The first app I created was absolutely horrid. It was an e-commerce app, and when I look at it now, I can see it was UGLY.

2000

Page 43: Flask First-Timer

And when Modperl came along, I was able to create complex websites that were more than single form-based pages. The first app I created was absolutely horrid. It was an e-commerce app, and when I look at it now, I can see it was UGLY.

mod_perl

Page 44: Flask First-Timer

And when Modperl came along, I was able to create complex websites that were more than single form-based pages. The first app I created was absolutely horrid. It was an e-commerce app, and when I look at it now, I can see it was UGLY.

e-commerce

Page 45: Flask First-Timer

And when Modperl came along, I was able to create complex websites that were more than single form-based pages. The first app I created was absolutely horrid. It was an e-commerce app, and when I look at it now, I can see it was UGLY.

UGLY

Page 46: Flask First-Timer

But, I kept reading and learning and with each eCommerce app or CRM website, I got better. Learned new things. Became better at SQL. As time passed I started getting a nagging feeling - I was becoming too comfortable with my stack. I started ignoring new things out there like the popular templating toolkits because I had written my own back in the 90s. I started to feel that the world was passing me by, but I was too busy to adapt.

reading

Page 47: Flask First-Timer

But, I kept reading and learning and with each eCommerce app or CRM website, I got better. Learned new things. Became better at SQL. As time passed I started getting a nagging feeling - I was becoming too comfortable with my stack. I started ignoring new things out there like the popular templating toolkits because I had written my own back in the 90s. I started to feel that the world was passing me by, but I was too busy to adapt.

comfortable

Page 48: Flask First-Timer

But, I kept reading and learning and with each eCommerce app or CRM website, I got better. Learned new things. Became better at SQL. As time passed I started getting a nagging feeling - I was becoming too comfortable with my stack. I started ignoring new things out there like the popular templating toolkits because I had written my own back in the 90s. I started to feel that the world was passing me by, but I was too busy to adapt.

busy

Page 49: Flask First-Timer

Once I started working at Citadel upstairs my webdev activity came almost to a standstill. I had switched over to the financial industry. I was mantaining existing apps here and there, but not really doing too much new stuff. It was only in 2009 when I started doing some internal web apps. Again, using Mod_perl, apache httpd 1.3

2005

Page 50: Flask First-Timer

Once I started working at Citadel upstairs my webdev activity came almost to a standstill. I had switched over to the financial industry. I was mantaining existing apps here and there, but not really doing too much new stuff. It was only in 2009 when I started doing some internal web apps. Again, using Mod_perl, apache httpd 1.3

Citadel

Page 51: Flask First-Timer

Once I started working at Citadel upstairs my webdev activity came almost to a standstill. I had switched over to the financial industry. I was mantaining existing apps here and there, but not really doing too much new stuff. It was only in 2009 when I started doing some internal web apps. Again, using Mod_perl, apache httpd 1.3

standstill

Page 52: Flask First-Timer

Once I started working at Citadel upstairs my webdev activity came almost to a standstill. I had switched over to the financial industry. I was mantaining existing apps here and there, but not really doing too much new stuff. It was only in 2009 when I started doing some internal web apps. Again, using Mod_perl, apache httpd 1.3

internal apps

Page 53: Flask First-Timer

The turning point was in 2012. My sister-in-law was getting married. She wanted a simple website. A pretty one-page thing that would give guests venue and accomodation information, and would allow them to RSVP. We've all done this dozens of times, right? I fired up a Linux virtual server, installed Apache httpd 2, perl. And then everything failed. Modperl didn't install. I don't wanna bore you with the details, but for that one simple website I spent an entire **weekend** setting up the server and then writing a blog post about it because in 2012 you could not find **instructions** on how to set up modperl using current versions of perl or apache. Perl was stagnating, and the formerly vibrant community had long ago moved to greener pastures (like python). That's when I knew: my next website would have to be written in python.

turning point

Page 54: Flask First-Timer

The turning point was in 2012. My sister-in-law was getting married. She wanted a simple website. A pretty one-page thing that would give guests venue and accomodation information, and would allow them to RSVP. We've all done this dozens of times, right? I fired up a Linux virtual server, installed Apache httpd 2, perl. And then everything failed. Modperl didn't install. I don't wanna bore you with the details, but for that one simple website I spent an entire **weekend** setting up the server and then writing a blog post about it because in 2012 you could not find **instructions** on how to set up modperl using current versions of perl or apache. Perl was stagnating, and the formerly vibrant community had long ago moved to greener pastures (like python). That's when I knew: my next website would have to be written in python.

one page

Page 55: Flask First-Timer

The turning point was in 2012. My sister-in-law was getting married. She wanted a simple website. A pretty one-page thing that would give guests venue and accomodation information, and would allow them to RSVP. We've all done this dozens of times, right? I fired up a Linux virtual server, installed Apache httpd 2, perl. And then everything failed. Modperl didn't install. I don't wanna bore you with the details, but for that one simple website I spent an entire **weekend** setting up the server and then writing a blog post about it because in 2012 you could not find **instructions** on how to set up modperl using current versions of perl or apache. Perl was stagnating, and the formerly vibrant community had long ago moved to greener pastures (like python). That's when I knew: my next website would have to be written in python.

failed

Page 56: Flask First-Timer

The turning point was in 2012. My sister-in-law was getting married. She wanted a simple website. A pretty one-page thing that would give guests venue and accomodation information, and would allow them to RSVP. We've all done this dozens of times, right? I fired up a Linux virtual server, installed Apache httpd 2, perl. And then everything failed. Modperl didn't install. I don't wanna bore you with the details, but for that one simple website I spent an entire **weekend** setting up the server and then writing a blog post about it because in 2012 you could not find **instructions** on how to set up modperl using current versions of perl or apache. Perl was stagnating, and the formerly vibrant community had long ago moved to greener pastures (like python). That's when I knew: my next website would have to be written in python.

weekend

Page 57: Flask First-Timer

The turning point was in 2012. My sister-in-law was getting married. She wanted a simple website. A pretty one-page thing that would give guests venue and accomodation information, and would allow them to RSVP. We've all done this dozens of times, right? I fired up a Linux virtual server, installed Apache httpd 2, perl. And then everything failed. Modperl didn't install. I don't wanna bore you with the details, but for that one simple website I spent an entire **weekend** setting up the server and then writing a blog post about it because in 2012 you could not find **instructions** on how to set up modperl using current versions of perl or apache. Perl was stagnating, and the formerly vibrant community had long ago moved to greener pastures (like python). That's when I knew: my next website would have to be written in python.

no instructions

Page 58: Flask First-Timer

The turning point was in 2012. My sister-in-law was getting married. She wanted a simple website. A pretty one-page thing that would give guests venue and accomodation information, and would allow them to RSVP. We've all done this dozens of times, right? I fired up a Linux virtual server, installed Apache httpd 2, perl. And then everything failed. Modperl didn't install. I don't wanna bore you with the details, but for that one simple website I spent an entire **weekend** setting up the server and then writing a blog post about it because in 2012 you could not find **instructions** on how to set up modperl using current versions of perl or apache. Perl was stagnating, and the formerly vibrant community had long ago moved to greener pastures (like python). That's when I knew: my next website would have to be written in python.

stagnating

Page 59: Flask First-Timer

The turning point was in 2012. My sister-in-law was getting married. She wanted a simple website. A pretty one-page thing that would give guests venue and accomodation information, and would allow them to RSVP. We've all done this dozens of times, right? I fired up a Linux virtual server, installed Apache httpd 2, perl. And then everything failed. Modperl didn't install. I don't wanna bore you with the details, but for that one simple website I spent an entire **weekend** setting up the server and then writing a blog post about it because in 2012 you could not find **instructions** on how to set up modperl using current versions of perl or apache. Perl was stagnating, and the formerly vibrant community had long ago moved to greener pastures (like python). That's when I knew: my next website would have to be written in python.

greener pastures

Page 60: Flask First-Timer

The turning point was in 2012. My sister-in-law was getting married. She wanted a simple website. A pretty one-page thing that would give guests venue and accomodation information, and would allow them to RSVP. We've all done this dozens of times, right? I fired up a Linux virtual server, installed Apache httpd 2, perl. And then everything failed. Modperl didn't install. I don't wanna bore you with the details, but for that one simple website I spent an entire **weekend** setting up the server and then writing a blog post about it because in 2012 you could not find **instructions** on how to set up modperl using current versions of perl or apache. Perl was stagnating, and the formerly vibrant community had long ago moved to greener pastures (like python). That's when I knew: my next website would have to be written in python.

(python)

Page 61: Flask First-Timer

I will now take a 15 second break and play a relevant video clip

INTERMISSION

Page 62: Flask First-Timer
Page 63: Flask First-Timer

Fast forward to last November. My brother was starting an Indian delivery-only restaurant preparation and delivery service and he needed a website as well as a back-end service for the inevitable mobile app. This was my chance to start from scratch, and not be burdened by the 'old way of doing things.' This was my chance to get out of my comfort zone and use the language that had been tempting me for the last decade: python.

TurboTiffin

Page 64: Flask First-Timer

Fast forward to last November. My brother was starting an Indian food preparation and delivery service and he needed a website as well as a back-end service for the inevitable mobile app. This was my chance to start from scratch, and not be burdened by the 'old way of doing things.' This was my chance to get out of my comfort zone and use the language that had been tempting me for the last decade: python.

restaurant

Page 65: Flask First-Timer

Fast forward to last November. My brother was starting an Indian food preparation and delivery service and he needed a website as well as a back-end service for the inevitable mobile app. This was my chance to start from scratch, and not be burdened by the 'old way of doing things.' This was my chance to get out of my comfort zone and use the language that had been tempting me for the last decade: python.

start from scratch

Page 66: Flask First-Timer

I knew about Django, and had tried to pick it up several times over the years, but there was something about it that I just didn't like. I still don't know what it is. People say it's monolithic. Maybe. Maybe the problems that the Django developers were solving didn't seem like the problems I wanted to solve. So the breakthrough came like so many other breakthroughs in my life. I went to Google and typed in: Django vs...

django

Page 67: Flask First-Timer

I knew about Django, and had tried to pick it up several times over the years, but there was something about it that I just didn't like. I still don't know what it is. People say it's monolithic. Maybe. Maybe the problems that the Django developers were solving didn't seem like the problems I wanted to solve. So the breakthrough came like so many other breakthroughs in my life. I went to Google and typed in: Django vs...

meh

Page 68: Flask First-Timer
Page 69: Flask First-Timer

Huh! Flask. Wonder what that's all about. I found Miguel Grinberg's excellent series of posts on Flask, bought his book, and that's when I realized that this was the framework for me. I LOVED the fact that the Flask book was thin. I LOVED the fact that I was getting excited about the whole rigamarole: - Create a virtual environment- pip3 install all the things- Run it locally easily- Install just the modules you want.This was what I was waiting for.

huh

Page 70: Flask First-Timer

Huh! Flask. Wonder what that's all about. I found Miguel Grinberg's excellent series of posts on Flask, bought his book, and that's when I realized that this was the framework for me. I LOVED the fact that the Flask book was thin. I LOVED the fact that I was getting excited about the whole rigamarole: - Create a virtual environment- pip3 install all the things- Run it locally easily- Install just the modules you want.This was what I was waiting for.

Miguel Grinberg

Page 71: Flask First-Timer

Huh! Flask. Wonder what that's all about. I found Miguel Grinberg's excellent series of posts on Flask, bought his book, and that's when I realized that this was the framework for me. I LOVED the fact that the Flask book was thin. I LOVED the fact that I was getting excited about the whole rigamarole: - Create a virtual environment- pip3 install all the things- Run it locally easily- Install just the modules you want.- Reload code whenever a file changesThis was what I was waiting for.

!

Page 72: Flask First-Timer

My requirements for the website and app were pretty ordinary. Now I'm gonna talk about 2 of them and my rationale for choosing the solutions I did. This is the part where I ask you a favor. As I describe my solutions, please put your skeptics' hats on and try to find flaws in my arguments or assumptions. If you think I've made the wrong decision, please tell me so. Either during the presentation, or afterwards. Challenge everything I say. You'll be doing me a great service. Alright back to the requirements.

requirements

Page 73: Flask First-Timer

My requirements for the website and app were pretty ordinary. Now I'm gonna talk about 4 of them and my rationale for choosing the solutions I did. This is the part where I ask you a favor. As I describe my solutions, please put your skeptics' hats on and try to find flaws in my arguments or assumptions. If you think I've made the wrong decision, please tell me so. Either during the presentation, or afterwards. Challenge everything I say. You'll be doing me a great service. Alright back to the requirements.

do me a solid

Page 74: Flask First-Timer

My requirements for the website and app were pretty ordinary. Now I'm gonna talk about 4 of them and my rationale for choosing the solutions I did. This is the part where I ask you a favor. As I describe my solutions, please put your skeptics' hats on and try to find flaws in my arguments or assumptions. If you think I've made the wrong decision, please tell me so. Either during the presentation, or afterwards. Challenge everything I say. You'll be doing me a great service. Alright back to the requirements.

challenge!

Page 75: Flask First-Timer

» Database

» Authentication

Page 76: Flask First-Timer

This is the subsystem that I agonized over the most. The fundamental decision is: Should I use the high-level ORM that is Flask-SQLAlchemy or should I use raw SQL? I tried to enumerate the pros and cons of using SQLAchemy

database

Page 77: Flask First-Timer

This is the subsystem that I agonized over the most. The fundamental decision is: Should I use the high-level ORM that is Flask-SQLAlchemy or should I use raw SQL? I tried to enumerate the pros and cons of using SQLAchemy

SQLAlchemy?

Page 78: Flask First-Timer

- db independence- easy integration- focus on models- connection pooling

pros» ease of use

Page 79: Flask First-Timer

easy integration- focus on models- connection pooling

pros» ease of use

» db independence

Page 80: Flask First-Timer

focus on models- connection pooling

pros» ease of use

» db independence

» easy integration

Page 81: Flask First-Timer

- connection pooling

pros» ease of use

» db independence

» easy integration

» focus on models

Page 82: Flask First-Timer

pros» ease of use

» db independence

» easy integration

» focus on models

» connection pooling

Page 83: Flask First-Timer

I didn't want to have to master yet another new thing just to get version 1.0 working well. I expected to spend a lot of time working with Flask, and retraining myself to think like a Python developer.- comfort w/ SQL- PostgreSQL 4 evah- mobilecontext shifts- multiple clients- undo

cons» time

Page 84: Flask First-Timer

I am really comfortable with SQL. After working for 8 years with one of the best DBAs in the country upstairs, it's easy for me to think in terms of multi-table joins. - PostgreSQL 4 evah- mobilecontext shifts- multiple clients- undo

cons» time

» comfort w/ SQL

Page 85: Flask First-Timer

I liked the fact my code would work just as well with PostgreSQL, sqlite3 or any other database. But the truth is that I will always be using PostgreSQL, even on my local mac.- mobilecontext shifts- multiple clients- undo

cons» time

» comfort w/ SQL

» PostgreSQL 4 evah

Page 86: Flask First-Timer

The mobile client would have its own sqlite3 relational database. It would be similar to the one on the server, so I would have fewer context shifts when moving from backend development to mobile and back again.- multiple clients- undo

cons» time

» comfort w/ SQL

» PostgreSQL 4 evah

» mobilecontext shifts

Page 87: Flask First-Timer

The Flask website would not be the only client of the database. I would have batch jobs that run at different times of the day that update menus, charge customers' cards for orders placed in advance and print deliver manifests and receipts. Of course, I could use SQLAlchemy for those jobs as well, but then I'm reminded of the final point?- undo

cons» time

» comfort w/ SQL

» PostgreSQL 4 evah

» mobilecontext shifts

» multiple clients

Page 88: Flask First-Timer

What if I'm joining the Flask bandwagon too late? What if Flask is about to begin its stagnation? Or, what if I realize it really isn't well suited for what I'm trying to do? How much work will be required to undo this decision to move to Flask?

cons» time

» comfort w/ SQL

» PostgreSQL 4 evah

» mobilecontext shifts

» multiple clients

» undo

Page 89: Flask First-Timer

When I looked at all these things together I decide to go with the pure SQL route and on top of that do something I had never done before. I put all the business logic in the database. Stored procedures. Lots of them.

cons» time

» comfort w/ SQL

» PostgreSQL 4 evah

» mobilecontext shifts

» multiple clients

» undo

Page 90: Flask First-Timer

When I looked at all these things together I decide to go with the pure SQL route and on top of that do something I had never done before. I put all the business logic in the database. Stored procedures. Lots of them.

sql

Page 91: Flask First-Timer

Everything from logging in, to finding the price of a dish, figuring out the tax, placing an order, applying coupon codes, EVERTHING would be in the database layer, written in PL/PGSQL. The client code, the Flask Python code, would never perform a join on two tables. It would instead call stored procedures that would do all of the heavy lifting.

stored procedures

Page 92: Flask First-Timer

Everything from logging in, to finding the price of a dish, figuring out the tax, placing an order, applying coupon codes, EVERTHING would be in the database layer, written in PL/PGSQL. The client code, the Flask Python code, would never perform a join on two tables. It would instead call stored procedures that would do all of the heavy lifting.

pl/pgsql

Page 93: Flask First-Timer

Everything from logging in, to finding the price of a dish, figuring out the tax, placing an order, applying coupon codes, EVERTHING would be in the database layer, written in PL/PGSQL. The client code, the Flask Python code, would never perform a join on two tables. It would instead call stored procedures that would do all of the heavy lifting. So instead of calling a bunch of code to create an order, I can just do this.

heavy lifting

Page 94: Flask First-Timer

So instead of calling a bunch of code to create an order, I can just do this. What this gives me is all my business logic in one place. It's easy to write test cases and verify them. The regression tests themselves are written as sql statement. It's easy to notice when tests fail. It's just another form of dependency injection

cur.execute("SELECT * FROM f_add_order (%s, %s, %s, %s)", ( session['person_id'] , epoch_date , section , items_list))

Page 95: Flask First-Timer

It also allows me to use the psql database prompt to run stored procedures that aren't yet accessible from the admin web site. Every once in a while, for example, someone will cancel an order. All I have to do is:

dependency injection

Page 96: Flask First-Timer

All the tables stay in a consistent state while the order is cancelled. I was a little afraid of not getting connection pooling down right, but after some research I realized I could create the connection pool when I initialize the app:

select f_mark_order_cancelled(3055);

Page 97: Flask First-Timer

def create_app(config_name) : app = Flask(__name__) app.config.from_object(config[config_name]) config[config_name].init_app(app)

# attach routes and error pages here from .main import main as main_blueprint app.register_blueprint(main_blueprint)

# ... app.connection_pool = ThreadedConnectionPool(min_conn, max_conn, host=db_host, database=db_database_name, user=db_user_name)

return app

Page 98: Flask First-Timer

» Database

» Authentication

Page 99: Flask First-Timer

This is really for the REST services part of the app, as opposed to the website, where I used cookies. I know what I didn't want: I didn't wanna use OAuth. It seemed icky for a restaurant to ask for your Google or Facebook credentials, for example. You and I both know that I wouldn't actually get the credentials, but a very common reaction from users is: Oh, I need to login via facebook to order a chicken tikka masala? Thanks, but no thanks. GrubHub it is.

authentication

Page 100: Flask First-Timer

It seemed icky for a restaurant to ask for your Google or Facebook credentials, for example. You and I both know that I wouldn't actually get the credentials, but a very common reaction from users is: Oh, I need to login via facebook to order a chicken tikka masala? Thanks, but no thanks. GrubHub it is. The other reason I decided not to use OAuth is that I really need the users' email addresses. This is how I send them receipts, let them know when their credit cards have expired and communicate with them in general. I wanted to make sure that the email addresses I have on file are the same adresses with which the users wish to communicate with TurboTiffin.

no OAuth

Page 101: Flask First-Timer

The other reason I decided not to use OAuth is that I really need the users' email addresses. This is how I send them receipts, let them know when their credit cards have expired and communicate with them in general. I wanted to make sure that the email addresses I have on file are the same adresses with which the users wish to communicate with TurboTiffin. Once the user authenticates with their email and password I create an token that they can use in lieu of sending me their password every time. This token expires after a few minutes, so that the window of opportunity of using a stolen token is relatively small.

emails

Page 102: Flask First-Timer

Once the user authenticates with their email and password I create an token that they can use in lieu of sending me their password every time. This token expires after a few minutes, so that the window of opportunity of using a stolen token is relatively small. Now, what Grinberg suggests is to use the itsdangerous package. Take the user id and expiration date and cryptographically sign these two and return the result as a token. The beauty of this system is that the web server doesn't need to store the token locally. The token has all the information the server needs, in a tamper-proof format.

token

Page 103: Flask First-Timer

Now, what Grinberg suggests is to use the itsdangerous package. Take the user id and expiration date and cryptographically sign these two and return the result as a token. The beauty of this system is that the web server doesn't need to store the token locally. The token has all the information the server needs, in a tamper-proof format. I decided not to go that route. I generate a random token and store it the database in clear text. I considered the risks of storing the token in clear text, and for this application, if you had access to the token, you either had access to the mobile client's secure storage, where the user id and password are also stored, or you have access to the server database. In either case, knowing the token does not increase the severity of the breach, and unlike storing the password in cleartext, knowing the token doesn't give you access to other accounts owned by the same person.

itsdangerous

Page 104: Flask First-Timer

I decided not to go that route. I generate a random token and store it the database in clear text. I considered the risks of storing the token in clear text, and for this application, if you had access to the token, you either had access to the mobile client's secure storage, where the user id and password are also stored, or you have access to the server database. In either case, knowing the token does not increase the severity of the breach, and unlike storing the password in cleartext, knowing the token doesn't give you access to other accounts owned by the same person.

tamper-proof

Page 105: Flask First-Timer

I generate a random token and store it the database in clear text. I considered the risks of storing the token in clear text, and for this application, if you had access to the token, you either had access to the mobile client's secure storage, where the user id and password are also stored, or you have access to the server database. In either case, knowing the token does not increase the severity of the breach, and unlike storing the password in cleartext, knowing the token doesn't give you access to other accounts owned by the same person.

random

Page 106: Flask First-Timer

I generate a random token and store it the database in clear text. I considered the risks of storing the token in clear text, and for this application, if you had access to the token, you either had access to the mobile client's secure storage, where the user id and password are also stored, or you have access to the server database. In either case, knowing the token does not increase the severity of the breach, and unlike storing the password in cleartext, knowing the token doesn't give you access to other accounts owned by the same person.

cleartext

Page 107: Flask First-Timer

I generate a random token and store it the database in clear text. I considered the risks of storing the token in clear text, and for this application, if you had access to the token, you either had access to the mobile client's secure storage, where the user id and password are also stored, or you have access to the server database. In either case, knowing the token does not increase the severity of the breach, and unlike storing the password in cleartext, knowing the token doesn't give you access to other accounts owned by the same person.

mobile

Page 108: Flask First-Timer

I generate a random token and store it the database in clear text. I considered the risks of storing the token in clear text, and for this application, if you had access to the token, you either had access to the mobile client's secure storage, where the user id and password are also stored, or you have access to the server database. In either case, knowing the token does not increase the severity of the breach, and unlike storing the password in cleartext, knowing the token doesn't give you access to other accounts owned by the same person.

server

Page 109: Flask First-Timer

In either case, knowing the token does not increase the severity of the breach, and unlike storing the password in cleartext, knowing the token doesn't give you access to other accounts owned by the same person. I was concerned about the impact of adding a database lookup for every page request, but it appears that the speed is still pretty good: I'm getting around 20ms to serve a page. So that's pretty good, right? The other effect of having the token stored in the database is that you can quickly see how many people have been active on your website during the amount of time equal to your token lifespan. And, by deleting a token, you can easily block out clients that may be hitting your server too frequently. Not that I need to worry about this on a small website, but these are the rationalizations that I came up with. I will be very interested to hear your comments on this.

severity

Page 110: Flask First-Timer

I was concerned about the impact of adding a database lookup for every page request, but it appears that the speed is still pretty good: I'm getting around 20ms to serve a page. So that's pretty good, right? The other effect of having the token stored in the database is that you can quickly see how many people have been active on your website during the amount of time equal to your token lifespan. And, by deleting a token, you can easily block out clients that may be hitting your server too frequently. Not that I need to worry about this on a small website, but these are the rationalizations that I came up with. I will be very interested to hear your comments on this.

impact on speed

Page 111: Flask First-Timer

I was concerned about the impact of adding a database lookup for every page request, but it appears that the speed is still pretty good: I'm getting around 20ms to serve a page. So that's pretty good, right? The other effect of having the token stored in the database is that you can quickly see how many people have been active on your website during the amount of time equal to your token lifespan. And, by deleting a token, you can easily block out clients that may be hitting your server too frequently. Not that I need to worry about this on a small website, but these are the rationalizations that I came up with. I will be very interested to hear your comments on this.

GET /admin/receipts => generated 1291 bytes in 21 msecs

Page 112: Flask First-Timer

I was concerned about the impact of adding a database lookup for every page request, but it appears that the speed is still pretty good: I'm getting around 20ms to serve a page. So that's pretty good, right? The other effect of having the token stored in the database is that you can quickly see how many people have been active on your website during the amount of time equal to your token lifespan. And, by deleting a token, you can easily block out clients that may be hitting your server too frequently. Not that I need to worry about this on a small website, but these are the rationalizations that I came up with. I will be very interested to hear your comments on this.

active

Page 113: Flask First-Timer

I was concerned about the impact of adding a database lookup for every page request, but it appears that the speed is still pretty good: I'm getting around 20ms to serve a page. So that's pretty good, right? The other effect of having the token stored in the database is that you can quickly see how many people have been active on your website during the amount of time equal to your token lifespan. And, by deleting a token, you can easily block out clients that may be hitting your server too frequently. Not that I need to worry about this on a small website, but these are the rationalizations that I came up with. I will be very interested to hear your comments on this.

block out

Page 114: Flask First-Timer

So there we have it. This is the story of how I got from a perl cgi robots game in 1994 to delivering people Indian food using Flask today. What did I learn along the way?

comments

Page 115: Flask First-Timer

Try to understand how things work under the hoodNEXT: SHARE WHAT YOU LEARN

» deep learning

Page 116: Flask First-Timer

Write blog posts. Even if no one reads them, you'll organize your thoughts. Or give talks. Like this oneNEXT: KNOW WHEN TO STOP

» deep learning

» share what you learn

Page 117: Flask First-Timer

Don't stick blindly to one technology or framework. Know when to move on. NEXT: FAILURE IS CHARACTER BUILDER

» deep learning

» share what you learn

» know when to stop

Page 118: Flask First-Timer

When you go down a certain path and give up because it doesn't suit your purpose, don't think of them as bad experiences, think of them as learning experiences and character buildersNEXT: SECOND-MOST IMPORTANT TASK IS TO WRITE BEAUTIFUL CODE

» deep learning

» share what you learn

» know when to stop

» character builders

Page 119: Flask First-Timer

Your second-most important task is to create beautiful code. Your most important task is to ship working code. FINALLY: CHANGE YOUR OPINION

» deep learning

» share what you learn

» know when to stop

» character builders

» ship on time

Page 120: Flask First-Timer

Be ready to change your opinion when faced with new data. It's called being an adult.

» deep learning

» share what you learn

» know when to stop

» character builders

» ship on time

» change opinion

Page 121: Flask First-Timer

adult

Page 122: Flask First-Timer

Thank you!

Page 123: Flask First-Timer

Aijaz Ansari@_aijaz_http://aijaz.net