WEBVTT

00:00:00.001 --> 00:00:04.840
Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds.

00:00:04.840 --> 00:00:11.180
This is episode 291, recorded July 6, 2022, and I'm Brian Okken.

00:00:11.180 --> 00:00:12.340
Hey, I'm Michael Kennedy.

00:00:12.340 --> 00:00:14.260
Good to see you, Michael. It's been a while.

00:00:14.260 --> 00:00:16.520
Yeah, good to see you, Brian, as well. Fun as always.

00:00:16.520 --> 00:00:21.980
There's just a never-ending flow of fun stuff to talk about. I know we've got good stuff to share today, as always.

00:00:21.980 --> 00:00:24.120
Yes, we do. Why don't you kick us off?

00:00:24.120 --> 00:00:27.860
Licensing. Something everybody's super psyched about.

00:00:27.860 --> 00:00:36.640
But I think you'll find this project interesting, and I don't know how you'll receive it, but I was like, wait a minute, what? This is odd.

00:00:36.640 --> 00:00:46.340
So this project comes to us from Tom Nyhoff, and he sent this in and said, you know, it occurred to me that we have licenses for things like pytest.

00:00:46.340 --> 00:00:54.480
So I could go search for pytest, and over on GitHub, or my programming lens, over on GitHub, I could check this out.

00:00:54.480 --> 00:00:57.620
And what is the license? Well, it looks like the license is MIT.

00:00:57.980 --> 00:01:01.700
So if I want to use pytest, I'm buying into the MIT license, right?

00:01:01.700 --> 00:01:02.980
Yeah, kind of.

00:01:02.980 --> 00:01:04.140
Maybe. Sometimes.

00:01:04.140 --> 00:01:05.860
Only if you ship with it.

00:01:05.860 --> 00:01:06.400
So it's going to be able to put pytest.

00:01:06.400 --> 00:01:07.120
That's true.

00:01:07.120 --> 00:01:11.080
But, you know, there are libraries like Request or whatever that you might, you know, ship, right?

00:01:11.080 --> 00:01:11.340
Yeah.

00:01:11.340 --> 00:01:13.440
So I'll just put pytest in here and see what we get.

00:01:13.700 --> 00:01:20.580
So this project is called Python Project Insight, and it only has about 5,300 packages parsed in so far.

00:01:20.580 --> 00:01:25.800
But the idea is you can say, load the dependencies, and it'll show you the licenses.

00:01:26.460 --> 00:01:29.460
So for example, for pytest, we have the MIT license.

00:01:29.460 --> 00:01:36.500
But pytest depends upon packaging and import lib metadata, and Colorama, and PyParsing, and Adders, and typing extensions.

00:01:36.500 --> 00:01:39.400
Well, packaging has the Apache license.

00:01:39.400 --> 00:01:41.460
Colorama has the BSD license.

00:01:41.460 --> 00:01:44.600
Adders has MIT license.

00:01:44.600 --> 00:01:45.500
So does pytest.

00:01:45.700 --> 00:01:48.360
And then the Python Software Foundation has typing extensions.

00:01:48.360 --> 00:01:49.740
So I don't know.

00:01:49.740 --> 00:01:50.360
What do you think of that?

00:01:50.360 --> 00:01:51.340
It is interesting.

00:01:51.340 --> 00:01:53.380
And I don't know what to do with it.

00:01:53.380 --> 00:01:55.120
I don't either.

00:01:55.120 --> 00:01:55.820
I'm like, wait a minute.

00:01:55.820 --> 00:02:02.580
I have to kind of sort of consider the transit of closure of the dependencies for their licenses.

00:02:02.580 --> 00:02:06.760
And I had never really, I'm sure people are there, well, of course, Michael.

00:02:06.760 --> 00:02:07.980
Of course, that's how it works.

00:02:07.980 --> 00:02:09.600
But for me, I hadn't really thought about it.

00:02:09.600 --> 00:02:11.680
I look at the project or the library and it has this license.

00:02:12.060 --> 00:02:17.240
Like another one could be, you know, that you would build on before, more likely would be like requests.

00:02:17.240 --> 00:02:24.120
So if we load the dependencies for requests, you have Apache, BSC, MIT, and Mozilla split across that one project.

00:02:24.120 --> 00:02:27.220
So, yeah, I just think this is pretty wild.

00:02:27.220 --> 00:02:31.980
I'm pointing out that TensorFlow is one of the more wild ones.

00:02:31.980 --> 00:02:36.400
If you load up TensorFlow, there's just lots of different licenses here.

00:02:36.400 --> 00:02:39.240
Like sample the GitHub licensing options, basically.

00:02:39.760 --> 00:02:57.560
So if I was shipping a commercial project, a commercial product with Python that used a whole bunch of dependencies, I do know that this transitive closure stuff, the stuff that I'm actually shipping with, I really am supposed to list those and have those licenses listed in somewhere.

00:02:57.560 --> 00:03:02.980
Right, in a sense, because you are shipping the dependencies of a thing in order for that thing to work, right?

00:03:03.260 --> 00:03:09.280
Yeah, so you're at least saying, I'm using this, it's here, and here's the license for it.

00:03:09.280 --> 00:03:10.580
I think that's the case.

00:03:10.580 --> 00:03:11.620
I'm not a lawyer, of course.

00:03:11.620 --> 00:03:18.960
But there's a whole bunch of these tools, like pytest, for instance, that we use that we don't ship.

00:03:18.960 --> 00:03:20.780
Those are a different story.

00:03:20.780 --> 00:03:23.300
And that's kind of a different license thing.

00:03:23.600 --> 00:03:25.340
But I don't know about the packages.

00:03:25.340 --> 00:03:28.340
Are these like the packages that these are shipping?

00:03:28.340 --> 00:03:29.860
They're there.

00:03:29.860 --> 00:03:31.200
They're not really being sold.

00:03:31.200 --> 00:03:35.200
But do you have to list the licenses of the things that you're depending on?

00:03:35.200 --> 00:03:35.700
I don't know.

00:03:35.700 --> 00:03:37.000
I don't know either.

00:03:37.320 --> 00:03:40.040
I think maybe in some times it doesn't matter.

00:03:40.040 --> 00:03:46.160
But if it was GPL rather than LGPL, right, for example, that might be something you care about.

00:03:46.160 --> 00:03:46.920
You know, I don't know.

00:03:46.920 --> 00:03:56.720
I would love to hear people who really understand this super well, if they could like maybe tweet at us or comment on the YouTube stream or something like that about exactly what that means.

00:03:56.720 --> 00:04:00.200
But I do think it's pretty interesting information.

00:04:00.200 --> 00:04:07.820
Like mostly this shows the licenses, but it also shows the total size of installing the project and what libraries it depends upon.

00:04:07.820 --> 00:04:09.420
So you can kind of like poke around with that as well.

00:04:09.420 --> 00:04:19.300
That is that's actually pretty useful and interesting information as well that you don't really think about is how big of a download do I get if I put all these things, all these things together?

00:04:19.300 --> 00:04:20.220
So, yeah.

00:04:20.220 --> 00:04:20.800
Yeah.

00:04:20.800 --> 00:04:22.120
And you can pile them up.

00:04:22.120 --> 00:04:23.200
So you can say I'm using TensorFlow.

00:04:23.200 --> 00:04:26.020
I'm using SK Learn.

00:04:26.620 --> 00:04:29.440
I'm using Request or whatever.

00:04:29.440 --> 00:04:33.700
Then you can say like, OK, for those three, tell me about what the story is.

00:04:33.700 --> 00:04:34.260
You know what I mean?

00:04:34.260 --> 00:04:34.760
Yeah.

00:04:34.760 --> 00:04:36.340
And it gets a little more interesting still.

