SlideShare a Scribd company logo
1 of 123
Download to read offline
Test Slide. Thanks C J SS
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
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
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
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
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
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
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
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
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
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
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>
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!
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
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
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
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!
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.html
Hello
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_
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/
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.
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.
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.
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.
You already know about robots.pl. Perl, CGI. using cgi-lib.pl
1994
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
- 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
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
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
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
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
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
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
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
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
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.out
void main(int argc, char ** argv)
{
gdImagePtr im, im2;
FILE *out;
//...
printf("Content-type: image/gifnn");
/* 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);
}
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
I will now take a 15 second break and play a relevant video
clip
INTERMISSION
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
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
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
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
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
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.
huh
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.
Miguel Grinberg
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.
!
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
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
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!
» Database
» Authentication
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
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?
- db independence
- easy integration
- focus on models
- connection pooling
pros
» ease of use
easy integration
- focus on models
- connection pooling
pros
» ease of use
» db independence
focus on models
- connection pooling
pros
» ease of use
» db independence
» easy integration
- connection pooling
pros
» ease of use
» db independence
» easy integration
» focus on models
pros
» ease of use
» db independence
» easy integration
» focus on models
» connection pooling
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
cons
» time
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
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
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
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
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
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
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
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
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
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
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))
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
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);
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
» Database
» Authentication
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
Try to understand how things work under
the hood
NEXT: SHARE WHAT YOU LEARN
» deep learning
Write blog posts. Even if no one reads them, you'll
organize your thoughts. Or give talks. Like this one
NEXT: KNOW WHEN TO STOP
» deep learning
» share what you learn
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
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 builders
NEXT: SECOND-MOST IMPORTANT TASK IS TO WRITE BEAUTIFUL
CODE
» deep learning
» share what you learn
» know when to stop
» character builders
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
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
adult
Thank you!
Aijaz Ansari
@_aijaz_
http://aijaz.net

More Related Content

Viewers also liked

Viewers also liked (18)

2016 Internet Trends Report
2016 Internet Trends Report2016 Internet Trends Report
2016 Internet Trends Report
 
MongoDB NoSQL database a deep dive -MyWhitePaper
MongoDB  NoSQL database a deep dive -MyWhitePaperMongoDB  NoSQL database a deep dive -MyWhitePaper
MongoDB NoSQL database a deep dive -MyWhitePaper
 
Tracxn Research - Mobile Advertising Landscape, February 2017
Tracxn Research - Mobile Advertising Landscape, February 2017Tracxn Research - Mobile Advertising Landscape, February 2017
Tracxn Research - Mobile Advertising Landscape, February 2017
 
Tracxn Research - Construction Tech Landscape, February 2017
Tracxn Research - Construction Tech Landscape, February 2017Tracxn Research - Construction Tech Landscape, February 2017
Tracxn Research - Construction Tech Landscape, February 2017
 
2015 Internet Trends Report
2015 Internet Trends Report2015 Internet Trends Report
2015 Internet Trends Report
 
Company website presentation march 2017
Company website presentation   march 2017Company website presentation   march 2017
Company website presentation march 2017
 
Company website presentation (b) march 2017
Company website presentation (b)   march 2017Company website presentation (b)   march 2017
Company website presentation (b) march 2017
 
DBワークロードのAWS化とデータベースサービス関連最新情報
DBワークロードのAWS化とデータベースサービス関連最新情報DBワークロードのAWS化とデータベースサービス関連最新情報
DBワークロードのAWS化とデータベースサービス関連最新情報
 
Web engineering notes unit 3
Web engineering notes unit 3Web engineering notes unit 3
Web engineering notes unit 3
 
Vertical Booking CRS Overview 2017
Vertical Booking CRS Overview 2017Vertical Booking CRS Overview 2017
Vertical Booking CRS Overview 2017
 
Getting Started with AWS Lambda and the Serverless Cloud
Getting Started with AWS Lambda and the Serverless CloudGetting Started with AWS Lambda and the Serverless Cloud
Getting Started with AWS Lambda and the Serverless Cloud
 
Introduction to Identity and Access Management (IAM)
Introduction to Identity and Access Management (IAM)Introduction to Identity and Access Management (IAM)
Introduction to Identity and Access Management (IAM)
 
Introduction to Big Data
Introduction to Big DataIntroduction to Big Data
Introduction to Big Data
 
Agile Data Science 2.0 - Big Data Science Meetup
Agile Data Science 2.0 - Big Data Science MeetupAgile Data Science 2.0 - Big Data Science Meetup
Agile Data Science 2.0 - Big Data Science Meetup
 
Email Marketing Metrics Benchmark Study 2016
Email Marketing Metrics Benchmark Study 2016Email Marketing Metrics Benchmark Study 2016
Email Marketing Metrics Benchmark Study 2016
 
Tugas 4 0317-imelda felicia-1412510545
Tugas 4 0317-imelda felicia-1412510545Tugas 4 0317-imelda felicia-1412510545
Tugas 4 0317-imelda felicia-1412510545
 
The future of insurance distribution: New models for a digital customer
The future of insurance distribution: New models for a digital customerThe future of insurance distribution: New models for a digital customer
The future of insurance distribution: New models for a digital customer
 
Tracxn Research - Chatbots Landscape, February 2017
Tracxn Research - Chatbots Landscape, February 2017Tracxn Research - Chatbots Landscape, February 2017
Tracxn Research - Chatbots Landscape, February 2017
 

Similar to Flask First-Timer

Progressive Enhancement & Intentional Degradation 2
Progressive Enhancement & Intentional Degradation 2Progressive Enhancement & Intentional Degradation 2
Progressive Enhancement & Intentional Degradation 2
elliotjaystocks
 
Hampton's 6 Rules of Mobile Design
Hampton's 6 Rules of Mobile DesignHampton's 6 Rules of Mobile Design
Hampton's 6 Rules of Mobile Design
Hampton Catlin
 
Social Media Brown Bag
Social Media Brown BagSocial Media Brown Bag
Social Media Brown Bag
guesta26314ad
 

Similar to Flask First-Timer (20)

iOS development made easy
iOS development made easyiOS development made easy
iOS development made easy
 
Go for Rubyists. August 2018. RUG-B Meetup
Go for Rubyists. August 2018. RUG-B MeetupGo for Rubyists. August 2018. RUG-B Meetup
Go for Rubyists. August 2018. RUG-B Meetup
 
FFWD.PRO - It's not you, It's me (or how to avoid being coupled with a Javasc...
FFWD.PRO - It's not you, It's me (or how to avoid being coupled with a Javasc...FFWD.PRO - It's not you, It's me (or how to avoid being coupled with a Javasc...
FFWD.PRO - It's not you, It's me (or how to avoid being coupled with a Javasc...
 
Adobemax2009na
Adobemax2009naAdobemax2009na
Adobemax2009na
 
Front Porch Keynote 2014
Front Porch Keynote 2014Front Porch Keynote 2014
Front Porch Keynote 2014
 
Beyond your daily coding - The Conf Brazil 2017 Keynote
Beyond your daily coding - The Conf Brazil 2017 KeynoteBeyond your daily coding - The Conf Brazil 2017 Keynote
Beyond your daily coding - The Conf Brazil 2017 Keynote
 
Software Applications around us
Software Applications around usSoftware Applications around us
Software Applications around us
 
Brucewang
BrucewangBrucewang
Brucewang
 
A University API
A University APIA University API
A University API
 
Progressive Enhancement & Intentional Degradation 2
Progressive Enhancement & Intentional Degradation 2Progressive Enhancement & Intentional Degradation 2
Progressive Enhancement & Intentional Degradation 2
 
Internet101 Presentation
Internet101 PresentationInternet101 Presentation
Internet101 Presentation
 
Building Stuff for Fun and Profit - confessions from a life in code and cables
Building Stuff for Fun and Profit - confessions from a life in code and cablesBuilding Stuff for Fun and Profit - confessions from a life in code and cables
Building Stuff for Fun and Profit - confessions from a life in code and cables
 
Past and today of Metasepi project
Past and today of Metasepi projectPast and today of Metasepi project
Past and today of Metasepi project
 
Hampton's 6 Rules of Mobile Design
Hampton's 6 Rules of Mobile DesignHampton's 6 Rules of Mobile Design
Hampton's 6 Rules of Mobile Design
 
DataDay 2023 Presentation - Notes
DataDay 2023 Presentation - NotesDataDay 2023 Presentation - Notes
DataDay 2023 Presentation - Notes
 
Social Media Brown Bag
Social Media Brown BagSocial Media Brown Bag
Social Media Brown Bag
 
Forget AMP – Make Fast Sites!
Forget AMP – Make Fast Sites!Forget AMP – Make Fast Sites!
Forget AMP – Make Fast Sites!
 
Finding harmony in web development
Finding harmony in web developmentFinding harmony in web development
Finding harmony in web development
 
Devops is a Security Requirement
Devops is a Security RequirementDevops is a Security Requirement
Devops is a Security Requirement
 
Gear diagram
Gear diagramGear diagram
Gear diagram
 

More from Aijaz Ansari

More from Aijaz Ansari (6)

Advanced Debugging with Xcode - Extending LLDB
Advanced Debugging with Xcode - Extending LLDBAdvanced Debugging with Xcode - Extending LLDB
Advanced Debugging with Xcode - Extending LLDB
 
360|iDev
360|iDev360|iDev
360|iDev
 
Beyond Breakpoints: Advanced Debugging with XCode
Beyond Breakpoints: Advanced Debugging with XCodeBeyond Breakpoints: Advanced Debugging with XCode
Beyond Breakpoints: Advanced Debugging with XCode
 
Now What?
Now What?Now What?
Now What?
 
Protecting Your Clients' Privacy
Protecting Your Clients' PrivacyProtecting Your Clients' Privacy
Protecting Your Clients' Privacy
 
Exploring JSON With jq
Exploring JSON With jqExploring JSON With jq
Exploring JSON With jq
 

Recently uploaded

Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
panagenda
 
Structuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessStructuring Teams and Portfolios for Success
Structuring Teams and Portfolios for Success
UXDXConf
 

Recently uploaded (20)

Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
 
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdfHow Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
 
How we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfHow we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdf
 
Salesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
Salesforce Adoption – Metrics, Methods, and Motivation, Antone KomSalesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
Salesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
 
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
 
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfThe Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
 
ECS 2024 Teams Premium - Pretty Secure
ECS 2024   Teams Premium - Pretty SecureECS 2024   Teams Premium - Pretty Secure
ECS 2024 Teams Premium - Pretty Secure
 
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxUnpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
 
Designing for Hardware Accessibility at Comcast
Designing for Hardware Accessibility at ComcastDesigning for Hardware Accessibility at Comcast
Designing for Hardware Accessibility at Comcast
 
AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101
 
1111 ChatGPT Prompts PDF Free Download - Prompts for ChatGPT
1111 ChatGPT Prompts PDF Free Download - Prompts for ChatGPT1111 ChatGPT Prompts PDF Free Download - Prompts for ChatGPT
1111 ChatGPT Prompts PDF Free Download - Prompts for ChatGPT
 
Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024
 
The Metaverse: Are We There Yet?
The  Metaverse:    Are   We  There  Yet?The  Metaverse:    Are   We  There  Yet?
The Metaverse: Are We There Yet?
 
A Business-Centric Approach to Design System Strategy
A Business-Centric Approach to Design System StrategyA Business-Centric Approach to Design System Strategy
A Business-Centric Approach to Design System Strategy
 
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
 
Structuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessStructuring Teams and Portfolios for Success
Structuring Teams and Portfolios for Success
 
Demystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John StaveleyDemystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John Staveley
 
AI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekAI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří Karpíšek
 
Powerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara LaskowskaPowerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara Laskowska
 
Google I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGoogle I/O Extended 2024 Warsaw
Google I/O Extended 2024 Warsaw
 

Flask First-Timer

  • 2. 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
  • 3. 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
  • 4. 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
  • 5. 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
  • 6. 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
  • 7. 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
  • 8. 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
  • 9. 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
  • 10. 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
  • 11. 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
  • 12. 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>
  • 13. 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!
  • 14. 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
  • 15. 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
  • 16. 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
  • 17. 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!
  • 18. 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.html Hello
  • 19. 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_
  • 20. 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/
  • 21. 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.
  • 22. 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.
  • 23. 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.
  • 24. 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.
  • 25. You already know about robots.pl. Perl, CGI. using cgi-lib.pl 1994
  • 26. 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
  • 27. - 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
  • 28. 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
  • 29. 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
  • 30. 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
  • 31. 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
  • 32. 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
  • 33. 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
  • 34. 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
  • 35. 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
  • 36. 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.out void main(int argc, char ** argv) { gdImagePtr im, im2; FILE *out; //... printf("Content-type: image/gifnn"); /* 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); }
  • 37. 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
  • 38. 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
  • 39. 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
  • 40. 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
  • 41. 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
  • 42. 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
  • 43. 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
  • 44. 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
  • 45. 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
  • 46. 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
  • 47. 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
  • 48. 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
  • 49. 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
  • 50. 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
  • 51. 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
  • 52. 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
  • 53. 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
  • 54. 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
  • 55. 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
  • 56. 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
  • 57. 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
  • 58. 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
  • 59. 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
  • 60. 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)
  • 61. I will now take a 15 second break and play a relevant video clip INTERMISSION
  • 62.
  • 63. 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
  • 64. 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
  • 65. 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
  • 66. 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
  • 67. 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
  • 68.
  • 69. 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. huh
  • 70. 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. Miguel Grinberg
  • 71. 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. !
  • 72. 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
  • 73. 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
  • 74. 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!
  • 76. 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
  • 77. 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?
  • 78. - db independence - easy integration - focus on models - connection pooling pros » ease of use
  • 79. easy integration - focus on models - connection pooling pros » ease of use » db independence
  • 80. focus on models - connection pooling pros » ease of use » db independence » easy integration
  • 81. - connection pooling pros » ease of use » db independence » easy integration » focus on models
  • 82. pros » ease of use » db independence » easy integration » focus on models » connection pooling
  • 83. 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 cons » time
  • 84. 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
  • 85. 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
  • 86. 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
  • 87. 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
  • 88. 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
  • 89. 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
  • 90. 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
  • 91. 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
  • 92. 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
  • 93. 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
  • 94. 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))
  • 95. 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
  • 96. 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);
  • 97. 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
  • 99. 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
  • 100. 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
  • 101. 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
  • 102. 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
  • 103. 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
  • 104. 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
  • 105. 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
  • 106. 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
  • 107. 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
  • 108. 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
  • 109. 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
  • 110. 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
  • 111. 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
  • 112. 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
  • 113. 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
  • 114. 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
  • 115. Try to understand how things work under the hood NEXT: SHARE WHAT YOU LEARN » deep learning
  • 116. Write blog posts. Even if no one reads them, you'll organize your thoughts. Or give talks. Like this one NEXT: KNOW WHEN TO STOP » deep learning » share what you learn
  • 117. 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
  • 118. 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 builders NEXT: SECOND-MOST IMPORTANT TASK IS TO WRITE BEAUTIFUL CODE » deep learning » share what you learn » know when to stop » character builders
  • 119. 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
  • 120. 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
  • 121. adult