WEBVTT 00:00:00.001 --> 00:00:05.220 Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds. 00:00:05.220 --> 00:00:09.660 This is episode 295, recorded August 4th, 2022. 00:00:09.660 --> 00:00:11.120 And I am Brian Okken. 00:00:11.120 --> 00:00:12.200 I'm Michael Kennedy. 00:00:12.200 --> 00:00:13.400 It's good to have you back. 00:00:13.400 --> 00:00:14.380 Good to be back. 00:00:14.380 --> 00:00:20.200 For people out there listening, we kind of batched some stuff up so that we have vacation for a couple of weeks. 00:00:20.200 --> 00:00:25.160 But now our news items will be more closely related in time to the release of the episode. 00:00:25.160 --> 00:00:27.180 Oh, we didn't do that. 00:00:27.180 --> 00:00:28.080 It was live. 00:00:28.080 --> 00:00:30.120 Always live. 00:00:30.120 --> 00:00:30.940 Always live. 00:00:30.940 --> 00:00:31.260 Yeah. 00:00:31.260 --> 00:00:33.680 I'm glad you got back quickly. 00:00:33.680 --> 00:00:37.500 And speaking of fast, you've got a fast story for us. 00:00:37.500 --> 00:00:37.980 Yeah. 00:00:37.980 --> 00:00:39.760 How about we make things faster? 00:00:39.760 --> 00:00:43.580 So I want to talk about Flask and Cort. 00:00:43.580 --> 00:00:45.540 So Flask is Flask. 00:00:45.540 --> 00:00:47.560 It's one of the most popular web frameworks out there. 00:00:47.560 --> 00:00:55.320 Cort is the API compatible async version of Flask, originally done by Philip Jones. 00:00:55.320 --> 00:01:02.220 But I think that Philip has joined David Lord, at least in support of the Palette's organization. 00:01:02.220 --> 00:01:05.740 I feel like Flask and Cort are working much closer together these days. 00:01:05.740 --> 00:01:10.920 So I don't know exactly what the relationship is, but Flask and Cort are very closely tied together right now. 00:01:10.920 --> 00:01:11.340 Yeah. 00:01:11.540 --> 00:01:13.820 What I want to talk about is routing. 00:01:13.820 --> 00:01:17.140 Or for those UK friends, routing, if you prefer. 00:01:17.140 --> 00:01:21.780 But the idea of taking a URL and figuring out what function to call. 00:01:21.780 --> 00:01:22.280 Right. 00:01:22.340 --> 00:01:29.580 So what you do is you set up in Flask, you say at app.get, app.post, and you give it URL pattern. 00:01:29.580 --> 00:01:31.340 Sometimes that's just like slash about. 00:01:31.340 --> 00:01:37.800 Other times it's like slash categories, bracket category name, or even more general stuff. 00:01:37.800 --> 00:01:43.200 Like where you might say it's category, maybe a category ID, and it has to be an integer. 00:01:43.380 --> 00:01:44.560 So convert that for me. 00:01:44.560 --> 00:01:51.940 Or I want to just capture arbitrary path, arbitrary URLs slash edit, whatever that happens to be. 00:01:51.940 --> 00:01:54.360 So that's the idea of routing. 00:01:54.360 --> 00:02:07.120 And the whole article here, something the big news is that Philip Jones has worked on Vexoig, the HTTP router that is the foundation of doing the routing in Flask and Cort. 00:02:07.120 --> 00:02:11.200 And it's something like five times faster than it was before. 00:02:11.200 --> 00:02:12.480 I think five times the number. 00:02:12.480 --> 00:02:12.940 Wow. 00:02:12.940 --> 00:02:13.460 Much faster. 00:02:13.460 --> 00:02:18.180 So for very small little toy apps, if you have a couple of routes, whatever, it's no big deal. 00:02:18.180 --> 00:02:28.620 However, if you've got a production app like, say, TalkBiton training, where you've got hundreds, at least hundreds of routes, when a URL comes in, you can spend a decent amount of time checking. 00:02:28.620 --> 00:02:30.820 Is it get or is it post? 00:02:30.820 --> 00:02:33.860 Is it this URL and actually this thing here? 00:02:33.860 --> 00:02:35.080 Can we convert it to an integer? 00:02:35.080 --> 00:02:36.720 Because if not, that's a 404. 00:02:36.720 --> 00:02:37.640 It's a different route. 00:02:37.640 --> 00:02:39.660 And you're like all the stuff that goes on there. 00:02:39.660 --> 00:02:40.140 Yeah. 00:02:40.140 --> 00:02:54.940 So the way that it worked previously is it just, when you would specify these routes like app.get slash API and API slash angle bracket ID, those types of things, it would just come up with a table that just says, okay, here's the get verb. 00:02:54.940 --> 00:02:56.280 Here's the path. 00:02:56.280 --> 00:02:58.360 And here's the function that it goes to. 00:02:58.360 --> 00:03:00.100 And it was using regular expressions. 00:03:00.100 --> 00:03:06.400 So slash API or slash API and then backslash D plus, right? 00:03:06.400 --> 00:03:08.140 The regular expression for a number. 00:03:08.140 --> 00:03:08.580 Okay. 00:03:08.580 --> 00:03:17.440 And the way it works is it just says, okay, we're going to run the verb test, the regex test, all those things, one at a time, top to bottom. 00:03:17.440 --> 00:03:21.720 Well, Brian, I know you studied a lot of computer stuff. 00:03:21.720 --> 00:03:26.780 This is not something that's good that grows with time, right? 00:03:26.780 --> 00:03:29.820 As you add more of these, it's complexity. 00:03:29.820 --> 00:03:30.240 What is it? 00:03:30.240 --> 00:03:35.180 Something like O of N or maybe a little bit O of N squared, maybe? 00:03:35.180 --> 00:03:35.680 I'm not sure. 00:03:35.680 --> 00:03:39.880 Something like that where you're, cause you're testing the verbs and you're testing the things, right? 00:03:39.880 --> 00:03:44.580 So as you get these larger and larger, you're like running through them every single request. 00:03:44.580 --> 00:03:49.220 And the world is full of interesting data structures and algorithms that you might consider. 00:03:49.440 --> 00:03:58.580 So the idea was this is going to get rewritten into something that's not just the sort of brute force test at top to bottom in the order that it's defined here. 00:03:59.300 --> 00:04:05.780 And so I think one thing, it's interesting, the news that routing and flask and court is five times faster. 00:04:05.780 --> 00:04:06.560 That's fantastic. 00:04:06.560 --> 00:04:08.460 But also just thinking about the algorithms. 00:04:08.460 --> 00:04:13.820 I think it's a cool problem solver, problem solving thing to go look at, right? 00:04:13.820 --> 00:04:14.460 An example. 00:04:14.460 --> 00:04:19.740 So Philip thought about different ways in which you might do this and how it works. 00:04:20.000 --> 00:04:23.820 So the first algorithm that he looked at was a radix tree. 00:04:23.820 --> 00:04:30.700 And this is an interesting tree structure that gets defined where instead of having a table, you have all the verbs. 00:04:30.700 --> 00:04:36.200 And then under each verb, you've got the API, the path pattern. 00:04:36.200 --> 00:04:41.740 And one of the things that's interesting here is they have a path type. 00:04:41.740 --> 00:04:48.960 So if you were building a CMS or something that would handle arbitrary URLs, right? 00:04:48.960 --> 00:04:53.720 So you could build, say, a database thing that says, here's a URL and here's the content to show for that URL. 00:04:53.720 --> 00:05:00.020 How do you express all the variations of that in the routing of flask or other frameworks? 00:05:00.020 --> 00:05:06.000 Is you just say it's a path type instead of an integer or something along those lines, right? 00:05:06.000 --> 00:05:08.880 So there's kind of this wildcard thing that makes it a little bit harder. 00:05:08.880 --> 00:05:11.700 So you've got this get and you've got this post. 00:05:11.700 --> 00:05:13.560 You've got API. 00:05:13.560 --> 00:05:17.480 Remember, we had slash API and we had slash API slash ID. 00:05:17.480 --> 00:05:26.280 So what gets created is there's a get node in the tree, then an API node that if it matches exactly, terminates at that call. 00:05:26.280 --> 00:05:31.480 But if not, then it also has the, well, keep going and match the next part of the path as a number. 00:05:31.480 --> 00:05:34.620 And if that matches, then you're going to get this next segment. 00:05:34.760 --> 00:05:37.540 Otherwise, you'll go to the next part of the tree and cruise through it. 00:05:37.540 --> 00:05:38.240 What do you think of that? 00:05:38.240 --> 00:05:38.900 That looks cool, right? 00:05:38.900 --> 00:05:39.520 Yeah. 00:05:39.520 --> 00:05:45.400 And also, I mean, yeah, it looks good and also faster because you don't look at everything. 00:05:45.400 --> 00:05:45.800 Right. 00:05:45.800 --> 00:05:46.140 Exactly. 00:05:46.140 --> 00:05:47.460 You say, is it a get or post? 00:05:47.460 --> 00:05:47.840 Boom. 00:05:47.840 --> 00:05:49.920 You've like, you're down to like one segment. 00:05:49.920 --> 00:05:51.820 Then you're like, well, what's this next path? 00:05:51.820 --> 00:05:57.000 Then you really quickly cruise through the various possibilities. 00:05:57.000 --> 00:06:01.600 And this looks really great until you get down to this wild card thing. 00:06:01.600 --> 00:06:09.540 And it turns out with all the variations and whatnot of like the wild card matching and the sub wild card matching. 00:06:09.540 --> 00:06:11.120 And it didn't really work that well. 00:06:11.120 --> 00:06:18.160 So, but one benefit is the performance is now described as O of N, which is pretty good. 00:06:18.160 --> 00:06:20.520 Better than N squared or something like that. 00:06:20.520 --> 00:06:20.920 Yeah. 00:06:20.920 --> 00:06:21.960 Or yeah. 00:06:21.960 --> 00:06:24.620 And N is the depth now, not the. 00:06:24.620 --> 00:06:25.220 Right. 00:06:25.220 --> 00:06:26.440 And it's, that's very important. 00:06:26.440 --> 00:06:30.060 It's the depth rather than just the number, which is even better. 00:06:30.060 --> 00:06:30.360 Right. 00:06:30.360 --> 00:06:33.200 Because I think I'm still confused. 00:06:33.200 --> 00:06:42.020 If, if like, if they're all gets, for instance, if you're like most of your API is retrieval, are they all going to be falling into that wild card thing? 00:06:42.020 --> 00:06:42.640 Yeah. 00:06:42.640 --> 00:06:45.620 I think they would, but then they, they would just be one. 00:06:45.620 --> 00:06:46.840 I think it'd be one more step. 00:06:46.840 --> 00:06:53.280 I think it just splits pretty quick on the second part, but still it's not that relevant because that's, that turned out to not work. 00:06:53.280 --> 00:07:02.460 What works is something I would have never, never thought should apply to this pathfinding path determining algorithm. 00:07:02.460 --> 00:07:02.940 Ooh. 00:07:02.940 --> 00:07:04.820 And that's a state machine. 00:07:04.820 --> 00:07:05.560 Awesome. 00:07:05.560 --> 00:07:07.900 Are you a fan of state machines? 00:07:07.900 --> 00:07:08.840 Yes, I am. 00:07:08.840 --> 00:07:09.300 I love them. 00:07:09.300 --> 00:07:09.660 Yeah. 00:07:09.660 --> 00:07:10.200 Yeah. 00:07:10.200 --> 00:07:11.720 State machines are pretty wild. 00:07:11.720 --> 00:07:14.380 You know, I'm, I'm in the current editing state. 00:07:14.380 --> 00:07:16.120 Now, what are my options? 00:07:16.120 --> 00:07:17.080 Where could I go from here? 00:07:17.080 --> 00:07:17.800 Things like that. 00:07:17.800 --> 00:07:22.560 So you define the same set of routes, but what you get is a state machine that has these transitions. 00:07:23.180 --> 00:07:27.400 And for example, state one says, if you go to API, we'll go to state two. 00:07:27.400 --> 00:07:33.160 Or if you do some wildcard slash edit, then the answer is you just do the edit or you just do the true wildcard thing. 00:07:33.160 --> 00:07:35.480 And then you do some other, other step there. 00:07:35.480 --> 00:07:35.680 Right. 00:07:35.680 --> 00:07:36.500 Pretty interesting. 00:07:36.500 --> 00:07:43.520 And then say for this API, where it says go to state two, state two says, well, if there's nothing else, you've already gone through API. 00:07:43.520 --> 00:07:46.540 Then you call the function create API you're looking for. 00:07:46.540 --> 00:07:51.400 Otherwise, if it's a number, go to state three and state three says, well, if that's it, then you're done. 00:07:51.480 --> 00:07:54.480 Otherwise you're in this wildcard state and so on. 00:07:54.480 --> 00:07:58.060 And the way that you kind of bounce between these states, it's pretty fascinating. 00:07:58.060 --> 00:07:59.200 Yeah. 00:07:59.200 --> 00:08:01.580 And also like, how is this faster? 00:08:01.580 --> 00:08:04.580 But exactly. 00:08:04.580 --> 00:08:05.480 Yes, it doesn't. 00:08:05.480 --> 00:08:09.780 That's like I said, I would have never thought about it because it, it also doesn't seem faster. 00:08:09.780 --> 00:08:10.320 Yeah. 00:08:10.520 --> 00:08:20.580 However, you get to the benchmarking section and it says, I think by having 20 routes here or something, it came out to be quite a bit faster. 00:08:20.580 --> 00:08:21.660 Let's see. 00:08:21.660 --> 00:08:22.760 Boom, boom, boom, boom. 00:08:22.760 --> 00:08:25.900 Ratio of this one says 50% better. 00:08:25.900 --> 00:08:29.680 I said five times and maybe it's not that much faster, but some way I know there's a five. 00:08:29.680 --> 00:08:30.500 There's got to be. 00:08:30.500 --> 00:08:30.700 Yeah. 00:08:30.700 --> 00:08:31.140 Here we go. 00:08:31.140 --> 00:08:33.880 A factor up to five times speed increase. 00:08:33.880 --> 00:08:38.320 And the more routes you have, the faster, the bigger the increase is. 00:08:38.320 --> 00:08:42.820 The more complicated and big your application is, the more it's going to benefit from this. 00:08:42.820 --> 00:08:43.120 Right. 00:08:43.360 --> 00:08:49.040 I think it says that if you're looking at just like a toy example, you can run the benchmarks all you want. 00:08:49.040 --> 00:08:50.240 It's not going to make any difference. 00:08:50.240 --> 00:08:52.800 But for realistic ones, it'll be quite a bit faster. 00:08:52.800 --> 00:08:54.560 So pretty cool. 00:08:54.560 --> 00:09:00.940 If you're using Flask Record, be sure to use the latest version because the version that's coming up with this, 00:09:00.940 --> 00:09:02.860 is this going to make it a lot faster for you? 00:09:02.860 --> 00:09:11.600 And just an interesting example of how you might have a non-obvious solution to a problem like a state machine for finding the URL matches. 00:09:11.600 --> 00:09:12.100 Yeah. 00:09:12.100 --> 00:09:12.800 Yeah. 00:09:12.920 --> 00:09:14.740 Brandon out there on and says, I agree. 00:09:14.740 --> 00:09:15.760 I don't see all this as faster. 00:09:15.760 --> 00:09:18.280 I hear you. 00:09:18.280 --> 00:09:18.780 Yeah. 00:09:18.780 --> 00:09:24.160 But the cool thing about computers is you push the button and then it does a thing and then you know. 00:09:24.160 --> 00:09:24.600 Right. 00:09:24.600 --> 00:09:29.720 Well, it's not like you've got to have a theory and then you debate the theory and it's measurable. 00:09:29.720 --> 00:09:40.140 One of the interesting things around this also is that you can't assume much for Flask or Court because there are frameworks that other people build up websites with. 00:09:40.480 --> 00:09:48.340 So some people are going to have big forest trees that have lots of branching and everything for their routes. 00:09:48.340 --> 00:09:55.340 And some people are going to have like, oh, let's just throw half the stuff in one directory or one bucket or something like that. 00:09:55.340 --> 00:09:55.800 Right. 00:09:55.800 --> 00:09:56.300 That's true. 00:09:56.300 --> 00:10:02.300 A lot of people have different variations of how they construct the URLs that map into your site. 00:10:02.500 --> 00:10:03.740 And that also affects it. 00:10:03.740 --> 00:10:04.060 That's true. 00:10:04.060 --> 00:10:09.540 So you kind of have to have both be like one, you know, faster or not. 00:10:09.540 --> 00:10:11.420 You just have to not be slower. 00:10:11.420 --> 00:10:13.420 And in really any case. 00:10:13.420 --> 00:10:14.220 So interesting. 00:10:14.220 --> 00:10:14.500 Yeah. 00:10:14.500 --> 00:10:14.820 Yeah. 00:10:14.820 --> 00:10:17.700 Also looking at the state machine, there's only four states. 00:10:17.700 --> 00:10:21.860 Most things terminate in one or two steps. 00:10:22.140 --> 00:10:26.960 So instead of testing four, five, six different regular expressions doing one or two. 00:10:26.960 --> 00:10:28.760 But yeah, it's, it is interesting. 00:10:28.760 --> 00:10:29.160 All right. 00:10:29.160 --> 00:10:30.060 What do you got next for us? 00:10:30.060 --> 00:10:32.500 Well, speaking of court, we've got court. 00:10:32.500 --> 00:10:33.860 Oh, or corto. 00:10:33.860 --> 00:10:35.420 And actually it's funny. 00:10:35.420 --> 00:10:37.860 I have no idea if this is built on court or not. 00:10:37.860 --> 00:10:38.540 Probably not. 00:10:38.720 --> 00:10:39.900 But I don't know. 00:10:39.900 --> 00:10:44.100 So corto, this was, oh, somebody suggested it. 00:10:44.100 --> 00:10:44.720 Paul McKenzie. 00:10:44.720 --> 00:10:52.520 This is a, this is a thing to build documents and stuff, but it's, it's open source. 00:10:52.520 --> 00:10:58.340 And it's, it's, it's, they say open source scientific and technical publishing system built 00:10:58.340 --> 00:10:59.060 on Pandoc. 00:10:59.060 --> 00:11:00.700 So we love Pandoc. 00:11:00.700 --> 00:11:02.000 I, at least I do. 00:11:02.000 --> 00:11:06.920 It's, it converts Markdown to really anything else or rest to other stuff. 00:11:07.760 --> 00:11:09.740 Like a whole bunch of stuff. 00:11:09.740 --> 00:11:15.720 You can convert things to, to like PDFs or even eBooks and HTML documents, all sorts of 00:11:15.720 --> 00:11:16.020 things. 00:11:16.020 --> 00:11:23.720 So this is, and then Jupyter, of course, Jupyter's great for a lot of scientific Python research 00:11:23.720 --> 00:11:27.460 and data science, and even just learning Python and playing and stuff. 00:11:27.460 --> 00:11:34.380 And, and I've kind of liked to see lately some people doing presentations even with, with just 00:11:34.380 --> 00:11:37.980 right within Jupyter notebooks, just kind of fun. 00:11:37.980 --> 00:11:43.300 And I know people are teaching that way with tutorials, but anyway, so corto is a system where 00:11:43.300 --> 00:11:49.200 you can do, you can have documents be either Markdown documents or Jupyter notebooks and have a 00:11:49.200 --> 00:11:52.380 combination of these things around and then build up stuff. 00:11:52.380 --> 00:11:58.940 So you can, so, you know, you've got like a Jupyter notebook and a demo and some, some Markdown and 00:11:58.940 --> 00:12:05.360 stuff, and then you can convert the whole thing to a website or a, a journal entry or, you 00:12:05.360 --> 00:12:11.240 know, a publication ready for a journal or a website or an ebook or really anything. 00:12:11.240 --> 00:12:12.800 So this is pretty exciting. 00:12:12.800 --> 00:12:15.020 I think it's, I think it's very neat. 00:12:15.020 --> 00:12:20.880 The idea that you can take a notebook, put a little extra metadata into it, and then publish 00:12:20.880 --> 00:12:22.120 it to all these different sources. 00:12:22.120 --> 00:12:24.040 Have you seen how much you can do? 00:12:24.040 --> 00:12:25.420 You know, this is based on Pandoc. 00:12:25.420 --> 00:12:26.960 Have you seen how much you can do with Pandoc? 00:12:26.960 --> 00:12:28.060 Have you seen the conversion? 00:12:28.060 --> 00:12:31.180 Like here, I'll pull up their homepage here. 00:12:31.180 --> 00:12:33.720 you just go to Pandoc.org. 00:12:33.840 --> 00:12:36.480 See on the right, that thing that looks like gray shading. 00:12:36.480 --> 00:12:37.540 Yeah. 00:12:37.540 --> 00:12:41.160 Those are the different formats that it can convert from or to. 00:12:41.160 --> 00:12:41.640 Yeah. 00:12:41.640 --> 00:12:42.340 It's incredible. 00:12:42.340 --> 00:12:44.280 It's just like unbelievable. 00:12:44.280 --> 00:12:44.600 Yeah. 00:12:44.600 --> 00:12:44.860 Yeah. 00:12:44.860 --> 00:12:49.600 So when you say, okay, well, if I could take my notebook and then power it through Pandoc to 00:12:49.600 --> 00:12:52.880 do these things, like the output possibilities are insane. 00:12:52.880 --> 00:12:53.920 Yeah. 00:12:53.920 --> 00:13:00.720 and it even does, like one of the things that was unexpected, for me is the presentation. 00:13:00.720 --> 00:13:04.560 So you can convert one of these to, to like, PowerPoint. 00:13:04.560 --> 00:13:09.800 yeah, even to PowerPoint or, I was excited about reveal JS. 00:13:09.800 --> 00:13:11.040 I like reveal. 00:13:11.040 --> 00:13:14.580 but, and then Beamer, I don't know what Beamer is, but. 00:13:14.580 --> 00:13:15.940 I've never heard of Beamer either. 00:13:15.940 --> 00:13:18.700 it's going to be our new favorite way to present. 00:13:18.700 --> 00:13:19.320 Oh, I see. 00:13:19.320 --> 00:13:21.360 You can create Beamer LaTeX. 00:13:21.360 --> 00:13:21.880 I see. 00:13:21.880 --> 00:13:27.540 So it's Beamer maybe is a little more like scientific mathematical where you have to, you know, 00:13:27.540 --> 00:13:30.660 here's the integral of this or like where you've got really specific. 00:13:30.660 --> 00:13:31.180 Huh. 00:13:31.180 --> 00:13:32.020 Things possibly. 00:13:32.020 --> 00:13:32.540 I don't know. 00:13:32.540 --> 00:13:33.680 specific formulas. 00:13:33.680 --> 00:13:39.500 And then within each of these formats, there's things like, so, I use reveal JS for instance, 00:13:39.500 --> 00:13:43.420 but you can, there's, the documentation is great. 00:13:43.420 --> 00:13:48.420 It talks about using, using this to create like, you know, code blocks and line highlighting. 00:13:48.420 --> 00:13:49.840 And check this out. 00:13:49.840 --> 00:13:54.200 You've got, line height line highlighting that goes, incremental. 00:13:54.200 --> 00:13:56.460 So you could have, stages. 00:13:56.460 --> 00:14:01.880 You can, instead of step creating three slides, for instance, that have just slightly 00:14:01.880 --> 00:14:03.180 different highlighted texts. 00:14:03.180 --> 00:14:07.120 You can say what order you want things highlighted in as you step through them. 00:14:07.120 --> 00:14:10.160 So, I'm going to try this for a presentation. 00:14:10.160 --> 00:14:11.880 I might try this as well. 00:14:11.880 --> 00:14:12.580 This is pretty neat. 00:14:12.580 --> 00:14:12.940 Actually. 00:14:12.940 --> 00:14:16.080 I was excited also about the eBooks feature. 00:14:16.080 --> 00:14:18.820 you can even publish EPUB. 00:14:18.820 --> 00:14:23.720 I was talking to Matt, Matt Harrison about this and Matt pointed out that he'd seen 00:14:23.720 --> 00:14:29.280 this, but he was, if you really care about like indexing or the front matter or the back 00:14:29.280 --> 00:14:33.620 matter, this doesn't quite get there, for generating that stuff. 00:14:33.860 --> 00:14:38.620 but, there's cross, cross references and all sorts of things that it does do. 00:14:38.620 --> 00:14:42.960 So if you're, you know, just starting out of a publication, this would be kind of fun. 00:14:42.960 --> 00:14:44.680 So, I'm excited about this. 00:14:44.680 --> 00:14:50.900 The reason, one of the reasons why I brought up EPUB is, I read all my, I read all 00:14:50.900 --> 00:14:52.920 my, eBooks on a Kindle. 00:14:52.920 --> 00:14:56.880 And whenever I used to see this, I was like, but do Moby also? 00:14:56.880 --> 00:14:58.620 Cause I want to be able to read it on my Kindle. 00:14:58.620 --> 00:14:59.160 Yes, exactly. 00:14:59.540 --> 00:15:05.300 But, I don't have the link here, but, Kindle Amazon is doing a conversion this 00:15:05.300 --> 00:15:05.560 year. 00:15:05.560 --> 00:15:11.580 So, right now the mail to the last time I sent a Moby document to my Kindle through the 00:15:11.580 --> 00:15:17.560 email feature, it emailed me back and said, we did this, but, EPUB is preferred now. 00:15:17.560 --> 00:15:18.600 so. 00:15:18.600 --> 00:15:19.560 Oh, interesting. 00:15:19.560 --> 00:15:25.120 They're kind of moving away from the Moby format and back into, to EPUB. 00:15:25.120 --> 00:15:26.400 So that's really cool. 00:15:26.400 --> 00:15:26.860 Cool. 00:15:26.860 --> 00:15:27.240 Yeah. 00:15:27.240 --> 00:15:29.420 I use the send to Kindle app. 00:15:29.720 --> 00:15:32.160 It's some weird old archaic kind of app for me. 00:15:32.160 --> 00:15:32.600 Yeah. 00:15:32.600 --> 00:15:32.980 I try. 00:15:32.980 --> 00:15:33.900 Really? 00:15:33.900 --> 00:15:39.940 yeah, I can't, it's some weird sort of install an app on off the web. 00:15:39.940 --> 00:15:41.280 That's not a progressive web app. 00:15:41.280 --> 00:15:42.240 I can't remember what it is. 00:15:42.240 --> 00:15:42.640 It's something. 00:15:42.640 --> 00:15:43.060 Okay. 00:15:43.060 --> 00:15:47.760 I think from Adobe, it's some bizarre format, but yeah, that's what I just, I just, you, 00:15:47.760 --> 00:15:52.060 you get a free, you get like this email address that you can send stuff to and it just goes 00:15:52.060 --> 00:15:52.800 right to your Kindle. 00:15:52.800 --> 00:15:53.340 Yeah. 00:15:53.340 --> 00:15:53.600 Nice. 00:15:53.600 --> 00:15:55.200 So that's what I use usually. 00:15:55.200 --> 00:15:59.380 Anyway, I would probably use that if I didn't have so many Kindles over the 00:15:59.380 --> 00:16:03.440 years and I don't know which is the real, which email for it. 00:16:03.440 --> 00:16:03.700 Exactly. 00:16:03.700 --> 00:16:06.140 I was like five Kindles over and I lost some of them. 00:16:06.140 --> 00:16:08.420 You gotta like unregister them, man. 00:16:08.420 --> 00:16:09.700 Oh, come on. 00:16:09.700 --> 00:16:10.080 Yes. 00:16:10.080 --> 00:16:10.640 I should do that. 00:16:10.640 --> 00:16:14.040 But, so for the website stuff, it's kind of fun too. 00:16:14.140 --> 00:16:16.160 So this will generate websites for you. 00:16:16.160 --> 00:16:19.960 and, there, and then it has pages. 00:16:19.960 --> 00:16:20.640 Yeah. 00:16:20.640 --> 00:16:23.220 It has publishing input, publishing in it too. 00:16:23.220 --> 00:16:28.580 So you can, you can hook this up to a GitHub action and just say Quattro publish and be using 00:16:28.580 --> 00:16:29.920 this to publish stuff too. 00:16:29.920 --> 00:16:32.460 So, this is really kind of cool. 00:16:32.460 --> 00:16:38.060 the whole, the whole, the whole infrastructure around, documentation and publishing around 00:16:38.060 --> 00:16:39.140 scientific computing. 00:16:39.140 --> 00:16:40.780 So I'm pretty excited about this. 00:16:40.780 --> 00:16:41.200 Yeah. 00:16:41.200 --> 00:16:41.840 I love it. 00:16:41.840 --> 00:16:42.380 That's great. 00:16:42.380 --> 00:16:44.680 Now, before we move on, Brian. 00:16:44.680 --> 00:16:45.480 Yes. 00:16:45.480 --> 00:16:51.180 Another thing I'm excited about is, Microsoft for Microsoft for startups. 00:16:51.400 --> 00:16:54.860 it's the Microsoft for startups founders hub. 00:16:54.860 --> 00:16:58.660 So this episode of Python bites is brought to you by Microsoft for startups. 00:16:58.660 --> 00:17:04.180 Starting a business is hard, but by some estimates, over 90% of startups will go out of business 00:17:04.180 --> 00:17:05.140 in the first year. 00:17:05.140 --> 00:17:05.560 Ouch. 00:17:05.560 --> 00:17:10.680 With this in mind, Microsoft for startups set out to understand what startups need to be 00:17:10.680 --> 00:17:14.260 successful and create a digital platform to help overcome those challenges. 00:17:14.260 --> 00:17:16.800 Microsoft for startups founders hub. 00:17:17.120 --> 00:17:23.340 it provides all founders at any stage with free resources to help solve startup challenges. 00:17:23.340 --> 00:17:28.920 The platform provides technology benefits, access to expert guidance and skilled resources, 00:17:28.920 --> 00:17:31.600 mentorship, and networking connections, and so much more. 00:17:31.600 --> 00:17:36.900 Unlike others in the industry, Microsoft for startup founders hub doesn't require startups 00:17:36.900 --> 00:17:40.840 to be investor backed or third party validated to participate. 00:17:40.840 --> 00:17:42.940 Founders hub is truly open to all. 00:17:42.940 --> 00:17:47.060 So what do you get speed up development with free access to github and Microsoft 00:17:47.060 --> 00:17:51.460 cloud with the ability to unlock credits over time to help your startup innovate. 00:17:51.460 --> 00:17:56.760 Founders hub is partnering with innovation, innovative companies like open AI, a global leader 00:17:56.760 --> 00:18:01.460 in AI research and development to provide exclusive benefits and discounts through Microsoft for 00:18:01.460 --> 00:18:01.780 startups. 00:18:01.780 --> 00:18:06.600 Founders hub become becoming a founder is no longer about who, you know, you'll have access 00:18:06.600 --> 00:18:11.420 to mentors, their mentorship network, giving you access to a pool of hundreds of mentors 00:18:11.420 --> 00:18:16.820 across a range of disciplines across areas like validation, fundraising, management, and coaching. 00:18:17.000 --> 00:18:20.520 sales and marketing as well as specific technical stress points. 00:18:20.520 --> 00:18:25.460 You'll be able to book a one-on-one meeting with a mint with mentors, many of whom are former 00:18:25.460 --> 00:18:26.380 founders themselves. 00:18:26.380 --> 00:18:32.200 Make your idea reality today with the critical support you'll get from Microsoft for startups 00:18:32.200 --> 00:18:33.880 founders hub to join the program. 00:18:33.880 --> 00:18:35.400 Visit Python bytes. 00:18:35.400 --> 00:18:38.100 FM slash founders hub 2022. 00:18:38.100 --> 00:18:39.840 The link is in your show notes. 00:18:39.840 --> 00:18:40.440 Awesome. 00:18:40.640 --> 00:18:40.720 Yeah. 00:18:40.720 --> 00:18:42.480 Thanks Microsoft for supporting the show. 00:18:42.480 --> 00:18:47.500 They're, they're big backers of Python bytes and definitely help amplify what we're doing 00:18:47.500 --> 00:18:47.780 here. 00:18:47.780 --> 00:18:51.980 I think the most awesome thing is the mentors and the advice and support you get. 00:18:51.980 --> 00:18:52.420 Yeah. 00:18:52.420 --> 00:18:55.100 Well, this is one of the things I think is awesome is this. 00:18:55.280 --> 00:19:02.520 When I, when I read about this, I think about like the startup, the startup access that people 00:19:02.520 --> 00:19:06.940 get if they're in like Silicon Valley or walk Y Combinator or something like that. 00:19:06.940 --> 00:19:07.000 Yeah. 00:19:07.000 --> 00:19:07.840 Something like that. 00:19:07.840 --> 00:19:12.680 But this is, but that's, you only get a handful of those a year and this is open to a way, way 00:19:12.680 --> 00:19:13.220 more people. 00:19:13.220 --> 00:19:14.000 So that's cool. 00:19:14.000 --> 00:19:14.460 Awesome. 00:19:14.460 --> 00:19:14.900 Yeah. 00:19:15.080 --> 00:19:15.500 Very cool. 00:19:15.500 --> 00:19:15.860 All right. 00:19:15.860 --> 00:19:19.000 Can I take you on a diversion to show you something pretty cool? 00:19:19.000 --> 00:19:19.580 Yeah. 00:19:19.580 --> 00:19:20.220 All right. 00:19:20.220 --> 00:19:25.200 So, Dart is a programming language that we don't usually talk about on Python bytes, 00:19:25.200 --> 00:19:26.360 right? 00:19:26.360 --> 00:19:33.000 And Dart is a language that, that came out from Google and I felt like it was trying to compete 00:19:33.000 --> 00:19:40.460 with JavaScript to a large degree and didn't really gain a lot of traction until Flutter came 00:19:40.460 --> 00:19:48.500 along and Flutter is a really cool way to design mobile and desktop native applications using 00:19:48.500 --> 00:19:49.400 Dart, right? 00:19:49.400 --> 00:19:57.660 It's think of it as an alternative to Cordova, PhoneGap, Xamarin, Ionic, all these different 00:19:57.660 --> 00:20:02.040 sort of generic ways to build apps that run on different platforms. 00:20:02.040 --> 00:20:07.960 So with Flutter, I can build an app that runs on iOS and Android, but I can also compile it as 00:20:07.960 --> 00:20:13.420 a target to macOS, Linux and Windows, and I can even compile it to a target for the web 00:20:13.420 --> 00:20:14.960 where to run as a progressive web app. 00:20:14.960 --> 00:20:15.300 Okay. 00:20:15.300 --> 00:20:16.800 And you get some really cool apps. 00:20:16.800 --> 00:20:21.040 Like the, by far the most well known one is the BMW car. 00:20:21.040 --> 00:20:22.380 You have a BMW. 00:20:22.380 --> 00:20:25.920 This is like the app that is your car, but there's, there's other ones as well. 00:20:25.920 --> 00:20:27.620 It's used a lot within Google, obviously. 00:20:27.620 --> 00:20:28.280 Right. 00:20:28.280 --> 00:20:29.720 Now you may be wondering. 00:20:29.720 --> 00:20:31.320 I bought a car and all I got was an app. 00:20:31.320 --> 00:20:32.440 I know I would be too. 00:20:32.440 --> 00:20:35.780 By the way, sidebar, BMW is doing all sorts of weird stuff. 00:20:35.780 --> 00:20:38.520 They're charging you subscriptions to use your seat heaters. 00:20:38.520 --> 00:20:42.540 $18 a month subscription to turn on the seat heater that's already in your car. 00:20:42.540 --> 00:20:45.980 So I, the least thing I'd be upset about is the app. 00:20:45.980 --> 00:20:46.520 Okay. 00:20:46.520 --> 00:20:48.600 That's a, that's something else. 00:20:48.600 --> 00:20:51.940 Now, why in the world am I talking about Flutter and Dart? 00:20:52.080 --> 00:21:05.740 I'm actually looking into using Flutter and Dart to rebuild the Talk Python training apps so that we can have, macOS, Windows and Linux in addition to the iOS and Android version and give it like a refresh. 00:21:05.740 --> 00:21:09.260 And it's a really cool technology that I, I'm pretty excited about. 00:21:09.260 --> 00:21:12.700 So let me introduce you to something called Flet. 00:21:12.700 --> 00:21:13.940 Have you heard of Flet? 00:21:14.280 --> 00:21:16.620 Well, just because Brandon just mentioned it. 00:21:16.620 --> 00:21:19.720 Yeah. 00:21:19.720 --> 00:21:20.640 Tell me about Flet. 00:21:20.640 --> 00:21:20.940 Yes. 00:21:20.940 --> 00:21:21.640 Yes. 00:21:21.640 --> 00:21:21.940 Yes. 00:21:21.940 --> 00:21:24.340 very timely, Brandon. 00:21:24.340 --> 00:21:29.340 So Flet comes, was, sent over to us from Mikael Honkala. 00:21:29.560 --> 00:21:32.880 And Flet is the fastest way to build Flutter apps. 00:21:32.880 --> 00:21:36.460 But instead of using the Dart programming language, use Python. 00:21:36.460 --> 00:21:37.280 Oh, perfect. 00:21:37.280 --> 00:21:39.860 So let me see if I can, I'll go to the getting started. 00:21:39.860 --> 00:21:41.040 I'll pull up a little example here. 00:21:41.040 --> 00:21:43.980 so there's, an app here. 00:21:43.980 --> 00:21:44.500 Check out. 00:21:44.500 --> 00:21:46.300 It's a calculator and look at it. 00:21:46.300 --> 00:21:49.560 It's got a nice little animated, animated GIF showing how it works. 00:21:49.560 --> 00:21:53.860 And, you know, this looks like a proper calculator app you would see on a mobile phone or something, right? 00:21:53.860 --> 00:21:54.340 Yeah. 00:21:54.340 --> 00:21:55.460 It looks like my calculator. 00:21:55.460 --> 00:21:56.540 Yeah, exactly. 00:21:56.720 --> 00:22:05.740 You could even go see, interactive version that is running in your browser because one of the six or seven compile targets is your browser. 00:22:05.740 --> 00:22:08.240 And I don't know if you noticed, but how quick did that load? 00:22:08.240 --> 00:22:11.080 Way faster than PyScript or any of these other things. 00:22:11.080 --> 00:22:12.380 It was like nearly instant. 00:22:12.380 --> 00:22:19.980 So if you go through and you look at how you build it, you just create a main method in Python and it's provided a page. 00:22:19.980 --> 00:22:23.780 You say Flet.app and you just give it the function to call. 00:22:23.780 --> 00:22:26.780 And here you say, I'm just going to add some text called hello world, right? 00:22:26.780 --> 00:22:28.700 So you get your hello world here, but you don't want that. 00:22:28.700 --> 00:22:29.600 You want some controls. 00:22:29.600 --> 00:22:38.680 So I'm going to add a bunch of elevated buttons with like the buttons that are on the calculator, like one, two, three, star, plus, minus, and so on. 00:22:38.680 --> 00:22:40.920 And you end up with this column of that. 00:22:40.920 --> 00:22:44.660 That's, that's kind of interesting, but you want these in rows and columns. 00:22:44.660 --> 00:22:50.160 So you would say I'm creating a row, which has some controls for elevated buttons, another row, right? 00:22:50.160 --> 00:22:52.260 So these are the rows of the calculators. 00:22:52.260 --> 00:22:57.460 And look at that already, how cool it is to define that UI with just that in Python. 00:22:57.460 --> 00:22:57.940 Yeah. 00:22:57.940 --> 00:22:58.200 Right. 00:22:58.200 --> 00:22:58.760 It's pretty neat. 00:22:59.020 --> 00:23:05.900 And because it's Flutter, all of these things have native representations on their platforms, right? 00:23:05.900 --> 00:23:11.960 In macOS, it looks like a macOS button and Windows looks like a Windows button and so on. 00:23:11.960 --> 00:23:15.920 You got to put styles to make it look like, you know, the calculator app type of thing. 00:23:16.200 --> 00:23:18.340 So yeah, that's pretty much it. 00:23:18.340 --> 00:23:22.500 You just go and you put all these controls together like this and you say go. 00:23:22.500 --> 00:23:26.840 And then somewhere in here, there's a place where it talks about handling the input. 00:23:26.840 --> 00:23:37.500 But yeah, so here you just say, I have a create a class and then on click itself dot button clicked or, or whatever it is, whatever you're interested in. 00:23:37.500 --> 00:23:45.020 And what it's going to pass over is the actual button, the elevated button that was clicked, the event source or whatever you call it. 00:23:45.020 --> 00:23:45.540 Right. 00:23:45.800 --> 00:23:53.620 So you just say, I'm hooked into these different button click events like you would with any sort of UI reactive framework. 00:23:53.620 --> 00:23:57.900 And now you have a calculator or you've got a, what other kind of app you want to build? 00:23:57.900 --> 00:23:58.680 Isn't that cool? 00:23:58.680 --> 00:23:59.780 It's very neat. 00:23:59.780 --> 00:24:02.120 So you can build both. 00:24:02.120 --> 00:24:06.900 So I think some people would use this for iOS or Android, right? 00:24:06.900 --> 00:24:07.780 A mobile device. 00:24:07.780 --> 00:24:10.820 But you said there's other things too, like you can test it out. 00:24:10.820 --> 00:24:14.740 Would you realistically use this to develop a, like a web app? 00:24:14.740 --> 00:24:15.140 Would you? 00:24:15.180 --> 00:24:18.180 I think developing a web app seems like it would be totally reasonable. 00:24:18.180 --> 00:24:25.460 If one of the things, if you look here, if you go to the roadmap, the mobile story is not yet complete actually. 00:24:25.460 --> 00:24:26.060 Okay. 00:24:26.340 --> 00:24:30.740 So right now I would think of it as more of a desktop type of thing. 00:24:30.740 --> 00:24:36.780 But as you saw with that example, there's also a web, so desktop and sort of progressive web app story, right? 00:24:36.780 --> 00:24:40.580 The mobile story is not yet finished, but that's what's on the roadmap. 00:24:40.580 --> 00:24:44.260 And I would love to see it, see it come along and make good progress. 00:24:44.260 --> 00:24:46.720 There's also the possibility of other languages. 00:24:46.940 --> 00:24:49.260 That's not super interesting to me. 00:24:49.260 --> 00:24:52.060 But because I want to write Python. 00:24:52.060 --> 00:24:58.120 Anyway, but you have like Go and C# and stuff as possible other programming languages. 00:24:58.120 --> 00:24:58.660 Yeah. 00:24:58.760 --> 00:25:05.320 But things like having a built-in database with a simple ORM, it sounds way more, it's way more powerful than it sounds. 00:25:05.320 --> 00:25:09.000 Because if you're in the web, well, how do you do database stuff? 00:25:09.100 --> 00:25:17.920 You know, the web has local storage and it has like a SQL, a wimpy SQL thing that's embedded in like offline storage for your app. 00:25:17.920 --> 00:25:24.080 If you're on iOS, you've got SQLite built in and stuff, but figuring out all those variations is a pain. 00:25:24.080 --> 00:25:32.340 But if you can just say create a database and do queries against it with an ORM, all of a sudden that gives you a super cool offline data access story. 00:25:32.340 --> 00:25:32.580 Yeah. 00:25:32.580 --> 00:25:33.080 Right? 00:25:33.080 --> 00:25:33.560 Yeah. 00:25:33.560 --> 00:25:34.960 And so on. 00:25:35.220 --> 00:25:39.140 So anyway, yeah, I think there's a lot of neat things that are coming here. 00:25:39.140 --> 00:25:44.740 This is created by, let me see if I got the name, by Fedora Fitzner. 00:25:44.740 --> 00:25:49.200 I'm actually having Fedora on HawkPython next week to talk about this. 00:25:49.200 --> 00:25:51.000 So we're going to be diving even more into it. 00:25:51.000 --> 00:25:51.380 Okay. 00:25:51.380 --> 00:25:51.820 Yeah. 00:25:51.820 --> 00:25:52.020 Cool. 00:25:52.020 --> 00:25:52.980 Nice. 00:25:52.980 --> 00:25:58.420 I don't know how ready this is for producing actual finished applications. 00:25:58.420 --> 00:26:00.860 Flutter is absolutely ready to go, right? 00:26:00.860 --> 00:26:04.620 It's been around for many years and there's lots of things being put out in production for it. 00:26:04.620 --> 00:26:05.780 Flutter on top of Flutter. 00:26:05.780 --> 00:26:07.140 Don't totally know. 00:26:07.140 --> 00:26:11.180 I'll ask for later, next week, and we'll know a little bit more. 00:26:11.180 --> 00:26:20.640 But when I look at this, this is really exciting because it looks like it builds applications that I would really want to use using modern paradigms and all sorts of cool stuff. 00:26:20.640 --> 00:26:24.480 So, and you should be able to integrate with all the Flutter things, which is great. 00:26:24.480 --> 00:26:24.920 Neat. 00:26:24.920 --> 00:26:25.380 Yeah. 00:26:25.380 --> 00:26:26.680 Anyway, very cool. 00:26:26.680 --> 00:26:28.500 Thank you, Mikhail, for sending that over. 00:26:29.140 --> 00:26:31.500 So that's a UI thing. 00:26:31.500 --> 00:26:35.040 I'd like to switch gears to the command line. 00:26:35.040 --> 00:26:36.980 So I was... 00:26:36.980 --> 00:26:37.240 To the TUI. 00:26:37.240 --> 00:26:39.020 To the Klee? 00:26:39.020 --> 00:26:41.640 The TUI, the text user interface. 00:26:41.640 --> 00:26:42.040 Oh, yeah. 00:26:42.040 --> 00:26:43.060 Text user interface. 00:26:43.060 --> 00:26:43.300 Yeah. 00:26:43.300 --> 00:26:44.780 Anyway. 00:26:44.780 --> 00:26:47.160 So like with rich and textual and things like that. 00:26:47.420 --> 00:26:50.260 So I was really excited about this article, actually. 00:26:50.260 --> 00:26:51.440 And now I'm a little confused. 00:26:51.440 --> 00:26:53.260 So I'm glad I'm going to talk it through. 00:26:53.260 --> 00:26:54.840 And you can let... 00:26:54.840 --> 00:26:56.260 I'd like to hear what you think. 00:26:56.260 --> 00:26:59.860 So I ran across this article. 00:26:59.860 --> 00:27:03.640 It's called Building an Authenticated Python CLI. 00:27:03.960 --> 00:27:06.580 And it's from Notia. 00:27:06.580 --> 00:27:07.300 Notia? 00:27:07.300 --> 00:27:07.920 Notia. 00:27:07.920 --> 00:27:08.660 Notia. 00:27:08.660 --> 00:27:09.300 Notia. 00:27:09.300 --> 00:27:09.980 Anyway. 00:27:09.980 --> 00:27:12.320 It's a blog post about building this. 00:27:12.320 --> 00:27:13.840 So here's the idea. 00:27:13.840 --> 00:27:14.800 So if you've got a... 00:27:14.800 --> 00:27:19.480 And for this application, you need Twitter authentication. 00:27:19.480 --> 00:27:28.140 So if they're developing a command line application that has to use the Twitter API, to get that, 00:27:28.140 --> 00:27:29.040 we've got some secrets. 00:27:29.040 --> 00:27:33.060 So you've got a client ID and a secret that you've set up. 00:27:33.060 --> 00:27:36.360 And you need to store the Twitter token somewhere. 00:27:36.360 --> 00:27:40.040 You're going to do that OAuth exchange where you say, we're going to connect to Twitter. 00:27:40.040 --> 00:27:45.080 And Twitter says, this app is going to interact with your account this way and whatnot, right? 00:27:45.080 --> 00:27:45.540 Right. 00:27:45.540 --> 00:27:47.040 So I want to be able to just... 00:27:47.040 --> 00:27:53.040 But I'd like to be able to have the application keep that around and not have to do that. 00:27:53.040 --> 00:27:55.340 Not really build it into the app. 00:27:55.340 --> 00:27:58.940 I don't want to compile it into the app or copy that. 00:27:58.940 --> 00:27:59.640 Token there. 00:27:59.640 --> 00:28:01.260 I want to be able to put that somewhere else. 00:28:01.260 --> 00:28:05.940 So the idea around this article is to take that, use the Twitter API. 00:28:05.940 --> 00:28:13.400 They talk about using click and rich a little bit, but for the command line stuff and click is cool. 00:28:13.400 --> 00:28:15.740 And we both love rich. 00:28:15.740 --> 00:28:18.940 And anyway, so the idea is to use a... 00:28:18.940 --> 00:28:20.940 Once you have... 00:28:20.940 --> 00:28:24.300 So use the OAuth and you come back and you've got a bear... 00:28:24.300 --> 00:28:25.080 What they call it? 00:28:25.080 --> 00:28:26.820 A bearer token. 00:28:26.820 --> 00:28:28.000 A bearer token. 00:28:28.000 --> 00:28:32.320 And then saving that in a file called a netRC file. 00:28:32.320 --> 00:28:44.580 And instead of telling somebody to just go put it there, they're reading, like asking the user for the client ID and the secret from the Twitter API website stuff. 00:28:44.580 --> 00:28:46.060 So copy it and paste it here. 00:28:46.340 --> 00:28:54.180 And then they're storing that bearer token in the netRC file. 00:28:54.180 --> 00:28:58.720 And then the next time the application runs, it just reads that. 00:28:58.720 --> 00:29:00.420 And you don't have to do it every time. 00:29:00.420 --> 00:29:08.440 And then that stuff isn't stored with the client code, but it's stored within the user netRC file or something. 00:29:08.840 --> 00:29:20.780 So at first I thought this was something that you could use for, like, okay, so I don't know whether or not this is a good idea for that even, whether you want to store your bearer stuff. 00:29:22.220 --> 00:29:31.340 But you probably don't want to ask the user for username and password and store that there because it's just a text file, I think. 00:29:31.340 --> 00:29:33.780 But maybe there's some other way around. 00:29:33.780 --> 00:29:35.420 I was kind of hoping that... 00:29:35.420 --> 00:29:43.280 I'd rather lose an OAuth token than I would my actual username and password because at least you can revoke the tokens or expire them and stuff, you know? 00:29:43.280 --> 00:29:43.780 Okay. 00:29:43.780 --> 00:29:50.140 So for token stuff, for saving tokens, is this a reasonable thing to do to keep that in the user's directory or something? 00:29:50.140 --> 00:29:52.620 Seems like it's all right. 00:29:52.620 --> 00:29:59.280 I'm a little suspicious of storing straight plain text, even if it is just an OAuth token. 00:29:59.280 --> 00:29:59.860 Yeah. 00:29:59.860 --> 00:30:00.300 Okay. 00:30:00.860 --> 00:30:07.240 I might, you know, I don't know, because I haven't read the article all the way through, but I might encrypt the token and then store it. 00:30:07.240 --> 00:30:07.660 Yeah. 00:30:07.660 --> 00:30:08.220 You know? 00:30:08.220 --> 00:30:08.500 Yeah. 00:30:08.500 --> 00:30:15.700 So actually, so I wanted to start this conversation and then ask people because either for token... 00:30:15.700 --> 00:30:22.180 I know there's other password ways to, like, store them locally safely, but is it something that... 00:30:22.180 --> 00:30:23.180 Can you do that with... 00:30:23.180 --> 00:30:35.840 Anyway, I'd love to hear people's thoughts on this, on where, like, what's the best way to store people's secret information so they don't have to enter it every time? 00:30:35.840 --> 00:30:36.440 Yeah. 00:30:36.440 --> 00:30:41.840 But, so storing in their user directory might not be terrible, but maybe there's a better way. 00:30:41.840 --> 00:30:46.280 So it's probably operating system specific too, but I don't know. 00:30:46.280 --> 00:30:46.480 Right. 00:30:46.480 --> 00:30:52.560 Well, your user profile is protected in general, right, from other users. 00:30:52.560 --> 00:30:53.140 Right. 00:30:53.140 --> 00:30:58.640 But is it protected if you run an app that decides it's just going to go cruising through your user profile? 00:30:58.640 --> 00:31:02.560 You know, something that you ran and you shouldn't have trusted it, but you did. 00:31:02.560 --> 00:31:07.460 I mean, SSH token, SSH keys, private keys are there, right, in the .SSH folder. 00:31:07.460 --> 00:31:08.900 Yeah, that's true. 00:31:09.180 --> 00:31:12.080 Yeah, that's probably worse than losing an OAuth token as well. 00:31:12.080 --> 00:31:18.940 So if you can guess, I'm thinking of, I'm in the design process for a command line application that has to store user credentials. 00:31:18.940 --> 00:31:22.400 So that's where I was running across stuff like this. 00:31:22.400 --> 00:31:25.340 I mean, isn't that one of the benefits of doing this podcast? 00:31:25.340 --> 00:31:33.040 It's a byproduct of our natural just working on new projects, like Flutter for me on the previous one, right? 00:31:33.040 --> 00:31:33.400 Yeah. 00:31:33.400 --> 00:31:33.640 Okay. 00:31:33.640 --> 00:31:35.620 Yeah, this is interesting, and I see where it goes. 00:31:35.620 --> 00:31:36.080 Yeah. 00:31:36.080 --> 00:31:36.200 Cool. 00:31:36.380 --> 00:31:38.540 But yeah, I would probably at least encrypt the token. 00:31:38.540 --> 00:31:39.460 I don't know. 00:31:39.460 --> 00:31:40.540 Okay, thanks. 00:31:40.540 --> 00:31:41.120 Maybe it doesn't matter. 00:31:41.120 --> 00:31:41.520 Yeah. 00:31:41.520 --> 00:31:42.020 Well. 00:31:42.020 --> 00:31:42.420 Awesome. 00:31:42.420 --> 00:31:43.980 They're done with our normal items. 00:31:43.980 --> 00:31:50.960 So the extra stuff that I had that I was going to let you go first, but I'm super excited. 00:31:50.960 --> 00:31:53.820 I'm getting a whole bunch done on the PyTist course, man. 00:31:53.820 --> 00:31:59.760 Really quick before you go on, just Sam Morley out there says, that's why you should encrypt your secret keys. 00:31:59.760 --> 00:32:03.140 And system tool chain is probably the correct, in quotes, answer. 00:32:03.140 --> 00:32:04.740 Okay, system tool chain. 00:32:05.020 --> 00:32:05.280 Okay. 00:32:05.280 --> 00:32:07.100 I don't even know what that means, but I'll look it up. 00:32:07.100 --> 00:32:10.980 Yes, this is something to go taggy or DuckDuckGo or maybe Google. 00:32:10.980 --> 00:32:11.480 Okay. 00:32:11.480 --> 00:32:16.220 I'm excited to hear about this PyTist course, because people have been asking, and progress 00:32:16.220 --> 00:32:18.060 is being significantly made, right? 00:32:18.060 --> 00:32:18.400 Awesome. 00:32:18.400 --> 00:32:19.040 How's it going? 00:32:19.040 --> 00:32:19.620 Yeah. 00:32:19.620 --> 00:32:20.380 Yeah, it's going great. 00:32:20.380 --> 00:32:23.760 So I've got, it's really seven chapters. 00:32:23.760 --> 00:32:28.600 It's broken up into seven sections or chapters, but it's a video course. 00:32:28.600 --> 00:32:36.440 But I'm really excited about it, because the PyTist book has received a lot of people of it, which is great. 00:32:36.440 --> 00:32:36.960 I love that. 00:32:36.960 --> 00:32:38.520 I got great feedback. 00:32:38.920 --> 00:32:41.580 But it's detailed, right? 00:32:41.580 --> 00:32:43.860 So we jump into a whole bunch of the details. 00:32:43.860 --> 00:32:48.220 And with a book, you can kind of get to some section that you're like, yeah, I don't need that right now. 00:32:48.220 --> 00:32:49.340 And you can skip over it. 00:32:49.620 --> 00:32:52.200 And yes, you can do that with a course, but it's a little harder. 00:32:52.200 --> 00:33:02.580 So the goal for this is really for people new to PyTist or that are just using a little piece of it and unfamiliar with some of the powers, 00:33:02.580 --> 00:33:08.040 is to introduce people to the full power of PyTist, but quickly and not overwhelm them. 00:33:08.040 --> 00:33:10.520 So I think I've done a good job, but we'll see. 00:33:10.520 --> 00:33:13.920 We'll get it edited and get it available to people as soon as we can. 00:33:13.920 --> 00:33:14.880 And it's pretty exciting. 00:33:14.880 --> 00:33:15.260 Yeah, I'm excited. 00:33:15.260 --> 00:33:15.740 Yeah. 00:33:15.740 --> 00:33:16.740 I'm excited to check it out. 00:33:16.740 --> 00:33:17.220 That's going to be awesome. 00:33:17.220 --> 00:33:17.740 All right. 00:33:17.740 --> 00:33:18.240 How about you? 00:33:19.080 --> 00:33:20.200 Do you have anything extra? 00:33:20.200 --> 00:33:21.520 Good lead in. 00:33:21.520 --> 00:33:27.340 So brand new course over at Talk Python training, Django getting started, which is awesome. 00:33:27.340 --> 00:33:29.420 This is put together by Chris Trudeau. 00:33:29.420 --> 00:33:32.960 And this is a six hour course on Django. 00:33:32.960 --> 00:33:35.180 And right now people hurry, hurry. 00:33:35.180 --> 00:33:39.020 There's an early bird discount to save 10% that you can get as well. 00:33:39.020 --> 00:33:40.740 So that just came out Wednesday. 00:33:40.740 --> 00:33:41.960 Wednesday is yesterday. 00:33:41.960 --> 00:33:43.720 So it came out yesterday, I think. 00:33:43.720 --> 00:33:45.520 That or the day before, very recently. 00:33:45.520 --> 00:33:48.840 Anyway, if you've been wanting to do getting started, 00:33:49.040 --> 00:33:52.120 if you want to get into Django, this gives our Django course is really good. 00:33:52.120 --> 00:33:55.880 If you've been dabbling, you're like, I really need to see how the pieces fit together better. 00:33:55.880 --> 00:33:57.120 Also, check it out. 00:33:57.120 --> 00:33:58.460 It's definitely good stuff. 00:33:58.460 --> 00:34:02.380 Django is one of the top two web frameworks these days still on Python. 00:34:02.380 --> 00:34:02.940 Yeah. 00:34:03.600 --> 00:34:06.860 Do you know how many courses you've got on the platform now? 00:34:06.860 --> 00:34:13.880 43 courses and about, that platform tells me, and 233 hours of content. 00:34:13.880 --> 00:34:17.460 So there's more than that in there, but a couple are not published yet. 00:34:17.460 --> 00:34:18.660 There's some exciting ones coming. 00:34:18.660 --> 00:34:19.180 Cool. 00:34:19.180 --> 00:34:19.680 Nice. 00:34:19.680 --> 00:34:20.080 Yeah. 00:34:20.080 --> 00:34:20.280 Sweet. 00:34:20.280 --> 00:34:20.460 Yeah. 00:34:20.800 --> 00:34:21.160 All right. 00:34:21.160 --> 00:34:22.920 Well, those are all the extras I have for now. 00:34:22.920 --> 00:34:24.220 I do have a joke for you, though. 00:34:24.220 --> 00:34:24.900 Oh, good. 00:34:24.900 --> 00:34:27.020 Are you a fan of The Lion King? 00:34:27.020 --> 00:34:28.200 You ever watched that show? 00:34:28.200 --> 00:34:28.940 The Lion King? 00:34:28.940 --> 00:34:29.980 The cartoon? 00:34:29.980 --> 00:34:30.680 Disney? 00:34:30.680 --> 00:34:31.360 It was a Disney? 00:34:31.360 --> 00:34:31.760 I don't know. 00:34:31.760 --> 00:34:32.640 I saw it. 00:34:32.640 --> 00:34:34.720 I don't know if I'd call me a fan, but sure. 00:34:34.720 --> 00:34:34.940 No. 00:34:34.940 --> 00:34:36.860 Did you enjoy watching it, I guess? 00:34:36.860 --> 00:34:37.240 Yeah. 00:34:37.240 --> 00:34:37.560 Yeah. 00:34:37.560 --> 00:34:37.760 Yeah. 00:34:37.760 --> 00:34:41.580 So I watched it with my kids and yeah, we enjoyed it as well. 00:34:41.580 --> 00:34:46.000 And so I don't even remember the name of the father. 00:34:46.000 --> 00:34:47.360 Remember the name of the father? 00:34:47.360 --> 00:34:49.060 The actual Lion King? 00:34:49.060 --> 00:34:49.780 No. 00:34:49.780 --> 00:34:51.060 Put me on the spot. 00:34:51.060 --> 00:34:52.400 Yeah, exactly. 00:34:52.400 --> 00:34:52.840 I don't either. 00:34:52.840 --> 00:34:58.180 But the little kid that was supposed to be, the kid lion who was supposed to be being groomed 00:34:58.180 --> 00:35:02.300 to be the king, is talking to his father and they're looking over the vast kingdom. 00:35:02.300 --> 00:35:03.760 This is Luxembourg. 00:35:04.180 --> 00:35:07.840 Every language that light touches has a garbage collector. 00:35:07.840 --> 00:35:12.480 And Symbol looks and goes, but what's that shadowy place over there? 00:35:12.480 --> 00:35:13.840 That's a C++. 00:35:13.840 --> 00:35:15.540 You must never go there. 00:35:15.540 --> 00:35:17.100 Yes. 00:35:17.100 --> 00:35:19.200 Sorry, C++, but yeah, that was fun. 00:35:19.200 --> 00:35:20.300 And Mufasa. 00:35:20.300 --> 00:35:22.040 Mufasa, yes. 00:35:22.040 --> 00:35:22.660 Thank you. 00:35:22.660 --> 00:35:23.500 Yes, you got it. 00:35:23.500 --> 00:35:25.340 Mufasa says, that's a C++. 00:35:25.340 --> 00:35:26.500 You must never go there. 00:35:26.500 --> 00:35:28.360 No, but you should. 00:35:28.360 --> 00:35:30.500 Don't take it too seriously. 00:35:30.500 --> 00:35:31.800 It's a joke, but it was fun. 00:35:31.800 --> 00:35:35.260 As a garbage collector. 00:35:35.260 --> 00:35:36.420 Yeah, I know. 00:35:36.420 --> 00:35:38.860 What's that shadowy place over there? 00:35:38.860 --> 00:35:40.880 You must never go there. 00:35:40.880 --> 00:35:42.840 What about Rust? 00:35:42.840 --> 00:35:44.260 What about Rust? 00:35:44.260 --> 00:35:45.200 Nice. 00:35:45.200 --> 00:35:48.460 I don't even know enough about Rust to make this part of the joke. 00:35:48.460 --> 00:35:50.720 Yeah. 00:35:50.720 --> 00:35:52.400 I'm busy learning Dart and Flutter. 00:35:52.400 --> 00:35:55.260 Maybe I don't have to learn Dart though, because I can do it in Python. 00:35:55.260 --> 00:35:56.080 I could just learn Flutter. 00:35:56.080 --> 00:35:56.520 We'll see. 00:35:56.820 --> 00:35:58.760 So that would be like, that is Rust. 00:35:58.760 --> 00:36:01.120 You can go there, but come back quickly. 00:36:01.120 --> 00:36:02.200 Exactly. 00:36:02.200 --> 00:36:04.100 Just short visits. 00:36:04.100 --> 00:36:04.840 Short visits. 00:36:04.840 --> 00:36:05.080 Short visits. 00:36:05.080 --> 00:36:05.540 Yeah. 00:36:05.540 --> 00:36:07.380 Just a fun show too. 00:36:07.380 --> 00:36:09.780 Well, thanks for having this great episode. 00:36:09.780 --> 00:36:11.140 Yeah, it's great to be back with you. 00:36:11.140 --> 00:36:11.640 Yeah. 00:36:11.640 --> 00:36:14.180 So, and I guess we'll talk next week. 00:36:14.180 --> 00:36:14.540 Yeah. 00:36:14.540 --> 00:36:15.060 You bet. 00:36:15.060 --> 00:36:15.740 See ya.