00:04:36.340 --> 00:04:38.600
I guess maybe that's not quite right.

00:04:38.600 --> 00:04:40.480
But that just comes with SciPy.

00:04:40.480 --> 00:04:41.440
But anyway, yeah.

00:04:41.440 --> 00:04:42.340
Something like that, right?

00:04:42.340 --> 00:04:42.840
Yeah.

00:04:42.840 --> 00:04:43.200
Yeah, neat.

00:04:43.200 --> 00:04:45.860
So anyway, thanks, Tom, for sending that in and sharing it with us.

00:04:45.860 --> 00:04:51.120
Well, I think I'll switch gears a little bit and talk about data classes.

00:04:51.120 --> 00:04:53.520
So I actually really like data classes.

00:04:53.520 --> 00:04:55.760
Have you used data classes much, Mike?

00:04:55.760 --> 00:04:56.400
Michael?

00:04:56.520 --> 00:05:00.120
Some, they definitely have some very neat properties.

00:05:00.120 --> 00:05:05.520
I find myself kind of when I'm on the edge of using a data class, I'm like, maybe Pydantic.

00:05:05.520 --> 00:05:07.680
But Frozen is a cool option.

00:05:07.680 --> 00:05:09.120
You can add slots.

00:05:09.120 --> 00:05:15.860
Slots makes so many things awesome in terms of lower memory usage, faster attribute access,

00:05:15.860 --> 00:05:16.700
all kinds of things.

00:05:16.700 --> 00:05:20.100
And if it's just slots equal true on the class definition, that's kind of nice.

00:05:20.440 --> 00:05:21.040
Yeah, it is.

00:05:21.040 --> 00:05:24.220
So Trey Hunter is a Python trainer.

00:05:24.220 --> 00:05:30.960
And he came up with this cool tool on his Python morsels site called the undata class.

00:05:30.960 --> 00:05:35.440
And it's actually also a library that he released, a little tool that's undata class.

00:05:35.880 --> 00:05:40.980
And the idea is he was thinking, like, what would be the equivalent of a data class?

00:05:40.980 --> 00:05:46.640
If you didn't write a data class, if you wanted to have the same sort of functionality, what would you do in a normal class?

00:05:46.640 --> 00:05:48.300
So he's got this cool tool down.

00:05:48.300 --> 00:05:58.580
And the example shows, yeah, it shows here slots, just a point with XYZ, all floats, and also shows frozen sets and slots.

00:05:58.580 --> 00:05:59.760
But I'm going to turn those off.

00:05:59.760 --> 00:06:03.380
And you just change the class and it changes the output.

00:06:03.380 --> 00:06:10.720
And he prints out what an equivalent class would be if you didn't use data classes.

00:06:10.720 --> 00:06:15.200
So actually, I'm not, and I tried to make sure I understood all of this.

00:06:15.200 --> 00:06:23.220
So one of the things that it's kind of neat that it just, it's part of a learning tool that he's got that it shows you, you know, what you get with data classes.

00:06:23.220 --> 00:06:26.320
But there's not a lot of description around, like, what all this means.

00:06:26.320 --> 00:06:30.140
So this is sort of a fun thing to help you look up stuff, I guess.

00:06:30.140 --> 00:06:38.220
So right off the bat, if we just have XYZ, you have a __init__() that takes XYZ as input values and assigns them.

00:06:38.220 --> 00:06:40.960
And it comes with a nice wrapper class.

00:06:41.160 --> 00:06:45.480
And then an EQ, a dunder EQ, which is for equality.

00:06:45.480 --> 00:07:03.580
And one of the things I wanted to look up was to make sure I understood is what it does is it says if the other thing, if I'm getting compared with something else, if that other thing is also my same type in this case point, then you can do the equality comparison.

00:07:03.760 --> 00:07:05.800
Otherwise, the raise and not implemented.

00:07:05.800 --> 00:07:09.060
And that's just kind of a convention because Python.

00:07:09.060 --> 00:07:18.980
And then what happens is Python will try to call EQ on the other thing of like reverse the order and stuff because it's kind of how Python works.

00:07:18.980 --> 00:07:28.600
But it's one of those hidden sort of things is you need to kind of know that if you don't know what to do in an EQ class or an EQ function, raise not implemented.

00:07:28.600 --> 00:07:30.300
And then Python goes from there.

00:07:30.300 --> 00:07:39.460
And then resetting, though, if you if you give it slots, all the slots does is add slots to it.

00:07:39.620 --> 00:07:41.480
And that's it, which is kind of cool.

00:07:41.480 --> 00:07:42.540
And what slots does.

00:07:42.540 --> 00:07:43.100
Yeah.

00:07:43.100 --> 00:07:46.420
And what slots does is it makes it so that you can't add later.

00:07:46.420 --> 00:07:51.120
So if you can't add a W attribute later to your point.

00:07:51.120 --> 00:07:55.220
But then if you do frozen, it does a whole bunch of stuff.

00:07:55.220 --> 00:07:57.760
Oh, you get a whole bunch more dunder methods.

00:07:57.880 --> 00:08:04.420
But mostly these are just raising raising exceptions so that, you know, if you try to change it, it raises.

00:08:04.420 --> 00:08:06.540
So anyway, this is kind of cool.

00:08:06.540 --> 00:08:06.980
Yeah.

00:08:06.980 --> 00:08:11.520
Do you see the dunder in it, the constructor implementation when you add frozen?

00:08:11.520 --> 00:08:13.480
It doesn't say self dot X.

00:08:13.480 --> 00:08:17.060
It's a it calls set adder like behind the scenes.

00:08:17.060 --> 00:08:22.640
And then it implements set adder and del adder and raises exceptions if you try to mess with it.

00:08:22.640 --> 00:08:23.180
Pretty wild.

00:08:23.180 --> 00:08:24.020
That's cool.

00:08:25.180 --> 00:08:31.860
We're also going to link to a couple a couple articles that that Trey wrote about.

00:08:31.860 --> 00:08:34.340
He wrote about this, about how he wrote this.

00:08:34.340 --> 00:08:41.500
And one of the things I'm bringing this up partly because I like data classes and it's kind of cool for people to learn what they are.

00:08:41.500 --> 00:08:55.100
But in his developing this, he says he came up with having a great use case for the match case, new match case blocks in Python using Sentinel objects, which I'm not sure what he's talking about there.

00:08:55.100 --> 00:08:55.900
So I'll take that.

00:08:55.900 --> 00:08:56.560
Look at that.

00:08:56.560 --> 00:08:59.840
Using text wrap ddent, which I love.

00:08:59.840 --> 00:09:03.260
And it's nice to see somebody else using that slice.

00:09:03.260 --> 00:09:04.180
And then an AST.

00:09:04.180 --> 00:09:05.620
So he's using AST in here.

00:09:05.620 --> 00:09:08.000
So it's kind of a cool, fun example of using that.

00:09:08.000 --> 00:09:08.900
Anyway.

00:09:08.900 --> 00:09:09.400
Cool.

00:09:09.400 --> 00:09:09.620
Yeah.

00:09:09.620 --> 00:09:10.260
A lot of cool stuff.

00:09:10.260 --> 00:09:11.940
And actually, go back to the first one.

00:09:11.940 --> 00:09:13.200
The first tab you got there.

00:09:13.200 --> 00:09:13.680
Yeah.

00:09:13.960 --> 00:09:19.760
One of the things I appreciate from this example is you just say class point, X colon float, Y colon float, Z colon float.

00:09:19.760 --> 00:09:20.300
Yeah.

00:09:20.300 --> 00:09:21.660
And put the data class attribute on it.

00:09:21.660 --> 00:09:23.180
Look how much it's doing for you, right?

