WEBVTT 00:00:00.001 --> 00:00:01.860 Are you considering getting into web programming? 00:00:01.860 --> 00:00:05.540 Choosing a web framework like Pyramid Flask or Django can be daunting. 00:00:05.540 --> 00:00:10.740 It would be great to see them all build out the same application and compare the results side by side. 00:00:10.740 --> 00:00:15.000 That's why when I heard what Nicholas Hunt Walker was up to, I had to have him on the podcast. 00:00:15.000 --> 00:00:18.320 He and I chatted about four web frameworks compared. 00:00:18.320 --> 00:00:22.340 He built a data-driven web app with Flask, Tornado, Pyramid, and Django, 00:00:22.340 --> 00:00:24.360 and then put it all together in a presentation. 00:00:24.360 --> 00:00:26.820 We're going to dive into that right now. 00:00:26.820 --> 00:00:32.200 This is Talk Python To Me, episode 149, recorded January 30th, 2018. 00:00:32.200 --> 00:00:52.500 Welcome to Talk Python To Me, a weekly podcast on Python, the language, the libraries, the ecosystem, and the personalities. 00:00:52.500 --> 00:00:54.620 This is your host, Michael Kennedy. 00:00:54.620 --> 00:00:56.620 Follow me on Twitter, where I'm @mkennedy. 00:00:56.620 --> 00:01:03.100 Keep up with the show and listen to past episodes at talkpython.fm, and follow the show on Twitter via at Talk Python. 00:01:03.100 --> 00:01:06.640 Talk Python To Me is partially supported by our training courses. 00:01:06.640 --> 00:01:09.620 How does your team keep their Python skills sharp? 00:01:09.620 --> 00:01:13.760 How do you make sure new hires get started fast and learn the Pythonic way? 00:01:14.540 --> 00:01:22.760 If the answer is a series of boring videos that don't inspire or a subscription service you pay way too much for and use way too little, listen up. 00:01:22.760 --> 00:01:26.660 At Talk Python Training, we have enterprise tiers for all of our courses. 00:01:26.660 --> 00:01:31.220 Get just the one course you need for your team with full reporting and monitoring. 00:01:31.620 --> 00:01:38.940 Or ditch that unused subscription for our course bundles, which include all the courses, and you pay about the same price as a subscription once. 00:01:38.940 --> 00:01:46.260 For details, visit training. talkpython.fm/business or just email sales at talkpython.fm. 00:01:47.260 --> 00:01:48.440 Nick, welcome to Talk Python. 00:01:48.440 --> 00:01:49.360 Hey, thanks for having me. 00:01:49.360 --> 00:01:50.380 Yeah, it's great to be here. 00:01:50.380 --> 00:01:53.540 It was really nice to meet you last week at PyCascades. 00:01:53.540 --> 00:01:54.500 That was a fun conference. 00:01:54.500 --> 00:01:55.760 Oh, man, that was awesome. 00:01:55.760 --> 00:02:01.440 That was my second Python conference ever, and it was on par for me with PyCon. 00:02:01.440 --> 00:02:02.960 Yeah, it was definitely a different vibe. 00:02:02.960 --> 00:02:10.020 It wasn't like a huge expo hall or things like that, but I felt it made up for it in the richness of conversations. 00:02:10.020 --> 00:02:13.480 You could sit and talk with three or four people, and those people were amazing. 00:02:13.640 --> 00:02:16.800 Right, and the one thing that's been different is I've done a lot of academic conferences. 00:02:16.800 --> 00:02:21.620 I used to do astronomy, so I've been to a few national conferences, and I've always missed out on talks. 00:02:21.620 --> 00:02:27.300 And this is the first conference that I've gone to where I had the actual opportunity to sit and hear every talk. 00:02:27.300 --> 00:02:29.460 I didn't feel like I missed out on anything. 00:02:29.460 --> 00:02:30.760 Yeah, and the talks were really good. 00:02:30.760 --> 00:02:31.680 So congrats to everyone. 00:02:31.680 --> 00:02:37.460 That's a new conference, and you missed it this year, but it's coming to Seattle next year and then Portland the year after. 00:02:37.460 --> 00:02:41.060 And it's supposed to kind of go up and down the Cascades and the West Coast of the U.S., the mountain range. 00:02:41.060 --> 00:02:42.900 So it should be a lot of fun. 00:02:42.960 --> 00:02:45.100 I'm looking forward to going next year already. 00:02:45.100 --> 00:02:53.500 But that's not what we're here to talk about exactly, although we are going to cover a talk that you gave there, which sort of surveys a bunch of the popular web frameworks. 00:02:53.500 --> 00:02:54.400 And we'll get into that. 00:02:54.400 --> 00:02:55.900 So let's start with your story. 00:02:55.900 --> 00:02:57.560 How did you get into programming in Python? 00:02:57.560 --> 00:02:57.960 Sure. 00:02:57.960 --> 00:03:01.220 I actually didn't think I'd ever be programming, ever. 00:03:01.220 --> 00:03:05.100 I started doing astronomy back in about 2007. 00:03:05.760 --> 00:03:08.360 I just got really interested in how stars lived and died. 00:03:08.360 --> 00:03:10.020 And so I started doing astronomy. 00:03:10.020 --> 00:03:10.880 I started doing science. 00:03:10.880 --> 00:03:15.980 It seems like one of the most amazing parts of all science is astronomy these days. 00:03:15.980 --> 00:03:16.300 Yeah. 00:03:16.300 --> 00:03:18.040 I mean, there's a lot going on in astronomy. 00:03:18.200 --> 00:03:25.600 A lot of my former colleagues are doing some amazing work finding planets, learning about black holes that we didn't know existed, all kinds of great things. 00:03:25.600 --> 00:03:33.820 When I started doing astronomy, I naively thought that I would just be looking through telescopes and taking down notes and thinking through equations and that kind of thing. 00:03:33.860 --> 00:03:36.520 I didn't think I'd be writing any programs at all. 00:03:36.520 --> 00:03:41.980 And so when I got into grad school, even before I got into grad school, I had to learn how to program a little bit. 00:03:41.980 --> 00:03:43.240 And I used Fortran 77. 00:03:43.240 --> 00:03:46.280 And that was, I hated it. 00:03:46.280 --> 00:03:46.840 I hated it. 00:03:46.840 --> 00:03:47.380 I hated it. 00:03:47.380 --> 00:03:48.000 I did, too. 00:03:48.000 --> 00:03:49.000 I had to take it. 00:03:49.000 --> 00:03:50.340 I was in engineering at first. 00:03:50.340 --> 00:03:52.860 And they told me, I said, can I please take C++? 00:03:52.860 --> 00:03:54.540 They said, no, you have to take Fortran. 00:03:54.540 --> 00:03:56.400 It's the most important language you'll ever learn. 00:03:56.400 --> 00:03:58.000 I'm like, no. 00:03:58.340 --> 00:04:07.220 Well, it's one of those things where, like, when you're in academia and you're an undergrad or you're in grad school, you learn the language that your advisor knows. 00:04:07.220 --> 00:04:10.060 And my advisor knew Fortran, so I learned Fortran. 00:04:10.060 --> 00:04:13.120 And then when I went, that was at Columbia. 00:04:13.120 --> 00:04:14.900 I was in the Bridge to the PhD program there. 00:04:14.900 --> 00:04:16.560 It's a great program for the scientists. 00:04:16.560 --> 00:04:26.000 And when I transferred into a graduate program at the University of Washington, then my advisor was using a language called IDL. 00:04:26.000 --> 00:04:28.780 I forget what it even stands for, but it's a proprietary language. 00:04:28.780 --> 00:04:30.880 So you have to have a license on your computer to use it. 00:04:30.880 --> 00:04:35.540 And if you wanted to be able to, like, do work at home, you have to have a license on your home computer to use it. 00:04:35.540 --> 00:04:37.760 And so it's a whole lot of stuff with that. 00:04:37.760 --> 00:04:40.240 You have to be connected to the internet so they can verify your license. 00:04:40.240 --> 00:04:41.500 Oh, it's that intense? 00:04:41.500 --> 00:04:43.740 It has, like, almost like a dongle type thing? 00:04:43.740 --> 00:04:44.340 No, it's not a dongle. 00:04:44.340 --> 00:04:49.580 It's more like if you're not connected to the internet, then you can't use the IDL editor. 00:04:49.580 --> 00:04:50.280 Wow, that's intense. 00:04:50.280 --> 00:04:51.960 And you can't run your IDL program. 00:04:51.960 --> 00:04:53.200 That's kind of the opposite of it. 00:04:53.200 --> 00:04:53.520 Which sucks. 00:04:53.520 --> 00:04:54.620 Yeah, it's terrible. 00:04:55.620 --> 00:04:56.560 Exactly, exactly. 00:04:56.560 --> 00:05:00.460 And so I actually learned Python partially to get away from IDL. 00:05:00.460 --> 00:05:02.460 It was kind of my way out. 00:05:02.460 --> 00:05:06.620 I was like, I had been introduced to this language, and I was like, oh, this is a free thing. 00:05:06.620 --> 00:05:08.800 I don't have to have a separate license to do this. 00:05:08.800 --> 00:05:10.340 I can install it on any machine. 00:05:10.340 --> 00:05:11.900 It looks like English. 00:05:11.900 --> 00:05:12.740 Like, this is... 00:05:12.740 --> 00:05:13.260 Yeah, yeah. 00:05:13.260 --> 00:05:13.920 Why not? 00:05:13.920 --> 00:05:14.560 Yeah, absolutely. 00:05:14.900 --> 00:05:16.800 So I used Python for my research. 00:05:16.800 --> 00:05:17.740 I used Python for my homework. 00:05:17.740 --> 00:05:22.600 And then one of my colleagues at the time, like, and this is kind of where it really took off for me. 00:05:22.600 --> 00:05:25.600 He had been doing blog posts about science. 00:05:25.600 --> 00:05:26.660 And I was like, oh, that sounds cool. 00:05:26.660 --> 00:05:27.320 I should do that too. 00:05:28.320 --> 00:05:33.920 And I used Python to help me learn more about the science that I was doing. 00:05:33.920 --> 00:05:36.360 And I was using the science to help me learn more about the Python that I was writing. 00:05:36.360 --> 00:05:43.580 And so I kind of got a lot of that practice, you know, after hours, just using Python to answer interesting questions. 00:05:43.800 --> 00:05:44.820 Yeah, that sounds really cool. 00:05:44.820 --> 00:05:48.440 It's a very organic story of just like, I kind of just found my way into it. 00:05:48.440 --> 00:05:51.000 And I just, you know, I sort of grew as you played with it. 00:05:51.000 --> 00:05:52.000 That's awesome. 00:05:52.000 --> 00:05:54.500 So like I said, I'm a big fan of astronomy. 00:05:54.500 --> 00:05:55.800 Are you still doing that today? 00:05:55.800 --> 00:05:56.600 You're not, right? 00:05:56.600 --> 00:05:57.600 You're sort of... 00:05:57.600 --> 00:05:57.960 I'm not. 00:05:57.960 --> 00:05:59.320 You took the path that I did. 00:05:59.320 --> 00:06:03.240 Like, let me work on a PhD and actually do nothing and just go programming with it later. 00:06:03.240 --> 00:06:04.760 Now I just feel bad. 00:06:04.760 --> 00:06:05.340 But yeah. 00:06:05.340 --> 00:06:06.640 No, I know I do too. 00:06:06.640 --> 00:06:09.700 I kind of looked at my advisors and stuff when I left. 00:06:09.700 --> 00:06:11.720 I'm like, yeah, I'm sorry, but I'm going. 00:06:11.720 --> 00:06:13.420 It was tough, actually. 00:06:13.540 --> 00:06:16.640 But I think it's totally the right choice for me. 00:06:16.640 --> 00:06:17.420 I don't know about you. 00:06:17.420 --> 00:06:18.840 Yeah, it was time. 00:06:18.840 --> 00:06:20.980 I wouldn't make a second choice in a second. 00:06:20.980 --> 00:06:26.440 You know, I met some great people there, but I'm much happier doing what I'm doing now. 00:06:26.440 --> 00:06:26.740 Yeah. 00:06:26.740 --> 00:06:31.840 I feel like the PC experience in all of grad school kind of taught me how to do what I do now. 00:06:31.840 --> 00:06:35.260 But I feel like I'm applying it in a place that makes a bigger difference for more people. 00:06:35.260 --> 00:06:35.740 Right. 00:06:35.740 --> 00:06:39.140 I'm still doing as much reading as I was doing during my PhD program. 00:06:39.140 --> 00:06:42.280 I'm still doing as much thinking, but it's toward... 00:06:42.800 --> 00:06:45.900 So one of the problems that I had with the work that I was doing in my PhD program was 00:06:45.900 --> 00:06:50.360 it was not very easy to explain to other people why it was interesting or important. 00:06:50.360 --> 00:06:51.780 I knew why it was interesting or important. 00:06:51.780 --> 00:06:55.920 I love like aged stars and seeing how like what was happening as they were dying. 00:06:55.920 --> 00:06:59.920 But in order to explain that, I've got to explain, okay, look, this is how stars evolve. 00:06:59.920 --> 00:07:01.720 This is what all this stuff means. 00:07:01.920 --> 00:07:03.760 I've got to apply all this background. 00:07:03.760 --> 00:07:07.020 Whereas, you know, what I'm doing right now, I'm teaching at Code Fellows. 00:07:07.020 --> 00:07:10.940 And I can just say, you know, I'm teaching people how to program, you know, teaching people how to make websites. 00:07:11.480 --> 00:07:22.880 So, you know, the kind of stuff you see like a Google.com or anything.com, I'm teaching people to do that, at least at the basic level so they can go out into the real world and get a job and do that stuff for real. 00:07:22.880 --> 00:07:23.240 Yeah. 00:07:23.360 --> 00:07:30.720 And it's a great experience to help people sort of change careers or advance their career down some other path they weren't doing before. 00:07:30.720 --> 00:07:32.660 So what is a typical day? 00:07:32.660 --> 00:07:35.940 So Code Fellows is a boot camp for those who don't know, right? 00:07:35.940 --> 00:07:37.720 And what's a typical day there look like? 00:07:37.720 --> 00:07:37.980 Yeah. 00:07:37.980 --> 00:07:40.120 Code Fellows is one of the coding schools in Seattle. 00:07:40.120 --> 00:07:41.300 I'm a little biased. 00:07:41.300 --> 00:07:42.400 I think it's one of the best ones. 00:07:42.400 --> 00:07:45.320 But I also work here and I know some really good people. 00:07:45.320 --> 00:07:49.180 But a typical day when I'm teaching looks like three hours of lecture. 00:07:49.180 --> 00:07:52.540 Let's say I'm teaching one of my Python lectures. 00:07:52.760 --> 00:07:55.140 It's like, okay, we do about an hour of code review. 00:07:55.140 --> 00:07:56.960 And then we talk about some topics. 00:07:56.960 --> 00:07:58.060 We do some data structures. 00:07:58.060 --> 00:07:59.780 We do some algorithms practice. 00:07:59.780 --> 00:08:09.260 I'll teach you about a web framework or some aspects of a web framework, like what a model is or what a view is or how to do routing or security, that kind of thing. 00:08:09.260 --> 00:08:11.340 And then we go to lunch. 00:08:11.340 --> 00:08:15.460 And afterward, they come back and they work with each other on lab assignments. 00:08:15.460 --> 00:08:18.220 And we build the lab assignments to complement the lectures. 00:08:18.660 --> 00:08:19.520 And so I teach a thing. 00:08:19.520 --> 00:08:23.240 And then they use that concept in their application. 00:08:23.240 --> 00:08:26.260 And after that point in time, they're kind of on their own. 00:08:26.260 --> 00:08:28.040 They're still on location. 00:08:28.040 --> 00:08:30.120 But they're on their own building the projects. 00:08:31.180 --> 00:08:36.860 And myself and the TAs are here to grade their assignments and to be resources when they need help. 00:08:36.860 --> 00:08:38.500 Yeah, that sounds like a really fun job. 00:08:38.500 --> 00:08:39.820 And how long does the boot camp run for? 00:08:39.820 --> 00:08:40.900 The full sequence. 00:08:40.900 --> 00:08:42.240 So there's three levels to it. 00:08:42.240 --> 00:08:43.340 201, 301, and 401. 00:08:43.340 --> 00:08:45.080 201 is four weeks. 00:08:45.700 --> 00:08:48.400 And that's the basics of HTML, CSS, and JavaScript. 00:08:48.400 --> 00:08:50.680 And then the 301 is also four weeks. 00:08:50.680 --> 00:08:51.820 Because you have to do that. 00:08:51.820 --> 00:08:53.320 There's no way to avoid JavaScript. 00:08:53.320 --> 00:08:53.720 Right. 00:08:53.720 --> 00:08:54.880 Like there's no way to avoid it. 00:08:54.880 --> 00:08:56.040 That is the language of the web. 00:08:56.040 --> 00:08:57.080 Let's be honest here. 00:08:57.080 --> 00:08:57.340 Yep. 00:08:57.340 --> 00:08:58.220 It is. 00:08:58.220 --> 00:08:59.820 So 301 is also four weeks. 00:08:59.820 --> 00:09:00.560 That's more intermediate. 00:09:00.560 --> 00:09:01.800 HTML, CSS, and JavaScript. 00:09:01.800 --> 00:09:02.660 We talk about jQuery. 00:09:02.660 --> 00:09:03.640 We talk about more libraries. 00:09:04.200 --> 00:09:09.300 We kind of get people kind of more interested in the wider scope of being a web developer. 00:09:09.300 --> 00:09:13.160 We start dipping into the back end a little bit with Express, but not too much. 00:09:13.160 --> 00:09:15.980 And then in the 401, that's 10 weeks. 00:09:15.980 --> 00:09:17.440 We have several 401s. 00:09:17.440 --> 00:09:18.980 We have Python. 00:09:18.980 --> 00:09:19.800 We have JavaScript. 00:09:19.800 --> 00:09:20.460 We have Java. 00:09:20.460 --> 00:09:22.160 We have C#.net. 00:09:22.160 --> 00:09:23.920 And that's 10 weeks. 00:09:23.920 --> 00:09:30.060 For the Python class, that's basics of Python, a preliminary web framework like Pyramid, 00:09:30.060 --> 00:09:32.720 and then a more advanced web framework like Django. 00:09:32.720 --> 00:09:36.600 This is actually where my talk came from because I've been teaching this course or at least 00:09:36.600 --> 00:09:40.340 being a part of the teaching process in some way, shape, or form for the last almost two 00:09:40.340 --> 00:09:43.360 years and having all this exposure to it. 00:09:43.360 --> 00:09:46.520 And I was like, huh, I wonder what these other frameworks look like because I'd only ever 00:09:46.520 --> 00:09:46.900 taught. 00:09:46.900 --> 00:09:50.520 I'd never actually learned Python for web development in my graduate work. 00:09:50.520 --> 00:09:51.400 I was doing astronomy. 00:09:51.400 --> 00:09:52.260 I was doing data analysis. 00:09:52.260 --> 00:09:54.700 I only learned how to do this stuff on the job. 00:09:54.700 --> 00:10:00.100 They don't have web frameworks for machine learning across. 00:10:00.100 --> 00:10:02.580 You don't build web apps, right? 00:10:02.620 --> 00:10:03.660 You do build other stuff. 00:10:03.660 --> 00:10:05.120 Yeah, it's all custom software. 00:10:05.120 --> 00:10:05.900 Yeah, exactly. 00:10:05.900 --> 00:10:07.860 I'd never actually used Python for web development. 00:10:07.860 --> 00:10:10.000 So I only learned this stuff when I was on the job. 00:10:10.000 --> 00:10:14.160 And so I'd only been exposed to Pyramid and Django. 00:10:14.160 --> 00:10:18.160 I did a little bit of Flask just kind of as a one-off thing, but I didn't really understand 00:10:18.160 --> 00:10:19.060 what I was doing. 00:10:19.060 --> 00:10:22.360 So I didn't really take the time to get to dig into these web frameworks. 00:10:22.360 --> 00:10:25.540 I was like, okay, I wonder what these other ones are like. 00:10:26.180 --> 00:10:29.740 I should try to talk about that because I'm sure I'm not the only one who thinks this. 00:10:29.740 --> 00:10:34.060 No, I think it's a super interesting idea because a lot of times what I find is people, 00:10:34.060 --> 00:10:36.560 they kind of do a quick survey. 00:10:36.560 --> 00:10:37.720 They're like, all right, what's out there? 00:10:37.720 --> 00:10:38.080 Django. 00:10:38.080 --> 00:10:39.780 Okay, there's a lot of building blocks already built. 00:10:39.780 --> 00:10:40.620 They're kind of big. 00:10:40.620 --> 00:10:43.240 And I like, okay, well, there's a micro frameworks and they're really small. 00:10:43.240 --> 00:10:43.960 I put pieces together. 00:10:44.400 --> 00:10:45.600 This one or that one is mine. 00:10:45.600 --> 00:10:46.560 That's my style. 00:10:46.560 --> 00:10:46.980 I'm going to do it. 00:10:46.980 --> 00:10:48.380 And then they kind of just stop, right? 00:10:48.380 --> 00:10:51.060 You learn what you need to know to do the job you try to do. 00:10:51.060 --> 00:10:51.320 Yeah. 00:10:51.320 --> 00:10:56.440 And most people aren't doing, unless you're a contractor, you're not doing a new project 00:10:56.440 --> 00:10:57.120 every three months. 00:10:57.120 --> 00:10:58.040 In a different framework. 00:10:58.040 --> 00:10:58.380 Right. 00:10:58.380 --> 00:11:01.160 In a different framework or a different language entirely. 00:11:01.160 --> 00:11:02.900 You have your job. 00:11:02.900 --> 00:11:08.140 You might jump around from company to company, but you still like, most places are hiring for 00:11:08.140 --> 00:11:09.160 Django, so you learn Django. 00:11:09.160 --> 00:11:10.960 Or they're hiring for Flask, so you learn Flask. 00:11:10.960 --> 00:11:12.960 Or you're just building tools for the backend. 00:11:13.760 --> 00:11:21.200 But yeah, in my 10-week class, it's all that plus data structures and algorithms and a little 00:11:21.200 --> 00:11:22.120 smattering of machine learning. 00:11:22.120 --> 00:11:26.860 So it's like end to end with the week breaking between each class, it's about 20 weeks total. 00:11:26.860 --> 00:11:27.180 Wow. 00:11:27.180 --> 00:11:28.140 It sounds really fun. 00:11:28.140 --> 00:11:32.240 It's something like I could actually kind of enjoy hanging out there and just being part 00:11:32.240 --> 00:11:32.400 of that. 00:11:32.400 --> 00:11:32.960 That sounds fun. 00:11:32.960 --> 00:11:33.480 It's great. 00:11:33.480 --> 00:11:34.160 It's super intense. 00:11:34.160 --> 00:11:39.960 And honestly, now that I've taught it, I really wish that I had learned to program this way. 00:11:39.960 --> 00:11:41.440 It's really directed. 00:11:41.440 --> 00:11:46.400 When you go through undergrad and you get your degree, you've got to do a lot of ancillary 00:11:46.400 --> 00:11:49.120 stuff, which is great for building a well-rounded person. 00:11:49.120 --> 00:11:53.440 But if you're focused on just wanting to do one thing, it tends to get distracting. 00:11:53.440 --> 00:11:57.040 Whereas with this, the goal is clear. 00:11:57.040 --> 00:11:58.600 We want you to get a job. 00:11:58.820 --> 00:12:03.340 So we're going to train you to be able to do the things that jobs are asking you to do. 00:12:03.340 --> 00:12:04.180 And that's it. 00:12:04.180 --> 00:12:06.400 There's no humanities requirements. 00:12:06.400 --> 00:12:08.620 There's no other paths here. 00:12:08.620 --> 00:12:10.640 It's just like you're here for a specific reason. 00:12:10.640 --> 00:12:14.020 If your cause doesn't fit that reason, then you want to go somewhere else. 00:12:14.020 --> 00:12:15.360 But it's directed. 00:12:15.360 --> 00:12:15.940 It's focused. 00:12:16.420 --> 00:12:20.100 And it's cheaper than an undergraduate degree by far. 00:12:20.100 --> 00:12:21.280 Yeah. 00:12:21.280 --> 00:12:22.020 By quite a bit. 00:12:22.020 --> 00:12:22.340 Yeah. 00:12:22.340 --> 00:12:23.280 And time and money. 00:12:23.280 --> 00:12:23.880 That's cool. 00:12:23.880 --> 00:12:26.280 I mean, I'm a huge fan of the liberal arts education. 00:12:26.280 --> 00:12:28.520 I feel like it's good to be a well-rounded person. 00:12:28.520 --> 00:12:34.800 But I'm not entirely sure how much college should drive career training. 00:12:34.800 --> 00:12:39.740 You know, more like be a good person in society and be well-informed. 00:12:39.740 --> 00:12:41.940 Now go learn the thing, right? 00:12:41.940 --> 00:12:42.280 Yeah. 00:12:42.280 --> 00:12:44.720 And I mean, it's also good for networking. 00:12:44.720 --> 00:12:48.060 It's good for, you know, expanding your interests beyond whatever you learned in high school. 00:12:48.060 --> 00:12:54.100 But, you know, most of the people that we get are people who are changing jobs, not people fresh out of high school. 00:12:54.100 --> 00:12:59.600 I've had a few people who are fresh out of high school, but most folks have gone through, you know, they might have an undergraduate degree. 00:12:59.600 --> 00:13:03.520 I've even had a few people with CS degrees, but they've had a job before. 00:13:03.900 --> 00:13:05.380 They want to do a different job. 00:13:05.380 --> 00:13:07.080 They don't need all the ancillary stuff. 00:13:07.080 --> 00:13:09.400 They just want to know how to do a new job, which is fine. 00:13:09.400 --> 00:13:11.020 And we teach them how to do that. 00:13:11.020 --> 00:13:11.300 Yeah. 00:13:11.300 --> 00:13:11.740 Yeah. 00:13:11.740 --> 00:13:12.180 That's cool. 00:13:12.180 --> 00:13:12.900 That's excellent. 00:13:12.900 --> 00:13:14.320 Yeah. 00:13:14.320 --> 00:13:25.600 So let's talk about your, the four frameworks that you chose and maybe even start with just because with the app, because your idea was, I'm going to build the same app in four different frameworks. 00:13:25.600 --> 00:13:26.220 Right. 00:13:26.220 --> 00:13:27.360 So what's that? 00:13:27.360 --> 00:13:27.880 Yeah. 00:13:27.880 --> 00:13:33.840 So the app itself, I tried to keep it as simple as possible while still displaying, you know, the aspects of what a web. 00:13:33.840 --> 00:13:34.560 A framework should handle. 00:13:34.560 --> 00:13:38.460 And so I chose a to do list, which is, you know, everyone knows a to do list. 00:13:38.460 --> 00:13:40.960 So there's not much that needs to be explained in that way. 00:13:40.960 --> 00:13:43.060 So when I get to talk, it's like, Hey, you know what a to do list is. 00:13:43.060 --> 00:13:44.480 This app does that. 00:13:44.480 --> 00:13:48.400 You know, with this, with this application, you can, you can add new users through registration. 00:13:48.400 --> 00:13:49.520 You can log in, log out. 00:13:49.520 --> 00:13:54.240 You can add new tasks, edit existing ones or complete existing ones. 00:13:54.240 --> 00:13:55.520 You can even delete them if you want to. 00:13:55.520 --> 00:14:02.420 And so that's just kind of the backdrop for investigating how these four frameworks work. 00:14:02.420 --> 00:14:02.720 Yeah. 00:14:02.860 --> 00:14:05.980 That sounds pretty simple, but actually it touches on a lot of stuff. 00:14:05.980 --> 00:14:07.740 You've got a data access layer. 00:14:07.740 --> 00:14:08.580 You've got a database. 00:14:08.580 --> 00:14:12.780 You've got forms because you've got to post back information to register. 00:14:12.780 --> 00:14:14.820 You've got like secure user management. 00:14:14.820 --> 00:14:16.840 There's a lot of stuff actually going on there. 00:14:17.080 --> 00:14:17.560 Oh, absolutely. 00:14:17.560 --> 00:14:20.700 And I didn't, I didn't get to go into all of it in my talk. 00:14:20.700 --> 00:14:23.700 I didn't even get to finish writing all the code just because time got away from me, but 00:14:23.700 --> 00:14:27.860 it's not just, I'm going to send some data somewhere and it gets handled. 00:14:27.860 --> 00:14:28.360 It's okay. 00:14:28.360 --> 00:14:29.780 How exactly is it being handled? 00:14:29.780 --> 00:14:30.960 What exactly am I handling? 00:14:30.960 --> 00:14:33.440 And how is every web framework supposed to be doing it? 00:14:33.440 --> 00:14:39.940 And so when I originally wrote this talk, it was looking at each aspect of a web framework 00:14:39.940 --> 00:14:41.180 across all four. 00:14:41.180 --> 00:14:46.900 And then I revised it to look at each web framework one at a time, doing all the things that's, 00:14:46.940 --> 00:14:48.460 that the app requires. 00:14:48.460 --> 00:14:55.200 So I started with Flask and the setup and installation and then getting things up and running 00:14:55.200 --> 00:14:57.800 configuration and then how to make a view. 00:14:57.800 --> 00:15:01.340 So like a view is just a function that handles a request. 00:15:01.340 --> 00:15:05.600 So an incoming HTTP request and sends back a properly formatted response. 00:15:05.600 --> 00:15:09.760 And the benefit of web frameworks, and this is definitely something that my students learn 00:15:09.760 --> 00:15:14.920 because I have them build a web server from scratch as part of the course, is that you 00:15:14.920 --> 00:15:20.500 don't have to worry about a lot of the stuff that goes into building a response or parsing 00:15:20.500 --> 00:15:21.340 an existing request. 00:15:21.340 --> 00:15:24.720 There's so many different ways that an incoming request can go wrong. 00:15:24.720 --> 00:15:27.140 And you don't have to think through all that logic. 00:15:27.140 --> 00:15:29.200 You want to think more about how your app is supposed to work. 00:15:29.200 --> 00:15:29.380 Right. 00:15:29.420 --> 00:15:32.460 You could open a socket and just go to town on that thing. 00:15:32.460 --> 00:15:32.720 Right. 00:15:32.720 --> 00:15:33.340 But right. 00:15:33.340 --> 00:15:37.940 You know, splitting strings and using regex to find different parts of the request headers 00:15:37.940 --> 00:15:39.180 and all that stuff. 00:15:39.180 --> 00:15:41.360 But who wants, no one wants to do all that. 00:15:41.360 --> 00:15:41.940 No, no, no. 00:15:41.940 --> 00:15:43.580 Something that's already pre-built. 00:15:43.580 --> 00:15:47.020 And you know, people smarter than myself have done it. 00:15:47.140 --> 00:15:48.440 So why should I do it myself? 00:15:48.440 --> 00:15:48.860 Exactly. 00:15:48.860 --> 00:15:50.820 And there's people actively working on it. 00:15:50.820 --> 00:15:53.520 So the four frameworks you chose, you chose Flask. 00:15:53.520 --> 00:15:56.580 And then Tornado, I thought, was an interesting option. 00:15:56.580 --> 00:15:57.000 Yeah. 00:15:57.000 --> 00:15:58.340 I had heard about Tornado. 00:15:58.340 --> 00:16:03.420 And I didn't have any idea what it looked like, what it would do. 00:16:03.420 --> 00:16:05.820 But I heard the word async. 00:16:05.820 --> 00:16:07.920 And I was like, that should be useful. 00:16:07.920 --> 00:16:08.980 That sounds fun. 00:16:08.980 --> 00:16:09.200 Yeah. 00:16:09.200 --> 00:16:09.980 That sounds really fun. 00:16:09.980 --> 00:16:10.600 That's cool. 00:16:10.600 --> 00:16:11.700 So yeah, I'll dig into it. 00:16:11.740 --> 00:16:11.880 Yeah. 00:16:11.880 --> 00:16:13.640 And you've got Pyramid and Django. 00:16:13.640 --> 00:16:14.960 So those are the four. 00:16:14.960 --> 00:16:17.860 And let's, I guess, start with Flask. 00:16:17.860 --> 00:16:21.360 It's on the smallish side, right? 00:16:21.360 --> 00:16:22.620 It doesn't bring a lot to the table. 00:16:22.620 --> 00:16:23.860 It's one of these micro frameworks. 00:16:23.860 --> 00:16:29.540 But for your example, you still use Flask, Flask SQLAlchemy, and Flask HTTP Auth, right? 00:16:29.540 --> 00:16:30.060 Right. 00:16:30.060 --> 00:16:34.640 And I have to have those external packages because Flask really is the barest bones. 00:16:34.640 --> 00:16:39.540 Where a framework, it's just, you know, you can make a function that handles requests 00:16:39.540 --> 00:16:40.940 and returns a response. 00:16:41.520 --> 00:16:44.040 And that's all that Flask does on its own. 00:16:44.040 --> 00:16:44.700 Yeah, pretty much. 00:16:44.700 --> 00:16:49.720 And so if you want to talk to a database, or if you want to do any sort of authentication, 00:16:49.720 --> 00:16:52.780 you've got to use something else or write your own. 00:16:52.780 --> 00:16:52.980 Yeah. 00:16:52.980 --> 00:16:57.100 So like Flask, and there's benefits and drawbacks to each of those. 00:16:57.100 --> 00:17:01.020 So like if you want to use a database like a MongoDB database, you download the package 00:17:01.020 --> 00:17:04.220 that someone has written to use Flask MongoDB. 00:17:04.220 --> 00:17:12.040 Or you can even just write, you know, straight up queries on your own without using a go-between. 00:17:12.040 --> 00:17:13.760 And then that'll work. 00:17:13.760 --> 00:17:14.000 Right. 00:17:14.000 --> 00:17:17.260 Just write a couple lines of code and like sort of piece it together yourself. 00:17:17.260 --> 00:17:17.540 Right. 00:17:17.540 --> 00:17:21.100 And that's something you can do, especially if you only need a very small application. 00:17:21.840 --> 00:17:22.940 Flask is the way to go. 00:17:22.940 --> 00:17:28.300 Once you want to start doing more of the classical CRUD application, CRUD being create, read, update, 00:17:28.300 --> 00:17:32.060 and delete functions, you're going to start wanting to move away from Flask. 00:17:32.060 --> 00:17:36.000 Just because it can still do those things, but it becomes harder. 00:17:36.220 --> 00:17:38.540 Yeah, you do more of the legwork yourself. 00:17:38.540 --> 00:17:38.800 Yeah. 00:17:38.800 --> 00:17:42.880 So maybe let's go through, like, we'll kind of go through the same section for each framework. 00:17:42.880 --> 00:17:49.080 For Flask, let's talk about like, how do you like connect to the database and sort of incorporate that? 00:17:49.080 --> 00:17:49.540 Sure. 00:17:49.540 --> 00:17:53.180 So I'm a fan of the 12-factor application. 00:17:53.180 --> 00:17:57.440 Give us the quick summary on what 12-factor app is, if you can. 00:17:57.440 --> 00:17:57.680 Sure. 00:17:57.680 --> 00:18:05.100 And the way that I'm trying to connect to it here is that one of the parts that's important is having your code not change between development production. 00:18:05.760 --> 00:18:09.980 Instead, be dependent on your environment and the variables that are set in your environment. 00:18:09.980 --> 00:18:17.340 So my application should have the same code running, whether it's on my own machine or on Heroku or on AWS. 00:18:17.340 --> 00:18:21.960 All that I'm changing are some flags, like, you know, am I in debug or not? 00:18:21.960 --> 00:18:24.680 Is my database a local database or is it a remote database? 00:18:24.680 --> 00:18:27.000 And so one of the ways that I do that is I use an environment variable. 00:18:27.000 --> 00:18:30.340 I call it database URL just because I use that everywhere. 00:18:30.340 --> 00:18:31.940 That's used in several places. 00:18:31.940 --> 00:18:35.260 One of the places it's used is Heroku, so it makes it very easy for that. 00:18:35.300 --> 00:18:40.520 So I use an environment variable called database URL to point to my database's URL. 00:18:40.920 --> 00:18:45.660 And then I use an environment variable called Flask Gap to point to the directory of my Flask Gap. 00:18:45.660 --> 00:18:52.400 And then I put all my working code in the location of my Flask Gap, that app.py file. 00:18:52.400 --> 00:18:52.700 Right. 00:18:52.700 --> 00:18:53.940 Yes, you just have the app.py. 00:18:53.940 --> 00:18:57.320 And basically, you could just use Flask.sqlalchemy. 00:18:57.320 --> 00:18:58.820 And what is that like? 00:18:58.820 --> 00:18:59.700 Is that integrated? 00:18:59.700 --> 00:19:01.740 It creates a sort of a base model, right? 00:19:01.740 --> 00:19:06.320 If you do SQLAlchemy on its own, you've got to create the declarative base and do all of that stuff. 00:19:06.320 --> 00:19:11.580 And so the Flask SQLAlchemy kind of does a little bit of that work for you, right? 00:19:11.580 --> 00:19:14.500 Yeah, Flask SQLAlchemy takes care of a lot of that work for you. 00:19:14.500 --> 00:19:16.860 It just gives you this model object that you use. 00:19:16.860 --> 00:19:20.520 That includes the declarative base and all the SQLAlchemy machinery. 00:19:20.800 --> 00:19:25.240 But just lets you focus on building the actual objects that you want to insert into your database. 00:19:25.240 --> 00:19:29.500 And it also does a nice thing for you where it includes a method. 00:19:29.500 --> 00:19:30.560 No, I guess it's not a method. 00:19:30.560 --> 00:19:35.380 It's an attribute on the model object that you create that will talk to the database for you. 00:19:35.380 --> 00:19:40.160 So you can query for one object by just saying, you know, object name.query.all. 00:19:40.160 --> 00:19:42.640 And that gives you all the instances of that object in your database. 00:19:42.640 --> 00:19:43.200 Oh, yeah. 00:19:43.200 --> 00:19:43.880 That's really cool. 00:19:43.880 --> 00:19:47.240 Because otherwise, you have to, like, create a session and then use the session to create the query. 00:19:47.240 --> 00:19:48.040 Right. 00:19:48.040 --> 00:19:52.140 Yeah, so it's kind of like a convenience wrapper around the SQLAlchemy stuff. 00:19:52.140 --> 00:19:55.420 But for the models and everything, you just define them the same, more or less. 00:19:55.420 --> 00:19:55.920 Right. 00:19:55.920 --> 00:19:58.080 You set up columns by declaring columns. 00:19:58.080 --> 00:19:59.360 Yeah, it's really easy. 00:19:59.360 --> 00:20:00.660 You set up columns by declaring columns. 00:20:00.660 --> 00:20:03.800 If you want a primary key field, you say, this column is going to have a primary key. 00:20:03.800 --> 00:20:05.160 And it's going to be true. 00:20:05.160 --> 00:20:06.560 Like, the primary key flag is true. 00:20:06.560 --> 00:20:11.800 If you want to set up an explicit table name, you have a table name attribute that you set in your class. 00:20:11.800 --> 00:20:13.460 Any other behavior you want to have. 00:20:13.460 --> 00:20:15.140 You know, it's still a class in Python. 00:20:15.300 --> 00:20:18.100 So you can still add whatever methods you want to do special things. 00:20:18.100 --> 00:20:18.980 Right, right. 00:20:18.980 --> 00:20:21.380 I find I don't do that often, but a little bit. 00:20:21.380 --> 00:20:28.060 There's sometimes there's just, like, a few things you want to compute in Python related to that entity. 00:20:28.060 --> 00:20:30.420 And you're just like, oh, it just needs, like, a property or something here. 00:20:30.420 --> 00:20:31.080 And it'll be perfect. 00:20:31.080 --> 00:20:31.700 Exactly. 00:20:32.020 --> 00:20:36.000 And one of the things that I use that for was, so in my models, I have two models. 00:20:36.000 --> 00:20:38.680 I have a task model, which is the actual, like, to-do list task. 00:20:38.680 --> 00:20:42.360 And then I have a profile model, which is the user who has the tasks. 00:20:42.360 --> 00:20:48.080 And one of the things I wanted to do was when you register a user, automatically give them, like, they joined. 00:20:48.460 --> 00:20:53.160 And then also automatically give them, like, a secret token that you can use to log in and log out with. 00:20:53.160 --> 00:20:56.000 And that's not handled by SQLAlchemy. 00:20:56.380 --> 00:21:03.980 And so in the init method, I just say, you know, do whatever you were going to do in your init method, but also set these properties on the class. 00:21:03.980 --> 00:21:05.300 Yeah, I really like that. 00:21:05.300 --> 00:21:09.720 This portion of Talk Python To Me is brought to you by Linode. 00:21:09.720 --> 00:21:13.660 Are you looking for bulletproof hosting that's fast, simple, and incredibly affordable? 00:21:13.660 --> 00:21:18.600 Look past that bookstore and check out Linode at talkpython.fm/Linode. 00:21:18.600 --> 00:21:20.520 That's L-I-N-O-D-E. 00:21:20.520 --> 00:21:25.000 Plans start at just $5 a month for a dedicated server with a gig of RAM. 00:21:25.280 --> 00:21:27.520 They have 10 data centers across the globe. 00:21:27.520 --> 00:21:30.040 So no matter where you are, there's a data center near you. 00:21:30.040 --> 00:21:38.080 Whether you want to run your Python web app, host a private Git server, or file server, you'll get native SSDs on all the machines, 00:21:38.080 --> 00:21:45.360 a newly upgraded 200 gigabit network, 24-7 friendly support, even on holidays, and a seven-day money-back guarantee. 00:21:45.360 --> 00:21:47.720 Do you need a little help with your infrastructure? 00:21:47.720 --> 00:21:53.940 They even offer professional services to help you get started with architecture, migrations, and more. 00:21:54.500 --> 00:21:57.040 Get a dedicated server for free for the next four months. 00:21:57.040 --> 00:21:59.880 Just visit talkpython.fm/Linode. 00:22:02.380 --> 00:22:12.100 So then also the Flask SQLAlchemy comes with sort of a create all function that would be the, you go get the metadata and then do that on the base, right? 00:22:12.100 --> 00:22:14.080 There's like a little bit of a nice utility method there. 00:22:14.080 --> 00:22:16.260 Then when you talk, you talk about views. 00:22:16.260 --> 00:22:19.680 So in Flask, views are basically functions with a decorator. 00:22:19.680 --> 00:22:21.620 And they're super simple, right? 00:22:21.760 --> 00:22:23.480 Yeah, and that decorator, yeah, absolutely. 00:22:23.480 --> 00:22:25.600 That decorator is the app.route. 00:22:25.600 --> 00:22:27.880 So like your Flask app is the app object. 00:22:27.880 --> 00:22:31.180 And everything goes through there, including the routing. 00:22:31.180 --> 00:22:35.000 And you decorate every function that you want to be a view with app.route. 00:22:35.000 --> 00:22:39.620 And you pass as an argument to that decorator the actual route that's going to connect to this view. 00:22:39.680 --> 00:22:41.000 So let's say I want to have a home route. 00:22:41.000 --> 00:22:43.140 I say slash home is that route. 00:22:43.140 --> 00:22:50.240 For my decorator, I say, you know, the app symbol, app.route, and then slash home for my route. 00:22:50.240 --> 00:22:54.260 And then directly underneath that, the function is going to be whatever handles that route. 00:22:54.260 --> 00:22:59.100 So when the home route is accessed, that function will run kind of like a callback in JavaScript. 00:22:59.460 --> 00:23:06.120 Yeah, the other thing that's interesting about Flask, I think, is this global request object that's kind of always there, right? 00:23:06.120 --> 00:23:09.180 That was one of the weirder aspects of Flask. 00:23:09.180 --> 00:23:11.800 I'd never encountered that before using Flask. 00:23:11.800 --> 00:23:15.420 Because typically, like with other web frameworks, the request object is populated. 00:23:15.420 --> 00:23:16.060 It's a parameter. 00:23:16.060 --> 00:23:17.700 Just as a local variable. 00:23:17.700 --> 00:23:17.960 Yeah. 00:23:17.960 --> 00:23:20.940 It's a parameter in a function or a method in a class. 00:23:20.940 --> 00:23:24.160 But it's just populated for that one instance. 00:23:24.160 --> 00:23:27.220 And it's only usable by that one function unless you pass it somewhere else. 00:23:27.600 --> 00:23:30.580 With Flask, the request object is a global variable. 00:23:30.580 --> 00:23:32.340 It is the incoming request. 00:23:32.340 --> 00:23:42.280 And it's usable not just by your view function, but any function or anything that you have in that file, that script file. 00:23:42.280 --> 00:23:43.840 You can use it to do whatever you want to. 00:23:43.840 --> 00:23:49.940 So you can set up, you know, background tasks if you want to use that request object without any actual reference to your view. 00:23:49.940 --> 00:23:51.120 Yeah, and that's kind of funky. 00:23:51.120 --> 00:23:53.680 But it also makes it pretty easy. 00:23:53.680 --> 00:23:55.600 I had the guys that did Quart. 00:23:55.800 --> 00:24:01.080 The guy who did Quart on, and Quart is an asyncified version of Flask. 00:24:01.080 --> 00:24:05.760 And this type of stuff was one of the things that made making it async really challenging. 00:24:05.760 --> 00:24:12.060 Because how do you control when the request thing points at the right one? 00:24:12.060 --> 00:24:14.380 And then you release the thread, another one runs. 00:24:14.380 --> 00:24:15.420 It's like, it gets a little tricky. 00:24:15.420 --> 00:24:18.640 Yeah, I have no idea how that would work, honestly. 00:24:19.260 --> 00:24:21.640 It took some crazy monkey patching, as from what I understand. 00:24:21.640 --> 00:24:22.980 Good God. 00:24:22.980 --> 00:24:26.260 I mean, it's certainly possible, and I'm sure there's use cases for it. 00:24:26.260 --> 00:24:29.380 But I can't imagine the mess that must be under the hood when you're trying to do that. 00:24:29.380 --> 00:24:30.420 Yeah, it gets interesting. 00:24:30.420 --> 00:24:30.740 Yeah. 00:24:31.120 --> 00:24:37.820 All right, speaking of interesting, the one that is the most out there of the four that you chose, I think, is Tornado. 00:24:38.760 --> 00:24:43.040 And I'll just read the quick summary for Tornado that they put on their website, like the paragraph. 00:24:43.040 --> 00:24:54.480 So Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed, which is like some interesting early social media, for a non-blocking network I.O., right? 00:24:54.600 --> 00:25:00.300 So it scales to tens of thousands of open connections and makes it ideal for long polling, WebSockets, and so on. 00:25:00.300 --> 00:25:10.920 So if what you're doing is waiting on stuff, I'm calling web services, I'm calling database things, and I want to not block up my web tier when that happens, like Tornado is pretty cool. 00:25:10.920 --> 00:25:14.660 There's other options that are more modern, but this is like a really popular one. 00:25:14.660 --> 00:25:15.260 Yeah, definitely. 00:25:15.260 --> 00:25:24.780 Yeah, Tornado is useful for if you want to have a long-lived connection or if you want to do anything that requires some long-running input-output. 00:25:24.780 --> 00:25:31.480 This particular use case, this to-do list, is not the best place for Tornado to be used. 00:25:31.480 --> 00:25:34.840 It's still like you don't need to do async stuff with Tornado. 00:25:34.840 --> 00:25:37.720 You can use it just like a Flask or like a Django. 00:25:37.720 --> 00:25:39.420 It'll work the exact same way. 00:25:39.420 --> 00:25:40.880 It just handles requests and sends back responses. 00:25:41.620 --> 00:25:50.440 But if you do have a long-running task like a database query that's going to take a while to aggregate some data or maybe you need to send a request to somewhere else, 00:25:50.440 --> 00:25:59.180 you can set up your views as coroutines that'll run in their own time and still free up the web service to handle other requests or do other operations. 00:25:59.180 --> 00:26:08.420 And it's really cool that way, and it's actually fairly simplified, where all you really need to do is know exactly which part of your code you want to, or which will be long-running. 00:26:08.520 --> 00:26:14.620 You set that up as being what's called a future object, something that's going to be running in the future, and set up the method as being a coroutine. 00:26:14.620 --> 00:26:16.440 Tornado will handle all the rest. 00:26:16.440 --> 00:26:17.960 You don't have to worry about the event loop. 00:26:17.960 --> 00:26:22.300 You don't have to worry about any of, well, most of the other asynchronous issues. 00:26:22.300 --> 00:26:23.940 It's just, it's done for you. 00:26:23.940 --> 00:26:24.260 Yeah. 00:26:24.260 --> 00:26:26.620 And so you're using SQLAlchemy here as well. 00:26:26.660 --> 00:26:34.020 And what gets interesting is SQLAlchemy itself is not async-enabled, coroutine-enabled, or things like that, right? 00:26:34.020 --> 00:26:38.920 So you have tornado-SQLAlchemy, which lets you do that, right? 00:26:38.920 --> 00:26:39.480 Mm-hmm. 00:26:39.480 --> 00:26:47.000 And the way that it does it is by setting up a context object where, so in that context, you have access to this session. 00:26:47.140 --> 00:26:53.600 And then whatever you would do with that session gets handed off as a task to your async event loop. 00:26:53.600 --> 00:26:56.140 And so you hand it off to the event loop. 00:26:56.140 --> 00:26:58.440 Your event loop continues to run. 00:26:58.800 --> 00:27:04.420 And you're not necessarily waiting for that process to finish before you handle your next request. 00:27:04.420 --> 00:27:13.180 It's just that when that process does finish, and the event loop is aware of that, then that response to that specific user is sent back as it needs to be sent back. 00:27:13.180 --> 00:27:19.240 The thing that it's not doing for you is, like, if you have some long-running computation, that's not going to be handled by a tornado. 00:27:19.240 --> 00:27:25.200 It's really just for input-output from some external service or from, like, clients. 00:27:25.200 --> 00:27:25.800 Right, exactly. 00:27:25.800 --> 00:27:29.400 You've got to have one of those things to make a future and wait upon it, right? 00:27:29.400 --> 00:27:32.820 And if that's just compute, it's just going to block up the same thread anyway, so. 00:27:32.820 --> 00:27:33.740 That's an interesting thing. 00:27:33.740 --> 00:27:37.480 Like, I was never actually trained in understanding async. 00:27:37.480 --> 00:27:38.740 And so... 00:27:38.740 --> 00:27:40.620 It's pretty mind-bending the more you dig into it. 00:27:40.620 --> 00:27:41.580 Yeah, it really is. 00:27:41.580 --> 00:27:42.020 It really is. 00:27:42.020 --> 00:27:42.900 It was interesting. 00:27:42.900 --> 00:27:49.060 And this goes back to PyCascades, where, like, I had kind of, like, dipped my toes into it with Tornado, but I was like, oh, I don't really know that much. 00:27:49.060 --> 00:27:51.120 I know I can decorate this method with a coroutine. 00:27:51.120 --> 00:27:52.160 It'll make it a coroutine. 00:27:53.280 --> 00:27:58.860 And then I got the privilege of being able to sit next to Guido during the speaker's dinner after the first night. 00:27:58.860 --> 00:28:03.720 And he talked to me for a while about, like, how async works. 00:28:03.720 --> 00:28:05.360 And I still didn't quite fully grasp it. 00:28:05.360 --> 00:28:14.140 But it was really interesting in how Python is still being a single-threaded process, but it's handing off tasks to be working in the background. 00:28:14.520 --> 00:28:19.640 And then I tweeted about, like, okay, I'm really going to be serious about learning about this async stuff. 00:28:19.640 --> 00:28:22.460 And he tweeted back at me, and he was like, hey, you want to check out this book? 00:28:22.460 --> 00:28:25.080 And it's been great thus far. 00:28:25.080 --> 00:28:25.620 I've been reading. 00:28:25.620 --> 00:28:27.040 I've read through it about this. 00:28:27.040 --> 00:28:28.600 This is one chapter in this book about twice now. 00:28:28.600 --> 00:28:31.280 I'd say my understanding is at about 25% level. 00:28:31.280 --> 00:28:32.520 That's awesome. 00:28:32.520 --> 00:28:33.780 What was the book you recommended? 00:28:33.780 --> 00:28:34.960 It was... 00:28:34.960 --> 00:28:35.400 Let's see if I can put... 00:28:35.400 --> 00:28:36.360 I don't have it on this machine. 00:28:36.360 --> 00:28:36.640 Do I? 00:28:36.640 --> 00:28:37.620 Let's see. 00:28:37.620 --> 00:28:39.640 I'm going to look for it. 00:28:39.640 --> 00:28:41.380 And if I find it, I'll send it to you. 00:28:41.380 --> 00:28:43.060 Yeah, we'll put it in the show notes or something like that. 00:28:43.060 --> 00:28:43.400 Yeah, sure. 00:28:43.600 --> 00:28:43.920 Absolutely. 00:28:43.920 --> 00:28:47.640 But it's an open source book about... 00:28:47.640 --> 00:28:48.440 It's very sharp. 00:28:48.440 --> 00:28:50.080 It's about the architecture of software. 00:28:50.080 --> 00:28:54.240 Oh, is it the one where they build all these different things and 500 lines of code or less? 00:28:54.240 --> 00:28:55.420 Yes, that's what it was. 00:28:55.420 --> 00:28:59.160 Is it the article of Jesse Davis and Guido's article, maybe? 00:28:59.160 --> 00:29:00.800 Yes, that is the exact one. 00:29:00.800 --> 00:29:02.140 Yeah, that's a good one. 00:29:02.140 --> 00:29:03.000 That is a really good one. 00:29:03.000 --> 00:29:06.180 A web crawler with asyncio coroutines. 00:29:06.180 --> 00:29:10.600 And it actually builds up what a coroutine is from ground level. 00:29:10.760 --> 00:29:12.760 It starts with your blocking sockets. 00:29:12.760 --> 00:29:15.140 And then it's still sockets, but non-blocking sockets. 00:29:15.140 --> 00:29:19.060 And then it goes to an actual web crawler using coroutines. 00:29:19.060 --> 00:29:20.460 And it's pretty awesome. 00:29:20.460 --> 00:29:21.860 Yeah, that's a really cool one. 00:29:21.860 --> 00:29:23.980 And I love the 500 lines or less aspect of it. 00:29:23.980 --> 00:29:24.800 That's pretty cool. 00:29:25.000 --> 00:29:33.040 Yeah, and for being 500 lines or less for such a complex topic, they do a really good job of explaining what async is and how it's supposed to work in the context of Python. 00:29:33.040 --> 00:29:34.280 Yeah, yeah, that's really cool. 00:29:34.280 --> 00:29:39.100 All right, so we've got these async coroutine view methods. 00:29:39.100 --> 00:29:41.500 Are they methods or are they classes in Tornado? 00:29:41.500 --> 00:29:42.140 I can't remember. 00:29:42.460 --> 00:29:44.040 So the views themselves are classes. 00:29:44.040 --> 00:29:48.320 And you connect the views to routes in Tornado's central application object. 00:29:48.320 --> 00:29:52.480 You can have multiple applications running at the same time, which goes back to that event loop thing. 00:29:52.480 --> 00:29:59.540 You can have in your one Tornado project four or five applications running at the same time, doing and handling different things if you want to. 00:30:00.120 --> 00:30:03.600 But the actual method that gets run depends on what kind of requests you come in. 00:30:03.600 --> 00:30:06.400 So you know that you have several types of HTTP requests. 00:30:06.400 --> 00:30:08.820 You can get, post, put, delete. 00:30:08.820 --> 00:30:09.940 Those are the main ones. 00:30:09.940 --> 00:30:12.580 There's other like hen, option, whatever, but normally you should use those. 00:30:12.580 --> 00:30:14.620 And then there are corresponding methods for those. 00:30:14.620 --> 00:30:22.700 So when an incoming get request comes in, whatever code that I've written for the get method will get run for that request. 00:30:22.700 --> 00:30:26.800 And the response is built from that request, from that method, and sent back to the client. 00:30:26.800 --> 00:30:27.820 Yeah, that sounds really cool. 00:30:27.920 --> 00:30:33.140 So the sort of fundamental building block in Flask is you have a decorated function. 00:30:33.140 --> 00:30:35.560 The fundamental building block here is I have a class. 00:30:35.560 --> 00:30:40.860 One URL points at it, but it can have different methods for the various HTTP verbs. 00:30:40.860 --> 00:30:43.200 So it's a little restful in that sense. 00:30:43.200 --> 00:30:44.700 It's a little restful in that sense. 00:30:44.700 --> 00:30:46.620 It works really well for a restful API. 00:30:46.620 --> 00:30:56.860 And the benefit of having it be a class is that you can set some instance attributes to only run for that one class, for that one type of request. 00:30:57.340 --> 00:31:01.060 You can think of them as, you know, semi-global things that only apply to that class. 00:31:01.060 --> 00:31:08.500 And you can have other methods in that class that work just for that class and whatever you want to do with those methods for those specific kinds of requests. 00:31:08.500 --> 00:31:25.480 For those methods, in this particular case, the to-do list, I add some methods to some base request handler for constructing responses, for setting default headers, for converting incoming data from post requests into Unicode, because they come in as byte code instead. 00:31:25.480 --> 00:31:27.220 Sorry, byte strains instead. 00:31:27.820 --> 00:31:28.560 That's really simple. 00:31:28.560 --> 00:31:29.480 It's just a method of the class. 00:31:29.480 --> 00:31:30.120 Yeah, that's cool. 00:31:30.120 --> 00:31:37.120 I find that that's a really nice design pattern, because there's probably like five or ten things like every web method wants access to. 00:31:37.120 --> 00:31:39.600 And if you put that in a base class and bundle it up, that's sweet. 00:31:39.600 --> 00:31:40.460 And that was very simple to do. 00:31:40.460 --> 00:31:40.940 Yeah, cool. 00:31:41.020 --> 00:31:47.280 And then for the SQLAlchemy, even though it's the Tornado SQLAlchemy, you still basically define it exactly the same, right? 00:31:47.280 --> 00:31:48.600 The declarative base and all that? 00:31:48.600 --> 00:31:52.020 It is almost the exact same thing as Flask. 00:31:52.020 --> 00:31:56.200 In fact, when I first written this project, I wrote it in Pyramid. 00:31:56.200 --> 00:32:06.120 And then when I was going through Tornado, I was like, oh, I can just copy and paste everything I wrote for Pyramid into Tornado and copy and paste everything I wrote for Pyramid into Flask, because it's all SQLAlchemy under the hood. 00:32:06.120 --> 00:32:07.280 And that's one of the things I like. 00:32:07.280 --> 00:32:13.720 If you have an ORM or like I use Mongo a lot, so an ODM that you really like, they kind of are portable, right? 00:32:13.720 --> 00:32:14.840 You learn the data part. 00:32:14.840 --> 00:32:17.960 It's almost like the 12-factor app idea that you were talking about. 00:32:17.960 --> 00:32:23.900 Like, you understand this part of your architecture independent of the framework, right? 00:32:23.900 --> 00:32:25.460 Like the pieces, you put them together. 00:32:25.460 --> 00:32:26.940 They're not like locked. 00:32:26.940 --> 00:32:31.700 And they're not like the one in the same, unlike, say, Django, which we'll get to in a second, right? 00:32:31.700 --> 00:32:32.580 Right, right. 00:32:32.580 --> 00:32:36.280 Yeah, that's the benefit of using things like Pyramid or Flask or Tornado. 00:32:36.280 --> 00:32:41.460 And they're similar in the way that there is some basic framework, but all the rest is just building. 00:32:41.460 --> 00:32:42.240 It's just Legos. 00:32:42.240 --> 00:32:42.660 Yeah. 00:32:42.660 --> 00:32:43.680 It's all the same stuff. 00:32:43.680 --> 00:32:43.960 Nice. 00:32:43.960 --> 00:32:46.320 So let's move on to Pyramid. 00:32:46.600 --> 00:32:50.620 I think Pyramid lives somewhere in between Flask and Django, maybe a little closer to the Flask world. 00:32:50.620 --> 00:32:52.140 But I really like their philosophy. 00:32:52.140 --> 00:32:55.500 They're the start small, finish big, stay finished framework. 00:32:55.500 --> 00:33:02.440 And they say their philosophy is it should be very quick and easy for you to learn to start with a web framework. 00:33:02.440 --> 00:33:06.840 But the stuff that you need as it grows more complex is just there. 00:33:06.840 --> 00:33:09.240 And so that's kind of a nice philosophy, I think. 00:33:09.240 --> 00:33:26.260 One of the things that was nice about Pyramid is that I use the cookie cutter template for building a Pyramid application where cookie cutter is a separate Python package that you download and then you point out a repository to copy over some files for you to build your application. 00:33:26.260 --> 00:33:29.700 There are cookie cutter templates for Flask, Tornado, and even Django. 00:33:29.940 --> 00:33:32.460 I didn't know how to use those as well as I knew for Pyramid. 00:33:32.460 --> 00:33:33.520 So I just used the one for Pyramid. 00:33:33.520 --> 00:33:33.700 Yeah. 00:33:33.700 --> 00:33:42.440 It's the official way to get started with Pyramid where the others you theoretically could use cookie cutter, but it's like there's some other sort of official starting point. 00:33:42.440 --> 00:33:42.980 Yeah. 00:33:42.980 --> 00:33:44.080 Actually. 00:33:44.080 --> 00:33:51.140 So it's interesting that you say that because when I first started teaching Pyramid almost two years ago, cookie cutter was not the way to do it. 00:33:51.140 --> 00:33:51.400 It was. 00:33:51.400 --> 00:33:53.000 I was using Pyramid 1.8. 00:33:53.000 --> 00:33:53.140 Yeah. 00:33:53.140 --> 00:33:53.560 It was pcreate. 00:33:53.560 --> 00:33:56.000 Like when you install Pyramid, it installs for you a command. 00:33:56.000 --> 00:33:58.280 It's actually still there in the current version of Pyramid. 00:33:58.280 --> 00:33:58.500 Yeah. 00:33:58.500 --> 00:33:59.760 If you still want to use it. 00:33:59.760 --> 00:34:01.080 I think it delegates to cookie. 00:34:01.080 --> 00:34:03.340 It just is a wrapper around the cookie cutter now, I think. 00:34:03.340 --> 00:34:03.740 Oh, is it? 00:34:03.740 --> 00:34:04.560 I haven't actually looked at it. 00:34:04.560 --> 00:34:05.120 I think so. 00:34:05.120 --> 00:34:06.040 I'm not entirely sure either. 00:34:06.040 --> 00:34:07.600 That makes sense. 00:34:07.600 --> 00:34:08.560 Okay, cool. 00:34:08.560 --> 00:34:14.040 But yeah, like the pcreate command would say, okay, you want to create a pyramid application. 00:34:14.040 --> 00:34:15.760 You want to do certain things. 00:34:15.760 --> 00:34:17.600 There are various templates you can use. 00:34:17.600 --> 00:34:21.800 The basic pyramid template says, okay, you have some main function, which is your main configuration. 00:34:22.420 --> 00:34:23.700 Maybe you want to hook up some views. 00:34:23.700 --> 00:34:24.920 Maybe you want to hook up some routes. 00:34:24.920 --> 00:34:25.900 Whatever. 00:34:25.900 --> 00:34:26.660 We got you. 00:34:26.660 --> 00:34:31.800 With the SQLAlchemy cookie cutter template, it says, oh, you want a database? 00:34:31.800 --> 00:34:36.120 Well, instead of having you write your own, because we know you don't know what you're doing, 00:34:36.120 --> 00:34:40.580 we're going to give you a script for initializing your database. 00:34:40.580 --> 00:34:41.980 Here it is. 00:34:41.980 --> 00:34:43.040 It's called initializeDB. 00:34:43.040 --> 00:34:45.660 It does exactly what you think it's supposed to do. 00:34:45.660 --> 00:34:48.580 Without you worrying about the actual implementation details. 00:34:48.580 --> 00:34:52.260 One of the things that I wish they had was an Alembic template. 00:34:52.400 --> 00:34:53.180 Maybe they have one now. 00:34:53.180 --> 00:34:54.400 I haven't checked in a few months. 00:34:54.400 --> 00:34:59.560 But that'd be cool, too, because one of the things that's hard to teach what I'm doing 00:34:59.560 --> 00:35:04.160 pyramid is, you know, you can actually, if you know how to use Alembic, you can set up 00:35:04.160 --> 00:35:08.120 these things called migrations, which are snapshots of your model as you change it over time. 00:35:08.120 --> 00:35:13.280 And that's a lot easier and better for production than just destroying it all and rebuilding it 00:35:13.280 --> 00:35:14.800 from scratch every single time you want to make a change. 00:35:14.800 --> 00:35:15.060 Yeah. 00:35:15.060 --> 00:35:16.940 The migrations are where that get tricky. 00:35:16.940 --> 00:35:19.860 And so the fact that if that were built in, that would be sweet, right? 00:35:20.260 --> 00:35:20.500 Yeah. 00:35:20.500 --> 00:35:22.800 And I'm sure that at this point in time, someone's done it. 00:35:22.800 --> 00:35:24.020 I just haven't looked. 00:35:24.020 --> 00:35:24.400 Maybe. 00:35:24.400 --> 00:35:27.820 I mean, one of the things that you could do for your courses is you could take one of 00:35:27.820 --> 00:35:31.880 these cookie cutter templates and make one that's like a little more focused on what 00:35:31.880 --> 00:35:34.380 you guys are trying to end up with the end goal. 00:35:34.880 --> 00:35:39.440 Like I have my Python for entrepreneurs course, which has just a crazy amount of different 00:35:39.440 --> 00:35:43.660 things brought into it, like bootstrap set up in a certain way and all sorts of templates. 00:35:43.660 --> 00:35:48.560 And so I actually created a cookie cutter template that is the, like, if you wanted to take what 00:35:48.560 --> 00:35:52.500 we built through the 20 hour course and start a new project from it, you would just run that 00:35:52.500 --> 00:35:56.380 new cookie cutter template and like you would start basically the end of the course. 00:35:56.380 --> 00:35:56.760 Yeah. 00:35:56.760 --> 00:35:57.760 That's awesome. 00:35:57.760 --> 00:35:58.000 Yeah. 00:35:58.000 --> 00:35:58.500 It's really fun. 00:35:58.500 --> 00:35:59.460 So that's a great idea. 00:35:59.460 --> 00:35:59.540 Yeah. 00:35:59.540 --> 00:36:01.460 It's really like you teaching the same thing. 00:36:01.460 --> 00:36:04.720 It's similar things you could like, you could help yourself by like, 00:36:04.720 --> 00:36:06.300 tweaking one of these and forking it. 00:36:06.300 --> 00:36:06.540 Yeah. 00:36:06.540 --> 00:36:09.600 That might be a thing that I'd do in the future. 00:36:09.600 --> 00:36:12.420 I have been trying, like, as I've modified the course. 00:36:12.420 --> 00:36:15.260 So it's worth noting that I didn't, I wasn't the one who created the course. 00:36:15.260 --> 00:36:19.420 The course was created by this awesome guy, Chris Ewing, great developer, great friend, 00:36:19.420 --> 00:36:20.900 extremely smart. 00:36:20.900 --> 00:36:25.100 And he created the course with Pyramid in there. 00:36:25.100 --> 00:36:29.540 He had done Flask before, but he decided to go with Pyramid instead as just kind of a more 00:36:29.540 --> 00:36:31.520 basic framework that could do a lot. 00:36:32.340 --> 00:36:39.520 And his idea was to not have the things that they learned be too heavily tied to just the 00:36:39.520 --> 00:36:40.320 course that we teach. 00:36:40.320 --> 00:36:44.700 Because when they get out in the real world, they need to be able to understand what's happening 00:36:44.700 --> 00:36:49.740 and not just fall back only onto what we taught, but be able to build up from scratch whatever 00:36:49.740 --> 00:36:52.040 they need to build up for whatever job they have. 00:36:52.260 --> 00:36:57.220 The benefit of using someone else's cookie cutter template is that someone else has done 00:36:57.220 --> 00:36:57.360 it. 00:36:57.360 --> 00:37:03.280 It's more likely to be used widely if someone's building a project and they can kind of just 00:37:03.280 --> 00:37:05.620 get direct, they can feed directly into that pipeline. 00:37:05.620 --> 00:37:09.760 But I think now that you mentioned it, I'm going to, I'm going to see if there's an Alumbic 00:37:09.760 --> 00:37:11.480 template out there for Pyramid. 00:37:11.480 --> 00:37:13.480 And if there isn't one, I might actually try to write one. 00:37:13.680 --> 00:37:14.460 Yeah, it'd be really cool. 00:37:14.460 --> 00:37:15.220 It would be useful. 00:37:15.220 --> 00:37:15.440 Yeah. 00:37:15.440 --> 00:37:19.300 I don't mean to derail you, but I do find this, these cookie cutters are really interesting 00:37:19.300 --> 00:37:19.940 to roll with. 00:37:19.940 --> 00:37:21.440 So this is how you get started in Pyramid. 00:37:21.440 --> 00:37:27.200 And let's say the terms of views, the default fundamental building block is very much like 00:37:27.200 --> 00:37:27.980 Flask, right? 00:37:27.980 --> 00:37:28.540 Oh yeah. 00:37:28.540 --> 00:37:30.640 It's just a function with a decorator. 00:37:30.900 --> 00:37:36.520 The difference between Pyramid and Flask is that your decorator, so your routes in Pyramid 00:37:36.520 --> 00:37:38.660 are separate from your views. 00:37:38.660 --> 00:37:42.800 They are just a listing of routes in, you can put them in a separate file, you can put them 00:37:42.800 --> 00:37:45.880 in your main configuration directly, and they have a name. 00:37:45.880 --> 00:37:52.020 So like, again, the home route, it would be called home, and then the actual pattern that's 00:37:52.020 --> 00:37:53.960 supposed to be matched to go to that route. 00:37:53.960 --> 00:37:58.860 And then your view has this view config decorator where you say, okay, here's the name of the 00:37:58.860 --> 00:38:00.120 route that I want you to connect to. 00:38:00.900 --> 00:38:04.740 Here's also the way in which I want you to render the response of this view. 00:38:04.740 --> 00:38:06.480 You can have, there's several options. 00:38:06.480 --> 00:38:11.080 One of those is JSON, so I can take my response, like if I pass a dictionary to my return value, 00:38:11.080 --> 00:38:14.780 then my response will just be a dictionary, and that's JSON serializable. 00:38:14.780 --> 00:38:19.180 Or I can make it, I can use a template like a Jinja template or a Chameleon template or any 00:38:19.180 --> 00:38:24.160 other template system that I want to, and just pass my response to that template, and Pyramid 00:38:24.160 --> 00:38:25.960 will build a response for me and send it back to the client. 00:38:25.960 --> 00:38:31.000 You can also go with the Tornado style and create these like handler classes that get 00:38:31.000 --> 00:38:31.600 one URL. 00:38:31.600 --> 00:38:34.420 You can, or they're called view classes, I think. 00:38:34.420 --> 00:38:35.580 You create handler classes. 00:38:35.580 --> 00:38:36.980 There's like a whole bunch of different ways. 00:38:36.980 --> 00:38:39.100 And I think that's one of the challenges of Pyramid. 00:38:39.100 --> 00:38:40.500 It's the framework I like most. 00:38:40.500 --> 00:38:42.020 My web apps are built in it. 00:38:42.020 --> 00:38:45.920 But I do feel like there's all these different ways to do the same thing. 00:38:45.920 --> 00:38:48.800 So I'm never like, am I doing it the best way? 00:38:48.800 --> 00:38:50.520 Or I'm just doing it the way that I know? 00:38:50.520 --> 00:38:51.000 You know what I mean? 00:38:51.060 --> 00:38:52.400 There's always a better way. 00:38:52.400 --> 00:38:57.780 It's more a matter of, my students often come to me with the question of like, is this best 00:38:57.780 --> 00:38:58.180 practice? 00:38:58.180 --> 00:39:00.100 Is what I'm doing best practice? 00:39:00.100 --> 00:39:05.880 And my response is always, well, best practice is oftentimes just defined by the person who's 00:39:05.880 --> 00:39:06.400 paying you. 00:39:06.400 --> 00:39:07.800 What do they want? 00:39:07.800 --> 00:39:09.140 It's a trade-off too, right? 00:39:09.140 --> 00:39:15.600 If I'm building Google, I'm making different trade-offs than if I'm building a small hotel's 00:39:15.600 --> 00:39:16.000 website. 00:39:16.000 --> 00:39:20.080 A best practice for Google is wasting money for the hotel and vice versa. 00:39:20.280 --> 00:39:23.340 The point there is that it always comes down to your use case, right? 00:39:23.340 --> 00:39:30.540 If your use case would be better served by using class-based views and having the mix-in 00:39:30.540 --> 00:39:34.260 pattern that Django has, then that's your best practice. 00:39:34.260 --> 00:39:39.520 But if your use case is better served by a function, then use the function and be okay 00:39:39.520 --> 00:39:39.880 with it. 00:39:39.880 --> 00:39:41.080 As long as the thing works. 00:39:41.080 --> 00:39:44.680 That's what matters more, is that the thing that you're building works. 00:39:44.680 --> 00:39:48.140 And then you can optimize as you need to for your specific use case. 00:39:48.140 --> 00:39:49.000 Yeah, for sure. 00:39:49.500 --> 00:39:50.660 All right, so you brought up Django. 00:39:50.660 --> 00:39:52.220 Let's move on to Django. 00:39:52.220 --> 00:39:58.620 So the summary there is it's a high-level Python web framework, and it encourages rapid development 00:39:58.620 --> 00:39:59.960 and pragmatic design. 00:39:59.960 --> 00:40:06.400 So it comes with lots of pre-built stuff, and the building blocks are kind of large. 00:40:06.400 --> 00:40:09.680 They're more like Duplo rather than Lego building blocks. 00:40:09.680 --> 00:40:11.040 I like to think of them as, right? 00:40:11.200 --> 00:40:11.560 Exactly. 00:40:11.560 --> 00:40:18.320 I would even say they're more like, if you know Power Rangers, where the robots come together 00:40:18.320 --> 00:40:19.360 to make one larger robot. 00:40:19.360 --> 00:40:26.300 There's still machinery in the individual robots, but their job is not to be inspected individually. 00:40:26.300 --> 00:40:29.140 Their job is to make one larger conglomerate. 00:40:30.000 --> 00:40:30.720 Yeah, yeah. 00:40:30.720 --> 00:40:35.380 One of the things that Django doesn't say in their description is that it is extremely opinionated 00:40:35.380 --> 00:40:37.100 about the way that things should be done. 00:40:37.100 --> 00:40:40.280 And so, yes, there are function-based views in Django. 00:40:40.280 --> 00:40:41.660 There's also class-based views in Django. 00:40:42.660 --> 00:40:46.700 There's the ability to talk to a database in Django, but the database you're talking to should 00:40:46.700 --> 00:40:47.980 probably be a SQL database. 00:40:47.980 --> 00:40:52.600 And the way that you build models in Django, at least through the tutorials and the documentation, 00:40:52.600 --> 00:40:55.000 assumes you want rows and columns. 00:40:55.000 --> 00:41:00.420 There are ways to incorporate a thing like Mongo into a Django application, but that takes a lot 00:41:00.420 --> 00:41:02.680 of extra legwork that you may not want to do. 00:41:02.680 --> 00:41:03.700 You're kind of fighting. 00:41:03.700 --> 00:41:07.940 You're going against the grain a lot of times, even though it's possible, I feel like. 00:41:07.940 --> 00:41:11.860 Django, it encourages rapid development as long as you want to do things the Django way. 00:41:11.860 --> 00:41:17.100 Which is oftentimes a good way to do things, but if you want to go outside that norm, 00:41:17.100 --> 00:41:19.520 you're going to have to pull apart some code to do that. 00:41:19.520 --> 00:41:20.860 I think Django is good. 00:41:20.860 --> 00:41:22.680 A lot of people use it. 00:41:22.680 --> 00:41:28.440 It certainly seems to be super effective for people who want to kind of get started quick 00:41:28.440 --> 00:41:29.080 and stuff. 00:41:29.080 --> 00:41:34.260 I personally lean more towards the micro framework because I want to pick that little data access 00:41:34.260 --> 00:41:38.360 layer and that little bit over here and just put it together, you know, but I think 00:41:38.360 --> 00:41:39.900 that's just my personality. 00:41:39.900 --> 00:41:44.900 Yeah, but if you want to start quick and build big to start, then Django is pretty much the 00:41:44.900 --> 00:41:45.360 way to go. 00:41:45.360 --> 00:41:45.640 Yeah. 00:41:46.040 --> 00:41:50.900 So in here, you design the models differently in a similar but different way because you 00:41:50.900 --> 00:41:54.380 use the Django ORM, not the SQLAlchemy style, right? 00:41:54.380 --> 00:41:56.740 Where the SQLAlchemy style has you inherit from this thing called the base. 00:41:56.740 --> 00:41:59.580 It's actually fairly similar with Django. 00:41:59.580 --> 00:42:04.040 When you're building a model, you inherit from Django's own base model, which handles the 00:42:04.040 --> 00:42:05.860 database interaction layer for you. 00:42:06.240 --> 00:42:10.600 And then instead of having columns or column objects, you have field objects, but it's still 00:42:10.600 --> 00:42:11.760 the same thing underneath. 00:42:11.760 --> 00:42:17.140 There are one of the benefits of using Django's fields is that there are some specific keyword 00:42:17.140 --> 00:42:19.100 arguments you can set for specific fields. 00:42:19.100 --> 00:42:23.400 One of my favorites is the auto now add that comes with the daytime field, which says, you 00:42:23.400 --> 00:42:27.240 know, when you create a new instance of this object, then I'm going to just set the date 00:42:27.240 --> 00:42:28.740 time on like for now. 00:42:28.740 --> 00:42:31.360 Whatever now is, that's the date time on this field. 00:42:31.680 --> 00:42:31.800 Yeah. 00:42:31.800 --> 00:42:37.280 And you could do that with SQLAlchemy, but it's easy to make mistakes on it, right? 00:42:37.280 --> 00:42:41.440 Like you could say, instead of saying the now function, you say now with parentheses and you 00:42:41.440 --> 00:42:46.680 get like every model is marked at the time that when the app started, you know, funky stuff 00:42:46.680 --> 00:42:47.060 like that. 00:42:47.060 --> 00:42:47.520 Exactly. 00:42:47.520 --> 00:42:53.840 One thing that's always kind of put me off on Django is the way you define URLs is like 00:42:53.840 --> 00:42:54.900 regular expressions. 00:42:54.900 --> 00:42:57.020 That's always sort of driven me crazy. 00:42:57.020 --> 00:42:57.600 Yeah. 00:42:57.600 --> 00:43:01.240 I mean, to a degree you do that in pyramid as well. 00:43:01.340 --> 00:43:02.820 If you want to have any variable routes. 00:43:02.820 --> 00:43:03.160 Right. 00:43:03.160 --> 00:43:05.440 If you want to, you say this can only be an integer. 00:43:05.440 --> 00:43:05.980 Right. 00:43:05.980 --> 00:43:06.500 Here. 00:43:06.500 --> 00:43:06.880 Right. 00:43:06.880 --> 00:43:10.040 You say the variable name, but if you want to constrain it, then it's a regular expression. 00:43:10.040 --> 00:43:11.460 Up through Django 111. 00:43:11.460 --> 00:43:14.600 I'm not sure if that's still the case in Django 2, actually, because they have the pattern 00:43:14.600 --> 00:43:14.920 now. 00:43:14.920 --> 00:43:15.720 They changed it. 00:43:15.720 --> 00:43:17.880 They changed the new pattern to make it a lot nicer. 00:43:17.880 --> 00:43:22.000 Up through Django 111, which is what I built the app in, is you have to have a specific 00:43:22.000 --> 00:43:24.000 regular expression to be matched for your pattern. 00:43:24.240 --> 00:43:29.420 And the way that you, like the whole pattern itself is a regular expression, not just the 00:43:29.420 --> 00:43:30.060 variable part. 00:43:30.060 --> 00:43:35.580 Whereas with Django 2 now, it's a little bit more natural, a little less nuanced for just 00:43:35.580 --> 00:43:36.140 regular expressions. 00:43:36.140 --> 00:43:40.460 You can still do the old way if you want to, but they're encouraging you to use the new pattern 00:43:40.460 --> 00:43:43.840 that isn't a regex unless you absolutely need it. 00:43:43.840 --> 00:43:44.140 Yeah. 00:43:44.140 --> 00:43:50.160 So instead of having like a regular expression for the integer, you know, you just say angle 00:43:50.160 --> 00:43:53.300 bracket int colon, you know, oh, so nice. 00:43:53.300 --> 00:43:54.200 Right. 00:43:54.200 --> 00:43:59.060 But if you want an integer that's only, you know, that must be four numbers long, then you 00:43:59.060 --> 00:44:01.480 want to get more and get more into doing regular expressions. 00:44:01.480 --> 00:44:02.380 Yeah, that's cool. 00:44:02.380 --> 00:44:03.040 All right. 00:44:03.040 --> 00:44:05.200 So you went through this whole experience. 00:44:05.200 --> 00:44:07.000 You went through these four frameworks. 00:44:07.000 --> 00:44:10.040 And to be honest, you just scratched the surface. 00:44:10.040 --> 00:44:15.940 There's a bunch more web frameworks like there's, there's bottle and there's webbed pie and there's 00:44:15.940 --> 00:44:16.780 There's cherry pie. 00:44:16.780 --> 00:44:18.380 There's sanding and cherry pie. 00:44:18.380 --> 00:44:21.180 There's hug, which is apparently a web framework. 00:44:21.180 --> 00:44:22.720 There's, yeah. 00:44:22.720 --> 00:44:25.640 Which is based on Falcon, which is another web framework. 00:44:25.640 --> 00:44:26.320 It's like, oh my gosh. 00:44:26.320 --> 00:44:34.160 So just to like, on one hand, this is just a sampling, but it is a sampling of the major 00:44:34.160 --> 00:44:36.180 elements of the Python web framework. 00:44:36.180 --> 00:44:37.800 So what are your takeaways here? 00:44:37.800 --> 00:44:42.420 My takeaways here for these four specifically, because I just didn't have a time to dig into 00:44:42.420 --> 00:44:42.980 any other ones. 00:44:42.980 --> 00:44:43.740 Well, and it's a talk. 00:44:43.740 --> 00:44:48.040 How many could, how many more could you have actually presented in like 35 minutes, right? 00:44:48.040 --> 00:44:48.540 Right. 00:44:48.540 --> 00:44:51.600 I mean, when I gave my talk, it was at 25 minutes, right? 00:44:51.600 --> 00:44:55.940 And even with just these four and with just a little bit of detail that I gave for each 00:44:55.940 --> 00:44:59.040 one, I still ran over time and I had to get cut off toward the end. 00:44:59.040 --> 00:45:01.960 They're shaking that red thing at you like, oh, you're over time. 00:45:01.960 --> 00:45:03.460 Yeah, exactly. 00:45:04.040 --> 00:45:06.140 But my impressions were as follows. 00:45:06.140 --> 00:45:12.740 For Flask, like Flask is good for small tasks or tasks that don't require a database. 00:45:12.740 --> 00:45:15.980 You can still do database stuff with Flask, but it becomes harder. 00:45:15.980 --> 00:45:21.980 So if you're going to start small and stay small and be simple, Flask is the way to go. 00:45:21.980 --> 00:45:23.820 It's really quick to get up and running. 00:45:23.820 --> 00:45:25.480 It's really simple to put together. 00:45:26.140 --> 00:45:30.820 And you can think more about the actual implementation of some of the logic you want to do. 00:45:30.820 --> 00:45:36.180 Pyramid is great if, as the slogan says, if you want to start small, but you anticipate 00:45:36.180 --> 00:45:38.400 getting larger, Pyramid is great for that. 00:45:38.400 --> 00:45:43.260 If you anticipate getting larger and you still want to know what's going on, you want to have 00:45:43.260 --> 00:45:47.680 a hand, you still want to have that do-it-yourself feel, Pyramid will give that to you. 00:45:48.140 --> 00:45:52.820 But it also can hand you some of the pieces to work with so you don't have to do too much 00:45:52.820 --> 00:45:53.600 thinking for yourself. 00:45:53.600 --> 00:45:58.240 Tornado is kind of like an in-between between Flask and Django. 00:45:58.240 --> 00:46:00.880 It can do Flask stuff if you want to do Flask sort of stuff. 00:46:00.880 --> 00:46:03.080 It can do Django sort of stuff if you want to do Django sort of stuff. 00:46:03.080 --> 00:46:08.320 But it's specifically good for any sort of asynchronous work you want to do or if you want to build a 00:46:08.320 --> 00:46:09.860 chat room, that's good for Tornado. 00:46:09.860 --> 00:46:15.080 If you want to have access to more of the bare networking layer of a web framework, Tornado 00:46:15.080 --> 00:46:15.900 is good for that as well. 00:46:16.760 --> 00:46:21.400 Django is if you want to build big and stay big, if you anticipate a lot of complexity 00:46:21.400 --> 00:46:24.680 and you don't want to think too much about the details, you want to think more about how 00:46:24.680 --> 00:46:27.120 it's supposed to all fit together, Django is good for that. 00:46:27.120 --> 00:46:27.540 All right. 00:46:27.540 --> 00:46:28.780 That sounds pretty good. 00:46:28.780 --> 00:46:33.740 What other frameworks were you thinking about or have you thought about that maybe? 00:46:33.740 --> 00:46:37.520 We sort of touched on them a little bit, but what else did you consider for this list? 00:46:37.520 --> 00:46:38.900 I was thinking, so it's interesting. 00:46:38.900 --> 00:46:43.420 One of the things that I only noticed after I started teaching about web dev is that we use 00:46:43.420 --> 00:46:50.280 a Jupyter Notebook, which is a popular data science tool for displaying your analysis, 00:46:50.280 --> 00:46:51.140 displaying your code. 00:46:51.340 --> 00:46:54.140 When you install Jupyter Notebook, let me just check if I could be installing it right 00:46:54.140 --> 00:46:54.400 now. 00:46:54.400 --> 00:46:58.260 When you install Jupyter Notebook, one of the dependencies is a web framework. 00:46:58.260 --> 00:47:00.360 And the web framework is Tornado. 00:47:00.360 --> 00:47:04.320 I think in the past it might have been Twisted, which is another asynchronous web framework. 00:47:04.320 --> 00:47:05.600 I didn't get a chance to look into it. 00:47:05.600 --> 00:47:09.160 From what I understand, it's a little twisted for writing. 00:47:09.160 --> 00:47:12.200 But yeah, that's another web framework that I kind of wanted to get into. 00:47:12.200 --> 00:47:15.040 I had seen Web2Py, but never actually used it. 00:47:15.420 --> 00:47:20.480 My friend Chris Ewing, he's a big proponent of Plone, which is an older web framework where 00:47:20.480 --> 00:47:22.780 Pyramid learned a lot from what Plone used to do. 00:47:22.780 --> 00:47:24.140 It's still around. 00:47:24.140 --> 00:47:27.300 Yeah, it's almost like the next generation of Plone, almost. 00:47:27.300 --> 00:47:29.640 The same people seem to work on it and stuff. 00:47:29.640 --> 00:47:29.860 Yeah. 00:47:29.860 --> 00:47:32.080 It's got some same idioms. 00:47:32.080 --> 00:47:34.060 When I started doing web dev, I started with WordPress. 00:47:34.060 --> 00:47:36.900 And this is a long way from WordPress. 00:47:36.900 --> 00:47:39.620 And I'm glad I didn't have to go through WordPress again. 00:47:40.900 --> 00:47:41.820 Yeah, that's cool. 00:47:41.820 --> 00:47:43.840 Those are all interesting ideas. 00:47:43.840 --> 00:47:48.640 I guess the other ones that kind of capture my imagination now are the async await enabled 00:47:48.640 --> 00:47:54.640 Python 3 ones, like API star, Sanic, Jepronto, Cort. 00:47:54.640 --> 00:47:58.100 They're sort of the Python 3 only ones that are pretty interesting. 00:47:58.100 --> 00:48:02.100 I think I might look into those then because I've kind of really had the fire lit under me 00:48:02.100 --> 00:48:03.200 for async. 00:48:03.200 --> 00:48:06.020 I feel like it doesn't need to be this esoteric thing. 00:48:06.020 --> 00:48:08.620 You know, it's a pattern in Python. 00:48:08.620 --> 00:48:10.520 It should be learnable. 00:48:10.800 --> 00:48:11.920 Yeah, it definitely should be learnable. 00:48:11.920 --> 00:48:16.600 I think, well, you know, you and I are teachers on one aspect of what we do. 00:48:16.600 --> 00:48:18.660 So we can work on that stuff, right? 00:48:18.660 --> 00:48:19.600 We can build it out for people. 00:48:19.600 --> 00:48:20.220 Yeah. 00:48:20.220 --> 00:48:21.120 Awesome. 00:48:21.120 --> 00:48:24.620 So I want to throw an idea out there that I just had while you're doing this that would 00:48:24.620 --> 00:48:26.300 be amazing that you could build for the community. 00:48:26.300 --> 00:48:31.340 You may be busy and not interested, but it would be amazing if there was like a website 00:48:31.340 --> 00:48:34.520 whose job was to have these comparisons. 00:48:35.500 --> 00:48:40.260 And somehow if it was like open to PRs, like somebody's like, oh, I want to submit an API 00:48:40.260 --> 00:48:43.020 star version of the same app to you. 00:48:43.020 --> 00:48:45.340 And that would be a killer community resource. 00:48:45.340 --> 00:48:49.420 If it like it was available for the community to write this app and sort of write an article 00:48:49.420 --> 00:48:51.380 for every framework that existed. 00:48:51.380 --> 00:48:55.340 The GitHub organization that holds all four of the web frameworks is there. 00:48:55.340 --> 00:48:59.200 You know, I'm perfectly happy to have PRs for that. 00:48:59.200 --> 00:49:01.140 Yeah, that's actually a pretty good starting point, isn't it? 00:49:01.140 --> 00:49:04.600 So we'll be sure to link to your repo for this in the show notes. 00:49:04.600 --> 00:49:07.060 Are you open for people to do PRs for you? 00:49:07.060 --> 00:49:07.800 To do another one? 00:49:07.800 --> 00:49:08.140 Sure. 00:49:08.140 --> 00:49:09.140 Oh, yeah. 00:49:09.140 --> 00:49:09.900 All right. 00:49:11.120 --> 00:49:12.800 So we talked about the web frameworks. 00:49:12.800 --> 00:49:14.840 We talked about your boot camp. 00:49:14.840 --> 00:49:19.100 What else have you got going on that you want to chat about that you'd like to let people 00:49:19.100 --> 00:49:19.400 know about? 00:49:19.400 --> 00:49:20.020 Yeah, absolutely. 00:49:20.020 --> 00:49:23.900 If you're in the Seattle area, the meetup group Puppy, Puget Sound Programming Python 00:49:23.900 --> 00:49:24.960 is really awesome. 00:49:24.960 --> 00:49:28.620 I've been lucky enough to be involved with them for the last year and a half or so. 00:49:28.620 --> 00:49:32.280 And they're really open to new people, to new developers. 00:49:32.280 --> 00:49:35.440 In the last year or so, we have a Slack channel. 00:49:35.800 --> 00:49:40.180 We've started the Q&A channel in the Slack team for people to just ask questions. 00:49:40.180 --> 00:49:42.300 We kind of have our own little Stack Overflow going in there. 00:49:42.300 --> 00:49:44.160 You know, and also just random stuff. 00:49:44.160 --> 00:49:49.180 If you have a pretty much like whatever interest you have, the organizers, Don and Alan, two of 00:49:49.180 --> 00:49:54.000 the people who helped put together PyCascades, they are always open to new ideas, to fresh 00:49:54.000 --> 00:49:55.920 ideas, to people who want to get more involved. 00:49:55.920 --> 00:49:58.000 So that's been cool to be a part of that. 00:49:58.000 --> 00:49:59.140 I've been really lucky there. 00:49:59.140 --> 00:50:00.120 Yeah, that's really great. 00:50:00.120 --> 00:50:01.820 And Puppy seems like a good organization. 00:50:02.000 --> 00:50:06.920 And what was surprising to me is how many people from Seattle and Portland we met in 00:50:06.920 --> 00:50:07.280 Vancouver. 00:50:07.280 --> 00:50:07.780 Yeah. 00:50:07.780 --> 00:50:08.320 Right? 00:50:08.320 --> 00:50:10.300 We left the country to meet people just down the street. 00:50:10.300 --> 00:50:11.740 It's time and opportunity, right? 00:50:11.740 --> 00:50:13.420 Like the conferences bring people together. 00:50:13.420 --> 00:50:16.820 But, you know, when you're at home, you have your work schedule, you have your home schedule. 00:50:16.820 --> 00:50:17.760 Like I have a kid. 00:50:17.760 --> 00:50:18.920 I can't even go out that much anymore. 00:50:18.920 --> 00:50:19.520 I know. 00:50:19.520 --> 00:50:20.180 I have three kids. 00:50:20.180 --> 00:50:21.320 It's like, go out at night? 00:50:21.320 --> 00:50:21.940 What are you talking about? 00:50:21.940 --> 00:50:25.780 Like it's super rare that I can go just hang out at like some tech evening event, right? 00:50:25.780 --> 00:50:26.160 Exactly. 00:50:26.160 --> 00:50:27.280 My wife's teaching or something. 00:50:27.280 --> 00:50:27.980 I got to be home. 00:50:27.980 --> 00:50:28.220 Right. 00:50:28.220 --> 00:50:31.700 Like if I'm going to go to Puppy, I need to know like two months in advance. 00:50:31.700 --> 00:50:35.440 You know, so I can, I can, I can warn my, my, my, my fiance. 00:50:35.440 --> 00:50:38.540 I can warn her again, two weeks later and warn her again, two weeks later after that. 00:50:38.540 --> 00:50:40.240 That, you know, I'm going to be going to this thing. 00:50:40.240 --> 00:50:42.300 We have to get a sitter or like you have to stay home. 00:50:42.300 --> 00:50:43.060 You know what? 00:50:43.060 --> 00:50:43.860 Something's got to happen. 00:50:43.860 --> 00:50:47.360 So we can, there's a lot of, there's a lot of logistical stuff going on in there. 00:50:47.360 --> 00:50:47.640 Right. 00:50:47.640 --> 00:50:50.840 But you go to a conference, you kind of, you've already stepped away from that. 00:50:50.840 --> 00:50:52.160 You've created that space. 00:50:52.160 --> 00:50:54.080 And so it's, it's easy to meet people, right? 00:50:54.080 --> 00:50:55.860 I'm here for this one specific reason. 00:50:55.860 --> 00:50:57.680 Just learn about Python and meet people. 00:50:57.680 --> 00:50:58.700 So that's, that was cool. 00:50:59.260 --> 00:51:02.100 And actually through Puppy, one of the things that I'm trying to do in the, in the coming 00:51:02.100 --> 00:51:03.940 year is to be more of a mentor. 00:51:03.940 --> 00:51:07.680 I've been, I've been the beneficiary of some really awesome people who have been mentors 00:51:07.680 --> 00:51:11.280 in the short term or the long term to give me advice every once in a while, give me some 00:51:11.280 --> 00:51:13.240 advice or, or help me deliver you through a process. 00:51:13.240 --> 00:51:15.500 And I kind of want to give that back to the community. 00:51:15.500 --> 00:51:20.180 And so as a teacher for the last two years, I've been able to graduate about a hundred or 00:51:20.180 --> 00:51:21.580 more people from the Python program. 00:51:21.580 --> 00:51:24.720 And I kind of want to get back in touch with those people and kind of figure out like what they're 00:51:24.720 --> 00:51:27.080 doing, what they're working on, where they're headed, where they're heading in their 00:51:27.080 --> 00:51:27.320 careers. 00:51:27.320 --> 00:51:31.360 Maybe if I can, if I can, even if it's not a mentorship position, more, more like a 00:51:31.360 --> 00:51:34.560 accountability partner, you know, help them move forward through their careers. 00:51:34.560 --> 00:51:39.220 I like being able to have a hand in developing talent in the same way that people help me 00:51:39.220 --> 00:51:40.220 develop my talent. 00:51:40.220 --> 00:51:44.280 It doesn't take a lot of effort on somebody who's experienced on their part to just give 00:51:44.280 --> 00:51:45.320 a little bit of guidance. 00:51:45.320 --> 00:51:45.640 Yeah. 00:51:45.640 --> 00:51:49.600 Because when you're new, you just look around and it's even like, it gets worse every day. 00:51:49.600 --> 00:51:50.560 There are more frameworks. 00:51:50.560 --> 00:51:51.380 There are more languages. 00:51:51.380 --> 00:51:52.280 There are more libraries. 00:51:52.280 --> 00:51:53.820 You're like, I have no idea what to do. 00:51:53.880 --> 00:51:57.980 I know I want to learn this stuff and I want to accomplish this, but where do I start? 00:51:57.980 --> 00:51:58.280 Right? 00:51:58.280 --> 00:51:59.320 Like, how do I go about this? 00:51:59.320 --> 00:52:00.840 And so you can give them some guidance. 00:52:00.840 --> 00:52:01.860 It goes beyond that too. 00:52:01.860 --> 00:52:05.700 It's like, you know, well, you know, I never thought about giving a talk at a conference. 00:52:05.700 --> 00:52:07.440 I never thought about giving a talk at a meetup. 00:52:07.440 --> 00:52:12.040 I hadn't thought about giving a talk at a meetup until my friend Chris said, Hey, you should 00:52:12.040 --> 00:52:12.760 give talks at meetups. 00:52:12.760 --> 00:52:14.440 And I was like, Oh, I can, I can do that. 00:52:14.440 --> 00:52:15.460 That's a thing that I can do. 00:52:15.460 --> 00:52:15.660 Yeah. 00:52:15.660 --> 00:52:16.480 There's no gatekeepers. 00:52:16.480 --> 00:52:18.040 You just have to decide that you can do it. 00:52:18.040 --> 00:52:18.680 Then you can do it. 00:52:18.840 --> 00:52:19.120 Exactly. 00:52:19.120 --> 00:52:19.720 Exactly. 00:52:19.720 --> 00:52:23.140 There are going to be some things that I'm aware of that people who are my former students 00:52:23.140 --> 00:52:23.880 are not aware of. 00:52:23.880 --> 00:52:26.080 Like if there's a panel going on, like, Hey, you should be on this panel. 00:52:26.080 --> 00:52:27.140 We should attend this panel. 00:52:27.140 --> 00:52:27.940 We should meet this person. 00:52:27.940 --> 00:52:32.840 You should go to this coffee meeting and see these people and be aware of these, of these 00:52:32.840 --> 00:52:33.980 concepts of these environments. 00:52:33.980 --> 00:52:39.700 Because, you know, have I found I've been in a lot of different spaces in the last, let's 00:52:39.700 --> 00:52:41.100 say like 10 years or so. 00:52:41.420 --> 00:52:46.600 And what I've noticed in each of those roles has been that most of the work isn't just 00:52:46.600 --> 00:52:50.900 being in the right place at the right time or meeting the right person at the right time. 00:52:50.900 --> 00:52:57.480 And if you never meet that person or if you're never in that place, you don't even know that 00:52:57.480 --> 00:52:59.460 those opportunities are there to be taken advantage of. 00:52:59.460 --> 00:53:05.660 Like I've been able to make some great contacts at Facebook just by going to a hackathon once and 00:53:05.660 --> 00:53:07.500 chatting up one of the organizers of the hackathon. 00:53:08.280 --> 00:53:14.340 Or Twitter has been an amazing resource to meet people, see what they're into, learning 00:53:14.340 --> 00:53:18.520 about other things going on in the field of Python development, just being aware of being 00:53:18.520 --> 00:53:22.400 around and being able to help new people get into that community. 00:53:22.400 --> 00:53:22.640 Yeah. 00:53:22.640 --> 00:53:27.540 I find that a lot of these little hands that you offer to people to help them actually 00:53:27.540 --> 00:53:29.700 come back in unexpected ways. 00:53:29.700 --> 00:53:32.480 And, you know, there's a lot of karma in the world in that sense. 00:53:32.480 --> 00:53:33.240 Oh, absolutely. 00:53:33.240 --> 00:53:34.180 Absolutely. 00:53:34.180 --> 00:53:38.980 I never would have gone to my first conference as an astronomer if my advisor never told 00:53:38.980 --> 00:53:39.800 me about that it existed. 00:53:39.800 --> 00:53:40.100 Yeah. 00:53:40.100 --> 00:53:44.560 And then I wouldn't have met the person who introduced me to Marcel Agueros, who runs the 00:53:44.560 --> 00:53:45.900 Bridge of the PhD program at Columbia. 00:53:45.900 --> 00:53:50.960 If I'd never gone to that, I would probably never be here in Seattle doing Python instruction 00:53:50.960 --> 00:53:54.200 at Code Fellows because I never would have gone for a PhD at UDEL. 00:53:54.320 --> 00:53:58.500 There's so many things in the chain of events that could have gone a different way if I had 00:53:58.500 --> 00:54:00.560 just been in the right place at the right time or talked to the right people. 00:54:00.560 --> 00:54:06.380 I think the big takeaway here is you can't too deeply overthink these little variations 00:54:06.380 --> 00:54:08.620 because your life could be so different. 00:54:08.620 --> 00:54:10.760 Just, you know, sort of chaos theory, right? 00:54:10.760 --> 00:54:11.880 Butterfly wings type of thing. 00:54:11.880 --> 00:54:12.360 Absolutely. 00:54:12.360 --> 00:54:12.880 Yeah. 00:54:12.880 --> 00:54:13.240 Cool. 00:54:13.240 --> 00:54:13.880 All right. 00:54:13.880 --> 00:54:16.200 Well, I think we're getting close to the end of our time together. 00:54:16.200 --> 00:54:19.560 Let me hit you with the two questions that I always put at the end. 00:54:19.560 --> 00:54:23.420 If you're going to write some Python code, what editor do you open up? 00:54:23.500 --> 00:54:27.420 My first instinct is Sublime Text, but I've been going more toward Visual Studio Code 00:54:27.420 --> 00:54:28.460 in the last week. 00:54:28.460 --> 00:54:28.760 Okay. 00:54:28.760 --> 00:54:29.300 Yeah, nice. 00:54:29.300 --> 00:54:31.840 Visual Studio Code with a Python plugin is quite nice. 00:54:31.840 --> 00:54:32.240 Oh, yeah. 00:54:32.240 --> 00:54:35.860 I use Visual Studio Code for like if I just want to open up one file and stuff. 00:54:35.860 --> 00:54:36.780 I'm doing a big project. 00:54:36.780 --> 00:54:41.000 I usually use PyCharm, but I definitely like Visual Studio Code as well. 00:54:41.000 --> 00:54:41.640 All right. 00:54:41.640 --> 00:54:43.440 And then notable PyPI package. 00:54:43.440 --> 00:54:44.900 I love the requests library. 00:54:44.900 --> 00:54:46.060 I also love beautiful soup. 00:54:46.060 --> 00:54:50.360 And then pandas, when I was a researcher, pandas changed my life. 00:54:50.360 --> 00:54:52.340 Like how I did research, how I did analysis. 00:54:52.560 --> 00:54:53.880 I was using NumPy and NumPy arrays. 00:54:53.880 --> 00:54:55.260 Pandas all the way. 00:54:55.260 --> 00:54:56.020 Oh, that's awesome. 00:54:56.020 --> 00:54:56.340 Yeah. 00:54:56.340 --> 00:54:58.500 Pandas is really, really cool and important. 00:54:58.500 --> 00:55:02.780 And to me, requests and beautiful soup literally feels like magic. 00:55:02.780 --> 00:55:05.820 Like there's this web page with stuff. 00:55:05.820 --> 00:55:07.580 And then I write like five lines of code. 00:55:07.580 --> 00:55:10.820 And then I have it like in structured data on my machine. 00:55:10.820 --> 00:55:13.420 I'm like, that just blew my mind that that just happened. 00:55:13.420 --> 00:55:13.700 Right? 00:55:13.700 --> 00:55:14.900 It is really cool. 00:55:14.900 --> 00:55:15.320 Oh, yeah. 00:55:15.440 --> 00:55:15.680 All right. 00:55:15.680 --> 00:55:17.420 So final call to action. 00:55:17.420 --> 00:55:18.400 People are excited. 00:55:18.400 --> 00:55:22.840 Maybe they're about checking out these web frameworks, your project, or maybe even your bootcamp. 00:55:22.840 --> 00:55:23.360 What do you say? 00:55:23.360 --> 00:55:26.060 If you want to talk to me, the easiest way to reach me is on Twitter. 00:55:26.060 --> 00:55:27.460 It's just at Enhan Walker. 00:55:27.460 --> 00:55:29.360 I'm on there literally all the time. 00:55:29.360 --> 00:55:30.340 Probably more than I should be. 00:55:30.340 --> 00:55:34.040 If you're interested in learning how to code, Code Fellows is a dope place. 00:55:34.040 --> 00:55:40.240 If you're in Seattle or in Portland, Code Fellows, great place to learn JavaScript, Java, C#, or Python. 00:55:40.240 --> 00:55:47.440 We have some really dedicated instructors who are really focused on getting people into careers as best as they can. 00:55:47.440 --> 00:55:47.760 All right. 00:55:47.760 --> 00:55:48.180 Awesome. 00:55:48.180 --> 00:55:53.620 Well, Nick, it's really been great to share the four framework comparison with you and the stories. 00:55:53.620 --> 00:55:54.780 Thank you so much for being on the show. 00:55:54.780 --> 00:55:55.560 Thanks for having me. 00:55:55.560 --> 00:55:56.840 I hope this was helpful to somebody. 00:55:56.840 --> 00:55:57.820 Yeah, I'm sure it will be. 00:55:57.820 --> 00:55:58.320 All right. 00:55:58.320 --> 00:55:58.480 Bye. 00:55:58.480 --> 00:55:58.800 Bye. 00:55:58.800 --> 00:56:03.120 This has been another episode of Talk Python To Me. 00:56:03.620 --> 00:56:07.800 Today's guest was Nicholas Hunt Walker, and this episode has been brought to you by Linode. 00:56:07.800 --> 00:56:11.580 Linode is bulletproof hosting for whatever you're building with Python. 00:56:11.580 --> 00:56:15.940 Get four months free at talkpython.fm/linode. 00:56:15.940 --> 00:56:17.720 That's L-I-N-O-D-E. 00:56:17.720 --> 00:56:20.440 Are you or a colleague trying to learn Python? 00:56:20.440 --> 00:56:25.120 Have you tried books and videos that just left you bored by covering topics point by point? 00:56:25.120 --> 00:56:31.140 Well, check out my online course, Python Jumpstart, by building 10 apps at talkpython.fm/course 00:56:31.140 --> 00:56:33.700 to experience a more engaging way to learn Python. 00:56:33.700 --> 00:56:38.540 And if you're looking for something a little more advanced, try my Write Pythonic code course 00:56:38.540 --> 00:56:41.080 at talkpython.fm/pythonic. 00:56:41.080 --> 00:56:43.800 Be sure to subscribe to the show. 00:56:43.800 --> 00:56:46.000 Open your favorite podcatcher and search for Python. 00:56:46.000 --> 00:56:47.240 We should be right at the top. 00:56:47.240 --> 00:56:53.360 You can also find the iTunes feed at /itunes, Google Play feed at /play, and direct 00:56:53.360 --> 00:56:56.560 RSS feed at /rss on talkpython.fm. 00:56:56.880 --> 00:56:58.440 This is your host, Michael Kennedy. 00:56:58.440 --> 00:56:59.800 Thanks so much for listening. 00:56:59.800 --> 00:57:00.860 I really appreciate it. 00:57:00.860 --> 00:57:02.800 Now get out there and write some Python code. 00:57:02.800 --> 00:57:03.320 I'll see you next time. 00:57:03.320 --> 00:57:03.440 Bye. 00:57:03.440 --> 00:57:03.600 Bye. 00:57:03.600 --> 00:57:03.600 Bye. 00:57:03.600 --> 00:57:03.640 Bye. 00:57:03.640 --> 00:57:04.440 Bye. 00:57:04.440 --> 00:57:04.440 Bye. 00:57:04.440 --> 00:57:04.440 Bye. 00:57:04.440 --> 00:57:04.440 Bye. 00:57:04.440 --> 00:57:05.240 Bye. 00:57:05.240 --> 00:57:05.240 Bye. 00:57:05.240 --> 00:57:05.240 Bye. 00:57:05.240 --> 00:57:06.040 Bye. 00:57:06.040 --> 00:57:06.040 Bye. 00:57:06.040 --> 00:57:06.040 Bye. 00:57:06.040 --> 00:57:06.040 Bye. 00:57:06.040 --> 00:57:06.040 Bye. 00:57:06.040 --> 00:57:06.040 Bye. 00:57:06.040 --> 00:57:06.840 Bye. 00:57:06.840 --> 00:57:06.840 Bye. 00:57:06.840 --> 00:57:06.840 Bye. 00:57:06.840 --> 00:57:06.840 Bye. 00:57:06.840 --> 00:57:06.840 Bye. 00:57:06.840 --> 00:57:07.640 Bye. 00:57:07.640 --> 00:57:07.640 Bye. 00:57:07.640 --> 00:57:07.640 Bye. 00:57:07.640 --> 00:57:07.640 Bye. 00:57:07.640 --> 00:57:08.440 Bye. 00:57:08.440 --> 00:57:08.440 Bye. 00:57:08.440 --> 00:57:08.440 Bye. 00:57:08.440 --> 00:57:09.240 Bye. 00:57:09.240 --> 00:57:09.240 Bye. 00:57:09.240 --> 00:57:09.240 Bye. 00:57:09.240 --> 00:57:10.040 Bye. 00:57:10.040 --> 00:57:10.040 Bye. 00:57:10.040 --> 00:57:10.040 Bye. 00:57:10.040 --> 00:57:10.040 Bye. 00:57:10.040 --> 00:57:10.040 Bye. 00:57:10.040 --> 00:57:10.840 Bye. 00:57:10.840 --> 00:57:11.640 Bye. 00:57:11.640 --> 00:57:12.440 Bye. 00:57:12.440 --> 00:57:13.240 Bye. 00:57:13.240 --> 00:57:14.040 Bye. 00:57:14.040 --> 00:57:14.840 Bye. 00:57:14.840 --> 00:57:15.640 Bye. 00:57:15.640 --> 00:57:16.440 Bye. 00:57:16.440 --> 00:57:17.240 Bye. 00:57:17.240 --> 00:57:18.040 Bye. 00:57:18.040 --> 00:57:18.840 Bye. 00:57:18.840 --> 00:57:19.640 Bye. 00:57:19.640 --> 00:57:20.440 Bye. 00:57:20.440 --> 00:57:20.940 you 00:57:20.940 --> 00:57:21.220 Thank you. 00:57:21.220 --> 00:57:23.220 Thank you. 00:57:23.220 --> 00:57:53.200 Thank you.