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.