00:09:23.180 --> 00:09:30.020
Like it's not just the typed values, but it's protecting the read-write ability, making it read-only.

00:09:30.020 --> 00:09:32.060
It's getting a wrapper definition.

00:09:32.060 --> 00:09:37.240
It's getting a hash ability, equality, not equality effectively by.

00:09:37.240 --> 00:09:37.780
All right.

00:09:37.780 --> 00:09:39.520
There's a lot of cool things it's adding for you there.

00:09:39.520 --> 00:09:39.960
Yeah.

00:09:40.040 --> 00:09:40.600
And he's-

00:09:40.600 --> 00:09:42.060
He can appreciate the data class.

00:09:42.060 --> 00:09:51.860
He's suggesting doing other stuff like using keyword-only and fields, different fields to see if you can change how it works.

00:09:51.860 --> 00:09:53.660
But yeah, I'll have to play with this more.

00:09:53.660 --> 00:10:00.580
And a reminder to everybody that is like data classes are almost enough, but you need more.

00:10:00.580 --> 00:10:04.680
We'll also look at attrs because attrs is kind of a superset of data classes.

00:10:04.680 --> 00:10:05.260
Right.

00:10:05.260 --> 00:10:05.720
Yeah.

00:10:05.720 --> 00:10:06.300
Fantastic.

00:10:06.300 --> 00:10:06.840
That's great.

00:10:06.840 --> 00:10:07.380
Cool.

00:10:07.380 --> 00:10:09.080
All right, Brian, the next one I got here.

00:10:09.500 --> 00:10:10.200
This one's for you.

00:10:10.200 --> 00:10:10.640
Okay.

00:10:10.640 --> 00:10:11.240
All right.

00:10:11.240 --> 00:10:11.860
All right.

00:10:11.860 --> 00:10:13.480
So let's go back.

00:10:13.480 --> 00:10:17.040
We'll take a two-step process to approach this.

00:10:17.040 --> 00:10:18.600
Did you ever use Lynx?

00:10:18.600 --> 00:10:19.840
L-Y-N-X?

00:10:19.840 --> 00:10:22.560
Yeah, like a long, long time ago.

00:10:22.560 --> 00:10:24.620
I remember SSH.

00:10:24.620 --> 00:10:24.920
I know.

00:10:24.920 --> 00:10:31.380
I think I telneted into the mainframes back of the university and I'd run L-Y-N-X.

00:10:31.380 --> 00:10:33.600
This predated the graphical web.

00:10:33.600 --> 00:10:35.480
I mean, it's insane, right?

00:10:35.480 --> 00:10:38.860
So, but it's a browser that is pure text in the terminal.

00:10:38.860 --> 00:10:42.780
Today we have all these fancy browsers, but one of the things you had a lot of was like

00:10:42.780 --> 00:10:45.980
keyboard shortcuts and other types of things you could do, right?

00:10:45.980 --> 00:10:46.480
Yeah.

00:10:46.480 --> 00:10:51.180
Well, now that it's 30 years later, what if we could go back to a time a little bit like

00:10:51.180 --> 00:10:51.420
that?

00:10:51.660 --> 00:10:56.840
So I want to introduce you to the Qt browser, Q-U-T-E browser.

00:10:56.840 --> 00:10:57.440
Okay?

00:10:57.440 --> 00:10:57.980
Okay.

00:10:57.980 --> 00:10:59.040
So what is this?

00:10:59.040 --> 00:11:05.640
The Qt browser is also like kind of in need of a homepage refresh, but it's a keyboard focused

00:11:05.640 --> 00:11:07.540
browser with a minimal GUI.

00:11:07.540 --> 00:11:10.220
And what's interesting is it's built with Python.

00:11:10.220 --> 00:11:10.680
Okay.

00:11:10.780 --> 00:11:13.480
So it's a full web browser built with Python.

00:11:13.480 --> 00:11:19.440
And it's kind of like a, like a Vimper or one of these other ones that lets you do Vim

00:11:19.440 --> 00:11:21.520
like control and behavior of it.

00:11:21.520 --> 00:11:27.060
A little bit like, a little bit like links, but it's actual, actually Chrome more or less,

00:11:27.060 --> 00:11:28.640
at least the Chrome runtime.

00:11:28.640 --> 00:11:31.100
So this one was sent in.

00:11:31.100 --> 00:11:33.420
I'm going to make sure I give him credit for giving a shout out.

00:11:33.420 --> 00:11:35.480
This was sent in to us by Martin Boris.

00:11:35.480 --> 00:11:38.020
And it's, it's pretty neat.

00:11:38.080 --> 00:11:41.900
So it's a browser, let me switch up my screen share just for you for a sec.

00:11:41.900 --> 00:11:43.180
Stop.

00:11:43.180 --> 00:11:45.640
And then I'm going to add the Qt browser.

00:11:45.640 --> 00:11:46.360
You ready?

00:11:46.360 --> 00:11:47.180
Where is it?

00:11:47.180 --> 00:11:47.520
There.

00:11:47.520 --> 00:11:48.120
All right.

00:11:48.120 --> 00:11:49.900
So look at this bad boy.

00:11:49.900 --> 00:11:51.840
So this is the browser.

00:11:51.840 --> 00:11:53.120
And how do I go to places?

00:11:53.120 --> 00:11:56.340
Well, I can click on things like here's a link I can click on.

00:11:56.340 --> 00:12:01.280
But if I want to go somewhere, I press O and it pulls up a place I can open.

00:12:01.280 --> 00:12:01.700
Look at this.

00:12:01.700 --> 00:12:02.460
I got my history.

00:12:02.460 --> 00:12:03.100
Oh, that's pretty cool.

00:12:03.100 --> 00:12:05.660
I want to go to like, I'll go to talk Python.

00:12:06.660 --> 00:12:10.540
How do I, if I want to do a command, I hit colon and here's all my commands.

00:12:10.540 --> 00:12:14.300
I've like my tab, I give focus and control and so on.

00:12:14.300 --> 00:12:16.440
Over here and it's type F.

00:12:16.440 --> 00:12:21.380
So if I want to, if I want to navigate, for example, I'm here on the talk Python page.

00:12:21.380 --> 00:12:26.540
What if I want to go to courses, I type F and then everything, see how everything gets a letter above it.

00:12:26.540 --> 00:12:27.080
That's pretty great.

00:12:27.080 --> 00:12:27.500
Yeah.

00:12:27.680 --> 00:12:28.760
L, D, D, G.

00:12:28.760 --> 00:12:33.780
If I want to go to D, I just press D and then we're off on the talk by then training site and so on.

00:12:33.780 --> 00:12:40.880
So I could open, I could say open and I could search for pytest and I'll pull up my tests and so on.

00:12:40.880 --> 00:12:42.580
And I can do a new tab.

00:12:42.580 --> 00:12:44.180
I got to remember how to do that.

00:12:44.180 --> 00:12:45.380
Yeah.

00:12:45.380 --> 00:12:46.320
We're going to say tab clone.

00:12:46.740 --> 00:12:47.740
And I come over here.

00:12:47.740 --> 00:12:49.980
I know there's a bunch of good commands that I'm not following.

00:12:49.980 --> 00:12:52.480
Like very much like if I was actually using Vim.

00:12:52.480 --> 00:12:53.520
Yeah.

00:12:53.520 --> 00:12:55.960
If I could search for pytest and book, I could come over here, right?

00:12:55.960 --> 00:12:56.640
Like that.

00:12:56.640 --> 00:13:00.180
And I can hit, is it control or Windows control?

00:13:00.180 --> 00:13:01.340
Ooh, that's a good book.

00:13:01.340 --> 00:13:02.380
Yeah, I heard that's a good book.

00:13:02.380 --> 00:13:05.760
So I can like cycle through my tabs, see how minimal my tabs are and stuff right there.

00:13:05.760 --> 00:13:06.380
Oh yeah.

00:13:06.380 --> 00:13:06.920
It's on the bottom.

00:13:06.920 --> 00:13:08.120
It's got all these little commands.

00:13:08.120 --> 00:13:10.300
So anyway, and I can type colon Q.

00:13:10.300 --> 00:13:11.160
Boom, we're out.

00:13:11.160 --> 00:13:11.780
Nice.

00:13:11.780 --> 00:13:12.920
What do you think of this?

00:13:12.920 --> 00:13:13.400
Yeah.

00:13:13.400 --> 00:13:14.020
What do you think of that?

00:13:14.240 --> 00:13:15.820
I actually love the cute browser.

00:13:15.820 --> 00:13:22.640
I haven't used it much, but I definitely know about it because the Florian Bruin who started

00:13:22.640 --> 00:13:29.920
the browser, he's a pytest contributor and also one of the technical reviewers for the

00:13:29.920 --> 00:13:30.460
pytest book.

00:13:30.460 --> 00:13:31.760
So really cool guy.

00:13:31.760 --> 00:13:36.180
But I love the idea of being able to just use a browser with a keyboard and not have to touch

00:13:36.180 --> 00:13:36.860
the mouse at all.

00:13:36.860 --> 00:13:39.640
That's like, that's next level.

00:13:39.640 --> 00:13:40.460
It's pretty neat.

00:13:40.460 --> 00:13:40.900
Yeah.

00:13:40.900 --> 00:13:42.280
Yeah.

00:13:42.280 --> 00:13:42.720
Let's see.

00:13:42.720 --> 00:13:44.500
Out in the audience, Kim Van Wijk.

00:13:44.500 --> 00:13:44.860
Hey, Kim.

00:13:44.860 --> 00:13:48.120
Says, I resigned myself to using a mouse more than I want to.

00:13:48.120 --> 00:13:49.800
Cute browser may be the way to go.

00:13:49.800 --> 00:13:50.500
Thanks to the tip.

00:13:50.500 --> 00:13:50.840
Awesome.

00:13:50.840 --> 00:13:51.460
Yeah.

00:13:51.460 --> 00:13:53.920
And Alvaro says, are those VS Code shortcuts?

00:13:53.920 --> 00:13:57.460
I suppose only if you have the Vim binding set in VS Code.

00:13:57.460 --> 00:13:59.040
But then I sort of, yes.

00:13:59.040 --> 00:14:00.980
Well, of course you do.

00:14:00.980 --> 00:14:01.840
Why wouldn't you?

00:14:01.840 --> 00:14:04.120
What are you, a monster?

00:14:04.120 --> 00:14:07.920
Can you even do Emacs bindings?

00:14:07.920 --> 00:14:09.300
I don't know.

00:14:09.300 --> 00:14:11.640
You could do non-Vim bindings.

00:14:11.640 --> 00:14:12.000
Yeah.

00:14:12.000 --> 00:14:12.520
Right.

00:14:12.520 --> 00:14:14.500
But then people would look down on you.

00:14:14.500 --> 00:14:14.920
Right, Brian?

00:14:14.920 --> 00:14:17.040
But I don't do Vim stuff in mine.

00:14:17.040 --> 00:14:18.100
I know that you probably do, though.

00:14:18.100 --> 00:14:19.660
Yeah.

00:14:19.660 --> 00:14:22.620
I use Vim everywhere, especially in VS Code.

00:14:22.620 --> 00:14:24.020
So, nice.

00:14:24.020 --> 00:14:24.740
Nice.

00:14:24.740 --> 00:14:26.860
But I think people should check it out.

00:14:26.860 --> 00:14:27.900
It's kind of a cool project.

00:14:27.900 --> 00:14:33.680
And also, it helped push forward some of the, some pytest things.

00:14:33.680 --> 00:14:35.580
We got some new features because of this.

00:14:35.580 --> 00:14:35.980
It's cool.

00:14:35.980 --> 00:14:36.460
Yeah.

00:14:36.740 --> 00:14:37.200
Oh, that's great.

00:14:37.200 --> 00:14:39.600
I installed it with Homebrew.

00:14:39.600 --> 00:14:40.900
So, that was easy to install.

00:14:40.900 --> 00:14:42.520
You can install it with apt on Linux.

00:14:42.520 --> 00:14:43.860
I'm not sure about Windows.

00:14:43.860 --> 00:14:45.420
But they've got a quick start guide.

00:14:45.420 --> 00:14:48.960
So, you can follow along to see like, you know, what, what you might want to do.

00:14:48.960 --> 00:14:50.580
Like, it's, it's not super obvious.

00:14:50.960 --> 00:14:56.140
No, that cheat sheet is, I have an iChart key binding.

00:14:56.140 --> 00:14:57.600
It's a bit of an iChart.

00:14:57.600 --> 00:14:59.300
I suspect you can zoom it.

00:14:59.300 --> 00:15:00.280
There you go.

00:15:00.280 --> 00:15:01.080
It's still small.

00:15:01.080 --> 00:15:02.780
It's still small.

00:15:02.780 --> 00:15:04.640
But, yeah.

00:15:04.640 --> 00:15:11.180
I do like the navigation, pressing like F and then just a letter to navigate instead of using your mouse to follow the links.

00:15:11.180 --> 00:15:11.840
That's pretty cool.

00:15:11.840 --> 00:15:21.200
Do you remember those, like, those templates that people used to have, like, back in the day for, like, in, like, Office tools where they would overlay.

00:15:21.200 --> 00:15:23.720
You would put them, it was actually an overlay on your keyboard.

00:15:23.720 --> 00:15:24.060
Yeah.

00:15:24.060 --> 00:15:30.460
It would go over the, like, the function keys to, so that you could remember which functions did what during what application.

00:15:30.460 --> 00:15:35.720
And if you switch to Word, you put a different, or probably WordPerfect at the time, you put a different template over it.

00:15:35.720 --> 00:15:36.440
And, yeah.

00:15:36.440 --> 00:15:36.940
Yeah.

00:15:36.940 --> 00:15:38.260
I'm going to use Lotus 1, 2, 3.

00:15:38.260 --> 00:15:39.840
Give me the function key overlay.

00:15:39.840 --> 00:15:40.560
Yeah.

00:15:40.560 --> 00:15:40.900
Yeah.

00:15:40.900 --> 00:15:41.420
Okay.

00:15:42.120 --> 00:15:43.100
I'm just showing.

00:15:43.100 --> 00:15:43.620
Yeah, it's a little like that.

00:15:43.620 --> 00:15:43.980
It is.

00:15:43.980 --> 00:15:45.320
Showing how old I am.

00:15:45.320 --> 00:15:47.020
So, let's talk about something new.

00:15:47.020 --> 00:15:48.520
I'm sure they still teach that in college.

00:15:48.520 --> 00:15:49.140
Yeah.

00:15:49.140 --> 00:15:50.360
No, they don't.

00:15:50.360 --> 00:15:53.080
Although, in college, I had to teach.

00:15:53.080 --> 00:15:58.360
I was a TA for, like, a computers 101 class during grad school.

00:15:58.360 --> 00:16:00.900
And links was one of the things we had to teach.

00:16:00.900 --> 00:16:03.020
And I was like, nobody's going to use this.

00:16:03.020 --> 00:16:03.360
Yeah.

00:16:03.360 --> 00:16:05.160
But it was part of the curriculum.

00:16:05.160 --> 00:16:06.040
Yeah.

00:16:06.040 --> 00:16:07.240
That's awesome.

00:16:07.240 --> 00:16:07.860
Anyway.

00:16:07.860 --> 00:16:10.900
So, let's switch to something new, like, async.

00:16:11.200 --> 00:16:15.840
So, I think we've talked about court probably several times.

00:16:15.840 --> 00:16:20.300
And court is a, it's like Flask, but it's async.

00:16:20.720 --> 00:16:29.060
It actually is the, does the entire, it supports the Flask API, or I think, and sort of looks

00:16:29.060 --> 00:16:30.660
the same, but it's async instead.

00:16:30.660 --> 00:16:31.460
But there's a problem.

00:16:31.460 --> 00:16:32.840
It's super close.

00:16:32.840 --> 00:16:36.780
You can basically, everywhere you have the word Flask, if you replace it with the word

00:16:36.780 --> 00:16:38.480
court, it more or less works.

00:16:38.480 --> 00:16:41.740
So, like, import lowercase flask.

00:16:41.740 --> 00:16:42.980
You import lowercase court.

00:16:42.980 --> 00:16:47.340
If you create an object, capital F Flask, you use capital court, and then it lets you do async,

00:16:47.340 --> 00:16:47.660
basically.

00:16:47.660 --> 00:16:48.180
Cool.

00:16:48.180 --> 00:16:51.020
But there's an ecosystem around both of them now.

00:16:51.020 --> 00:16:53.920
So, there are extensions to Flask.

00:16:53.920 --> 00:16:55.520
Some of them work on court.

00:16:55.520 --> 00:16:57.020
There's extensions to court.

00:16:57.160 --> 00:16:59.480
I don't know if any of those work on Flask.

00:16:59.480 --> 00:17:04.800
But the people behind both of them kind of are supportive of the whole thing.

00:17:04.800 --> 00:17:10.060
And so, court is actually now part of the pallets project, is the big news.

00:17:10.720 --> 00:17:17.900
And pallets is the project that includes Flask and a whole bunch of other stuff.

00:17:17.900 --> 00:17:25.480
But because of this, it will help maybe the maintainers kind of work together a little bit

00:17:25.480 --> 00:17:28.400
better and smoother to iron this out.

00:17:28.400 --> 00:17:35.260
So, the big difference, of course, is that Flask has a whiskey server behind it.

00:17:35.260 --> 00:17:35.980
Server is the right word?

00:17:35.980 --> 00:17:39.900
And court is ASCII.

00:17:40.580 --> 00:17:41.220
So, asynchronous.

00:17:41.220 --> 00:17:45.060
But the, it's, so this is cool.

00:17:45.060 --> 00:17:47.040
Well, why do we care a little bit?

00:17:47.040 --> 00:17:50.860
Is that it used to be that really you had to do async.

00:17:50.860 --> 00:17:52.640
If you wanted async, you had to do court.

00:17:52.640 --> 00:18:00.640
But now Flask, as a Flask 2.0, you do have some async capabilities, but it's still using

00:18:00.640 --> 00:18:02.880
a single-threaded server.

00:18:02.880 --> 00:18:04.740
So, there are some limitations.

00:18:04.740 --> 00:18:08.120
So, kind of interesting to read about this.

00:18:08.120 --> 00:18:10.380
There is an async and await.

00:18:10.440 --> 00:18:16.700
page on the Flask website that talks about really what the trade-offs are, what the performance

00:18:16.700 --> 00:18:22.640
and the background tasks and how to do that within, without shifting to court.

00:18:22.720 --> 00:18:27.000
But then also talks about, at some point, you might want to just switch to court instead.

00:18:28.680 --> 00:18:36.420
Along this line is, I was thinking about this partly while I was looking at this other article

00:18:36.420 --> 00:18:42.700
from Steve Pate that called, should you use async on your next Python web application?

00:18:42.700 --> 00:18:47.420
Which I was, I wanted to bring this up because I was curious about what your take on it was.

00:18:47.780 --> 00:18:51.660
The first part is, it's a really nice history.

00:18:51.660 --> 00:18:57.600
It talks about the history of web server interfaces with Python, with the timelines and Whiskey and ASCII.

00:18:58.560 --> 00:19:08.800
And then how ASCII.io came into play and how UVicorn is popular and Unicorn.

00:19:08.800 --> 00:19:11.100
I don't know how to say that.

00:19:11.760 --> 00:19:15.640
I'm pretty sure it's Gunicorn because it's short for green unicorn.

00:19:15.640 --> 00:19:16.200
Okay.

00:19:16.200 --> 00:19:17.980
So the last bit should still be pronounced unicorn.

00:19:17.980 --> 00:19:18.940
So I'm going to go with G.

00:19:18.940 --> 00:19:19.520
Okay.

00:19:19.520 --> 00:19:24.800
And then there's Hypercorn, which is the asynchronous web server that's similar.

00:19:25.600 --> 00:19:30.780
Anyway, so it talks about this, but then at the end, the conclusion, it talks about all the different frameworks.

00:19:30.780 --> 00:19:36.020
The conclusion is, most people don't need async on their web server.

00:19:36.020 --> 00:19:42.000
And I was curious what your reaction to this conclusion is.

00:19:42.000 --> 00:19:45.340
I have some thoughts, but let me pull up some first.

00:19:45.340 --> 00:19:45.580
Okay.

00:19:45.580 --> 00:19:46.880
So here's my thought.

00:19:46.880 --> 00:19:47.680
It depends.

00:19:47.680 --> 00:19:51.400
It depends on how far you need to push it towards the edge.

00:19:51.400 --> 00:19:57.500
I was surprised how far you can get without async in terms of concurrency.

00:19:57.500 --> 00:20:00.980
So I recently did an in-person class.

00:20:00.980 --> 00:20:05.480
Imagine that over Zoom, but live in person.

00:20:05.480 --> 00:20:07.020
I actually have some more to say about that.

00:20:07.020 --> 00:20:07.500
It's kind of related.

00:20:07.500 --> 00:20:11.200
But anyway, I just did a course with some folks who are doing FastAPI.

00:20:11.200 --> 00:20:17.860
And they said, look, this async stuff that we're doing adds some complexity to the way that we got our right code.

00:20:17.860 --> 00:20:19.840
We're not sure whether or not there's a trade-off.

00:20:19.840 --> 00:20:32.660
So what we did is we actually ended up writing a FastAPI app with using the sync and the async version of SQLAlchemy, and then using async and an async version of FastAPI endpoints.

00:20:32.660 --> 00:20:33.140
Okay.

00:20:33.140 --> 00:20:33.600
Okay.

00:20:33.600 --> 00:20:42.880
With the database that we had as the backend, and the database was not the limiting factor because it was at like 10% CPU while this was happening.

00:20:42.940 --> 00:20:43.520
It was just chilling.

00:20:43.520 --> 00:20:43.960
Yeah.

00:20:43.960 --> 00:20:51.740
But with a real database, Postgres as the backend, what we found was we could do, I can remember this right.

00:20:51.740 --> 00:20:52.480
Oh boy.

00:20:52.480 --> 00:20:55.940
I'll give you, I can certainly give you the relative bit.

00:20:56.140 --> 00:21:00.460
So with the synchronous version, we got way more scalability than we thought.

00:21:00.460 --> 00:21:05.900
So it was like 75% performance of the async version.

00:21:05.900 --> 00:21:06.420
Okay.

00:21:06.420 --> 00:21:11.760
So that seems way higher because the database had, like most of the things we were doing is just waiting on the database.

00:21:11.900 --> 00:21:25.160
But because we were running in G Unicorn with UVicorn workers, I was really just in G Unicorn with threads, you know, Python doesn't do threading well, except when it's listening on a network socket or doing a few other things that will release the GIL.

00:21:25.160 --> 00:21:25.960
And guess what?

00:21:25.960 --> 00:21:27.900
When you're talking to the database, you're listening to a network socket.

00:21:28.020 --> 00:21:30.840
So there's all these points that naturally free up the threading.

00:21:30.840 --> 00:21:39.620
And actually got us like 75% of the way there, but we still got 25 to 30% more performance out of the async version.

00:21:39.620 --> 00:21:45.860
And it was like, I think it was five worker processes running on my eight core machine, talking to Postgres.

00:21:45.860 --> 00:21:56.500
And we were getting something like, you know, like 2000 requests per second versus 1500 a second, or maybe it was 1000 and 1500, something like that was a lot of requests per second.

00:21:56.500 --> 00:22:00.660
But we did get more performance out of the async version.

00:22:00.660 --> 00:22:06.140
So my depends is like that last 25, are you like that close to your performance?

00:22:06.140 --> 00:22:10.600
I would say 95% of the web apps are not maxed, right?

00:22:10.600 --> 00:22:13.580
They're not maxed out with like multiple servers trying to deal with it.

00:22:13.580 --> 00:22:19.600
95% of servers are doing important work, but they're probably still have a lot of capacity left.

00:22:19.600 --> 00:22:20.840
So it's like, it depends.

00:22:20.840 --> 00:22:23.960
Are they like, do you need that last 25% or does it not really matter?

00:22:23.960 --> 00:22:24.620
Yeah.

00:22:24.620 --> 00:22:25.180
Yeah.

00:22:25.180 --> 00:22:27.160
And also like, those are my thoughts.

00:22:27.160 --> 00:22:32.520
What's the load like on your typical, I mean, what are your levels anyway?

00:22:32.520 --> 00:22:32.920
Right.

00:22:32.920 --> 00:22:41.120
So if you, if you already have, like for instance, if you already have an application running, you can measure it and see, see what your load is looking like.

00:22:41.120 --> 00:22:42.980
And how many people you have.

00:22:43.080 --> 00:22:47.420
And then if you, if you think, oh, I might, I might increase my, what if we double?

00:22:47.420 --> 00:22:52.080
Then you can kind of guess what your load is going to look like if you double and stuff.

00:22:52.080 --> 00:22:53.160
So interesting.

00:22:53.160 --> 00:22:54.060
Yeah.

00:22:54.060 --> 00:23:02.800
I recommend people check out this locus thing because it's so easy to say a typical user clicks on the page between five and 15 seconds.

00:23:02.800 --> 00:23:03.800
They might go log in.

00:23:03.800 --> 00:23:04.800
They might go log in some of the time.

00:23:04.800 --> 00:23:06.640
They might go hit the homepage.

00:23:06.640 --> 00:23:07.580
They might hit the about.

00:23:07.580 --> 00:23:10.440
And then you can say, I would like to see how many users I can take.

00:23:10.800 --> 00:23:16.560
And if, if you're 10 X, what you need, you know, it doesn't matter whether you use async or not, but there is a performance benefit.

00:23:16.560 --> 00:23:18.940
It's just not as massive as it might sound.

00:23:18.940 --> 00:23:27.460
The, the other bit that I want to like point out is the one, one statement that like depends on what you're using.

00:23:27.460 --> 00:23:41.300
Also like I can't find the bit here, but it, he was talking about how one application he had, he was thinking about, oh, I might, I might do a async except for he was using a payment gateway that didn't have an async version.

00:23:41.300 --> 00:23:44.120
So he had to use a synchronous for that.

00:23:44.120 --> 00:23:48.700
And since synchronous somewhere you kind of have, is this true?

00:23:48.700 --> 00:23:52.140
If it's synchronous somewhere, you have to be synchronous everywhere or that not really true.

00:23:52.140 --> 00:23:56.580
You know, if, sorry, say that if it's sync, async, it's async everywhere or sync.

00:23:56.580 --> 00:23:57.240
It's sync everywhere.

00:23:57.780 --> 00:23:59.680
Either one is either one of those true.

00:23:59.680 --> 00:24:11.680
If I, like, if I have a, if I've got an application and, and I do need to hit a gateway that's synchronous, do I need to, if I isolate it, I guess I can probably do asynchronous and hide it that way.

00:24:11.680 --> 00:24:17.520
But yeah, I mean, you're, you just don't get as good a scalability there and you kind of block up the processing.

00:24:17.520 --> 00:24:25.780
If you do the sync for the async one, you can do like a wrapper where you say like, we're going to do some async work, but I'm just going to call that and block.

00:24:25.780 --> 00:24:28.920
Because all the other stuff above it doesn't want to deal with being async.

00:24:28.920 --> 00:24:29.420
Yeah.

00:24:29.520 --> 00:24:34.240
So it's easier to go from sync to async to like have part of it be async.

00:24:34.240 --> 00:24:36.740
The other way around is a little more tricky.

00:24:36.740 --> 00:24:37.620
It can mess it up a bit.

00:24:37.620 --> 00:24:38.560
Okay, cool.

00:24:38.560 --> 00:24:39.000
Yeah.

00:24:39.000 --> 00:24:39.480
Nice.

00:24:39.480 --> 00:24:40.800
Interesting conversation.

00:24:40.800 --> 00:24:41.440
Thanks a lot.

00:24:41.880 --> 00:24:42.200
Absolutely.

00:24:42.200 --> 00:24:43.100
It sure is.

00:24:43.100 --> 00:24:43.740
Is that it?

00:24:43.740 --> 00:24:44.700
Is that all of our items?

00:24:44.700 --> 00:24:45.580
Are we?

00:24:45.580 --> 00:24:48.060
I think that all of our items?

00:24:48.060 --> 00:24:48.680
I think so.

00:24:48.680 --> 00:24:49.220
Yeah.

00:24:49.220 --> 00:24:49.420
Yeah.

00:24:49.420 --> 00:24:49.600
What?

00:24:49.600 --> 00:24:50.820
You got any extras for us?

00:24:50.820 --> 00:24:52.180
I don't.

00:24:52.180 --> 00:24:52.680
No.

00:24:52.680 --> 00:24:52.860
Okay.

00:24:52.860 --> 00:24:53.840
I have some.

00:24:53.840 --> 00:24:55.620
Let me pull them up here.

00:24:55.620 --> 00:24:56.220
Locus.

00:24:56.220 --> 00:24:57.100
Look, let me tell you about it now.

00:24:57.100 --> 00:24:57.420
It's great.

00:24:57.660 --> 00:24:57.860
All right.

00:24:57.860 --> 00:24:59.760
No, I have three things I want to tell people about.

00:24:59.760 --> 00:25:06.120
Number one is I did a talk at Python Web Conference, the HTMX and Flask one that I've done in some

00:25:06.120 --> 00:25:12.060
other places, but that was a fun talk, like a 45 minute Flask plus HTMX goodness there.

00:25:12.280 --> 00:25:19.160
And so that video, along with all the other Python Web Conf 2022 talks are now on YouTube.

00:25:19.160 --> 00:25:20.280
So people can check that out.

00:25:20.280 --> 00:25:20.740
Cool.

00:25:20.740 --> 00:25:28.080
Did you know that the Python Web Conference had five days and I think it was like four or five tracks all day.

00:25:28.080 --> 00:25:29.400
So there are a ton of videos.

00:25:29.400 --> 00:25:32.100
There's like 150 videos or something on there.

00:25:32.100 --> 00:25:33.860
I mean, look at this scroll bar here.

00:25:33.860 --> 00:25:37.080
It's probably going to like page as I get to the bottom too.

00:25:37.080 --> 00:25:37.600
Yep.

00:25:37.600 --> 00:25:39.040
Look at that.

00:25:39.040 --> 00:25:43.620
So there was a lot of talks that people can come check out if they're interested in that.

00:25:43.620 --> 00:25:44.440
That's pretty cool.

00:25:44.440 --> 00:25:45.960
One of them being HTMX that I did.

00:25:45.960 --> 00:25:46.460
Yeah.

00:25:46.460 --> 00:25:47.780
I want to watch your talk.

00:25:47.780 --> 00:25:49.100
You've given that a couple of times, haven't you?

00:25:49.100 --> 00:25:49.520
Yeah.

00:25:49.520 --> 00:25:50.500
Yeah.

00:25:50.500 --> 00:25:51.540
I've given it a couple of times.

00:25:51.540 --> 00:25:55.640
Basically, the way it worked is like when I was working on that course and really like playing with those ideas,

00:25:55.640 --> 00:26:01.000
I submitted to a bunch of conferences and those conferences were either a year out or they were like a month out or something.

00:26:01.000 --> 00:26:01.220
Right.

00:26:01.220 --> 00:26:03.100
That's how that ended up so spread out.

00:26:03.100 --> 00:26:05.820
The other one is I mentioned the browser.

00:26:05.820 --> 00:26:06.560
That was fun.

00:26:06.560 --> 00:26:08.380
But how about the browser-asaurus?

00:26:08.940 --> 00:26:09.160
Okay.

00:26:09.160 --> 00:26:13.500
This is a macOS only tool, but there's probably something like it for the others.

00:26:13.500 --> 00:26:14.380
So here's the thing.

00:26:14.380 --> 00:26:22.380
Suppose I'm in Typeora, which is a Markdown editor, or I'm in a PowerPoint and it's got a link and I click it.

00:26:22.380 --> 00:26:25.120
By default, it opens in the default browser.

00:26:25.120 --> 00:26:30.680
But depending on what you're doing, you might want it to be like, oh, sometimes I wanted to open in Vivaldi,

00:26:30.680 --> 00:26:35.760
but other times I wanted to open in like say the cute browser or Orion or some odd thing like that.

00:26:35.760 --> 00:26:35.940
Right.

00:26:36.180 --> 00:26:42.740
So the idea with this thing is that you click a link and when it opens up, instead of opening in the default browser,

00:26:42.740 --> 00:26:44.680
the browser-asaurus is the default.

00:26:44.680 --> 00:26:50.760
And then you have keyboard shortcuts like F for Firefox, E for Edge, S for Safari.

00:26:50.760 --> 00:26:53.580
And you say, well, which one do you want to open in right now?

00:26:53.580 --> 00:26:57.120
And it basically just delegates to the different browsers you register it with.

00:26:57.120 --> 00:27:00.140
So you can hit T for Tor or F for Firefox when you click a link.

00:27:00.140 --> 00:27:01.020
That's kind of cool, right?

00:27:01.020 --> 00:27:01.920
That is pretty cool.

00:27:01.920 --> 00:27:02.400
Yeah.

00:27:02.400 --> 00:27:07.700
I haven't been convinced that I would use that or not, but I do appreciate it.

00:27:07.700 --> 00:27:12.140
And I feel like maybe someone sent that in and if they did, I'd really appreciate it.

00:27:12.140 --> 00:27:14.340
But yeah, I don't have any notes I sent it in.

00:27:14.340 --> 00:27:15.640
So anyway, that's pretty cool.

00:27:15.640 --> 00:27:20.560
If you find yourself, you know, copying, going to different browsers a lot and you're on Mac,

00:27:20.560 --> 00:27:24.420
I know that's like a small, a rapidly decreasing Venn diagram.

00:27:24.420 --> 00:27:26.660
But if you're in that space, this might be a cool option for you.

00:27:27.060 --> 00:27:27.200
Yeah.

00:27:27.200 --> 00:27:28.860
What is it written with anyway?

00:27:28.860 --> 00:27:30.220
TypeScript mostly.

00:27:30.220 --> 00:27:30.860
Okay.

00:27:30.860 --> 00:27:34.660
So speaking of browsers, I just found this because I was like, is links dead?

00:27:34.660 --> 00:27:36.300
Can I use something like links now?

00:27:36.300 --> 00:27:41.280
And there's a browser called Broush, which is a text-based browser.

00:27:41.280 --> 00:27:42.820
So that's still a thing.

00:27:42.820 --> 00:27:43.300
Cool.

00:27:43.300 --> 00:27:44.540
I had to try this out.

00:27:44.540 --> 00:27:45.760
Oh my gosh.

00:27:45.760 --> 00:27:50.080
I love it that it kind of has text, but it like 8-bit pixelated.

00:27:50.080 --> 00:27:50.840
Yeah.

00:27:50.840 --> 00:27:52.560
It takes the images and makes them terrible.

00:27:52.560 --> 00:27:55.400
It takes the images and makes them look like what you would get.

00:27:55.400 --> 00:27:56.160
Yeah.

00:27:56.480 --> 00:27:57.740
So I'll have to give this a try.

00:27:57.740 --> 00:27:58.300
Yeah.

00:27:58.300 --> 00:27:59.640
And you've run it in Docker.

00:27:59.640 --> 00:28:00.460
Of course you do.

00:28:00.460 --> 00:28:00.960
All right.

00:28:00.960 --> 00:28:02.380
Pretty cool.

00:28:02.380 --> 00:28:03.780
All right.

00:28:03.780 --> 00:28:04.760
Oh, let's.

00:28:04.760 --> 00:28:05.060
Yeah.

00:28:05.060 --> 00:28:05.260
Go ahead.

00:28:05.260 --> 00:28:07.380
One more before we get to our joke.

00:28:07.380 --> 00:28:08.020
Okay.

00:28:08.020 --> 00:28:11.440
The other one is I talked about doing a live class.

00:28:11.440 --> 00:28:14.920
So I actually have an announcement for a live class that I'm doing.

00:28:14.920 --> 00:28:22.060
So obviously people know I have a bunch of online courses and of course I'm going to keep, I'm already working on the next one of those and we've got a bunch coming there.

00:28:22.060 --> 00:28:25.220
But I want to try some experiments.

00:28:25.220 --> 00:28:31.840
Something where people can attend a class in person with other people, right?

00:28:31.840 --> 00:28:34.860
If they sort of help each other along.

00:28:34.860 --> 00:28:39.280
And I've tried this before, this cohort thing, but I think I've got a better platform, a better way to do it.

00:28:39.280 --> 00:28:44.740
So over at, this link I'm going to put in the show notes, I'm doing a FastAPI and MongoDB.

00:28:44.740 --> 00:28:48.780
So basically FastAPI, Pydantic, Beanie and MongoDB course.

00:28:48.780 --> 00:28:53.020
That is going to be a four day, six day course over two weeks.

00:28:53.020 --> 00:28:55.960
And it has a couple hours a day.

00:28:55.960 --> 00:28:56.840
And.

00:28:56.840 --> 00:28:57.660
Oh, wow.

00:28:57.660 --> 00:29:00.260
We'd have a bunch of people there working together on some fun stuff.

00:29:00.260 --> 00:29:03.260
And I'll be live teaching every session.

00:29:03.260 --> 00:29:08.780
So it's going to be like a live course as if you were attending it in person, just remotely.

00:29:08.780 --> 00:29:15.120
Because it's 2022 and it's not a, I guess it's not post post COVID all the way.

00:29:15.120 --> 00:29:17.900
But anyway, it's, it's got a really cool set of topics that we cover.

00:29:17.900 --> 00:29:19.020
It talks about async.

00:29:19.020 --> 00:29:22.660
It talks about Mongo, Beanie, Pydantic, FastAPI, of course.

00:29:22.660 --> 00:29:24.860
We even use Locus at the end to test it out.

00:29:24.860 --> 00:29:27.360
I'm, I think this would be a fun.

00:29:27.360 --> 00:29:28.280
This looks great.

00:29:28.280 --> 00:29:28.820
Cool.

00:29:28.820 --> 00:29:29.380
Yeah.

00:29:29.380 --> 00:29:29.700
Yeah.

00:29:29.700 --> 00:29:29.960
Awesome.

00:29:29.960 --> 00:29:31.260
I think it'll be fun too.

00:29:31.260 --> 00:29:33.620
I think it'll be neat to have this experience with people.

00:29:33.620 --> 00:29:38.000
And I've tried this before, but all my prior attempts were, they were good, I think,

00:29:38.000 --> 00:29:39.680
but they were like, yeah, take the online course.

00:29:39.680 --> 00:29:41.540
And then we'll do like a community type thing.

00:29:41.540 --> 00:29:45.720
This is like a live course that I'm just teaching one off for that group of people that sign up.

00:29:45.720 --> 00:29:46.940
So we'll see how that goes.

00:29:46.940 --> 00:29:49.200
If it goes really well and people love it, then I'll do more of these.

00:29:49.200 --> 00:29:50.740
If not, then maybe less of them.

00:29:50.740 --> 00:29:51.080
I don't know.

00:29:51.080 --> 00:29:51.740
We'll see how it goes.

00:29:51.820 --> 00:29:55.340
But this is happening August 8th to 19th.

00:29:55.340 --> 00:29:59.460
So it has a real date because it has, you know, a real live aspect to it.

00:29:59.460 --> 00:29:59.920
Nice.

00:29:59.920 --> 00:30:00.360
Cool.

00:30:00.360 --> 00:30:00.740
All right.

00:30:00.740 --> 00:30:01.360
Cool.

00:30:01.360 --> 00:30:04.980
And Mario on the on says, that's my stack right there.

00:30:04.980 --> 00:30:05.380
Oh, yeah.

00:30:05.380 --> 00:30:06.280
That's a good stack, right?

00:30:06.460 --> 00:30:09.460
There's some really good stuff to talk about there.

00:30:09.460 --> 00:30:12.260
I've been using Beanie and FastAPI for stuff.

00:30:12.260 --> 00:30:13.080
And obviously, Monk.

00:30:13.080 --> 00:30:13.460
Yeah.

00:30:13.460 --> 00:30:16.700
Speaking of courses, one question out there.

00:30:16.700 --> 00:30:18.980
How's the pytest course going?

00:30:18.980 --> 00:30:19.940
It is going.

00:30:20.280 --> 00:30:25.320
It's creeping forward, but life has gotten in the way.

00:30:25.320 --> 00:30:27.260
And we'll get it out.

00:30:27.260 --> 00:30:28.100
It's awesome that you're having.

00:30:28.100 --> 00:30:28.940
Yeah.

00:30:28.940 --> 00:30:29.840
It's awesome that you're working on that.

00:30:29.840 --> 00:30:31.540
It takes a while to create a course, doesn't it?

00:30:31.540 --> 00:30:32.600
Longer than I thought.

00:30:32.600 --> 00:30:34.260
I'm like, man, I already wrote the book.

00:30:34.260 --> 00:30:36.380
I can totally pop a course out in a couple of days.

00:30:36.380 --> 00:30:38.500
Yes, of course.

00:30:38.500 --> 00:30:43.180
Would you say that as a junior developer, you might think about this differently than after

00:30:43.180 --> 00:30:44.140
somebody's been doing it for a while?

00:30:44.140 --> 00:30:45.360
Yeah.

00:30:45.360 --> 00:30:47.600
This cracked me up.

00:30:47.600 --> 00:30:49.280
So I can't remember who shared this.

00:30:49.280 --> 00:30:50.260
It's a great joke you got here.

00:30:50.260 --> 00:30:52.260
Somebody shared it on Twitter.

00:30:52.260 --> 00:30:53.160
Sorry, I can't.

00:30:53.160 --> 00:30:54.040
I don't know who.

00:30:54.040 --> 00:31:01.180
But OK, so in a job interview, you've got somebody gets asked, where do you see yourself

00:31:01.180 --> 00:31:01.980
in five years?

00:31:01.980 --> 00:31:09.980
And the junior developer in this interview question shows a picture of the black hoodie with multiple

00:31:09.980 --> 00:31:11.640
screens and light up keyboard.

00:31:11.640 --> 00:31:13.360
Just I'm in Hackersome.

00:31:13.360 --> 00:31:14.020
Five screens.

00:31:14.020 --> 00:31:14.280
Yeah.

00:31:14.280 --> 00:31:15.640
Totally coding.

00:31:15.640 --> 00:31:15.940
Yeah.

00:31:15.940 --> 00:31:18.660
Senior developer, where do you see yourself in five years?

00:31:18.660 --> 00:31:19.640
On a farm.

00:31:19.640 --> 00:31:23.560
Pumpkin farming with cows and apples.

00:31:23.560 --> 00:31:24.120
And you know what?

00:31:24.120 --> 00:31:25.580
I'm about done.

00:31:25.580 --> 00:31:26.920
I love it.

00:31:26.920 --> 00:31:27.380
Yeah.

00:31:27.380 --> 00:31:30.200
My personal thoughts are, why not both?

00:31:30.200 --> 00:31:33.780
This is just a view of the inside his office and then outside.

00:31:33.780 --> 00:31:35.980
Working from home, man.

00:31:35.980 --> 00:31:36.600
That's right.

00:31:36.600 --> 00:31:37.280
Working from home.

00:31:37.280 --> 00:31:37.980
Yeah.

00:31:38.120 --> 00:31:38.320
All right.

00:31:38.320 --> 00:31:43.480
I have maybe the one that preceded that, the one that, or maybe is in between these two

00:31:43.480 --> 00:31:45.020
that might precipitate the second.

00:31:45.020 --> 00:31:45.520
Okay.

00:31:45.520 --> 00:31:46.180
All right.

00:31:46.180 --> 00:31:48.400
So this is a tweet from Programming Humor.

00:31:48.400 --> 00:31:50.380
It's a strange language, that JS.

00:31:50.380 --> 00:31:52.540
JavaScript is such a strange language.

00:31:52.540 --> 00:31:53.920
Nobody can understand it.

00:31:53.920 --> 00:31:57.140
But if they manage to, then they create their own framework.

00:31:59.040 --> 00:31:59.520
Yes.

00:31:59.520 --> 00:32:03.520
Everyone's got their JavaScript front-end framework or something like that.

00:32:03.520 --> 00:32:03.960
Yeah.

00:32:03.960 --> 00:32:09.840
And you know you've made it when the framework you've invented starts showing up on job requirements.

00:32:09.840 --> 00:32:10.620
That's right.

00:32:10.620 --> 00:32:13.300
With four years experience.

00:32:13.300 --> 00:32:14.680
We're only two years old.

00:32:14.680 --> 00:32:15.580
Exactly.

00:32:15.580 --> 00:32:16.200
Yeah.

00:32:16.200 --> 00:32:16.600
Yeah.

00:32:16.600 --> 00:32:18.440
Well, good episode, Michael.

00:32:18.440 --> 00:32:20.240
Thanks for showing up again.

00:32:20.240 --> 00:32:20.860
You bet.

00:32:20.860 --> 00:32:21.740
Fun as always.

00:32:21.740 --> 00:32:22.640
Thanks, everybody.

00:32:22.640 --> 00:32:23.400
We'll see you later.

00:32:23.400 --> 00:32:25.340
In the slack and everything.

00:32:25.340 --> 00:32:25.940
Bye.

