WEBVTT

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

00:00:05.120 --> 00:00:09.400
This is episode 422 recorded March 3rd, 2025.

00:00:09.800 --> 00:00:10.560
I am Michael Kennedy.

00:00:10.800 --> 00:00:11.760
And I am Brian Okken.

00:00:11.980 --> 00:00:13.760
And this episode is brought to you by us.

00:00:14.340 --> 00:00:16.520
Check out Brian's pytest courses.

00:00:16.840 --> 00:00:18.860
Check out the ones over at Talk Python Training.

00:00:19.040 --> 00:00:22.020
We're up to almost 475 hours.

00:00:22.880 --> 00:00:23.600
275 hours?

00:00:24.080 --> 00:00:24.580
I mean, not that many.

00:00:24.900 --> 00:00:27.040
275 hours of courses over at Talk Python.

00:00:27.040 --> 00:00:28.620
There are many to choose from there.

00:00:28.900 --> 00:00:31.460
and Ryan's book and Patreon supporters and all these things.

00:00:31.530 --> 00:00:32.060
Thank you so much.

00:00:32.400 --> 00:00:36.360
Also, we're continuing to improve and evolve our newsletter,

00:00:36.570 --> 00:00:38.900
which gives you, I think, insights into the episode

00:00:39.160 --> 00:00:40.980
that we maybe didn't explicitly call out

00:00:40.980 --> 00:00:42.440
and certainly are not in the show notes.

00:00:42.600 --> 00:00:44.360
So head over to pythonbytes.fm,

00:00:44.820 --> 00:00:46.380
click on newsletter, put in your email.

00:00:46.760 --> 00:00:48.380
We will be kind and gentle to it,

00:00:48.520 --> 00:00:49.540
but we'll send you cool stuff,

00:00:50.020 --> 00:00:52.860
usually the day of or after the day after the show.

00:00:53.140 --> 00:00:54.720
Yeah, so with that said, Ryan,

00:00:55.460 --> 00:00:56.680
how do we start our show today?

00:00:57.080 --> 00:00:59.120
Let's start it with a video, kind of.

00:00:59.520 --> 00:01:00.820
- Wait, isn't this already a video?

00:01:01.000 --> 00:01:01.720
People want to watch it?

00:01:01.980 --> 00:01:02.700
- Yeah, yeah.

00:01:03.520 --> 00:01:04.260
- Very mad at you.

00:01:04.540 --> 00:01:08.400
- Yeah, so I'm trying to add this to the stage.

00:01:08.620 --> 00:01:09.160
What's going on?

00:01:09.360 --> 00:01:10.780
Oh, the wrong, yeah, anyway.

00:01:11.520 --> 00:01:12.080
There we go.

00:01:13.100 --> 00:01:15.200
Technical difficulties that won't make any sense

00:01:15.200 --> 00:01:15.960
to anybody listening.

00:01:16.439 --> 00:01:20.260
So, we don't normally cover video because it's,

00:01:20.880 --> 00:01:21.960
I don't know, I don't know why,

00:01:22.260 --> 00:01:25.160
but I don't watch a lot of Python videos, I guess.

00:01:25.680 --> 00:01:28.120
But this one is a do not miss.

00:01:28.360 --> 00:01:33.440
So Henik put out a video called my 2025 uv based project,

00:01:33.780 --> 00:01:36.120
Python project layout for production apps.

00:01:36.940 --> 00:01:39.920
And I was paid attention to this

00:01:40.440 --> 00:01:42.780
partly to see what he was up to and I like uv.

00:01:43.580 --> 00:01:46.600
But also this, so this, when you watch it,

00:01:47.040 --> 00:01:50.500
his example is a FastAPI app.

00:01:50.700 --> 00:01:54.240
And in his world, an app is usually like,

00:01:54.840 --> 00:01:56.640
really a website app.

00:01:56.800 --> 00:02:00.160
And later he's gonna go on to talk about Docker, I think,

00:02:00.360 --> 00:02:03.880
because this is a part one, part one of a series.

00:02:04.220 --> 00:02:05.980
But this one's already enough

00:02:06.080 --> 00:02:07.160
that I think it's really useful.

00:02:07.680 --> 00:02:11.180
And especially in a lot of the, some of the stuff I deal with

00:02:11.440 --> 00:02:16.460
I think of an app as anything that's packaged, kind of.

00:02:17.040 --> 00:02:20.460
Like it's not a package, it's not something you put on PyPI,

00:02:21.160 --> 00:02:22.999
but it's a bunch of your own code

00:02:23.000 --> 00:02:26.080
that you normally would have used a requirements.txt file,

00:02:26.720 --> 00:02:28.820
and I like his model better.

00:02:28.960 --> 00:02:31.420
So I'm gonna jump in, I got a couple tabs

00:02:32.200 --> 00:02:34.860
because it's kind of hard to like navigate.

00:02:35.350 --> 00:02:36.980
Anyway, snapshot videos.

00:02:37.220 --> 00:02:38.940
So I stopped them where I wanted to.

00:02:39.480 --> 00:02:43.340
So the video is great, it's about 25 minutes long,

00:02:43.500 --> 00:02:45.100
it's pretty quick to watch.

00:02:46.080 --> 00:02:49.400
Here we've got the project layout.

00:02:49.560 --> 00:02:53.280
So his project layout is using a source layout.

00:02:53.800 --> 00:02:55.780
And really, there's no requirements file.

00:02:56.540 --> 00:02:59.140
All of the requirements are in the pyproject.toml.

00:02:59.360 --> 00:03:03.200
And instead of a custom lock file or one you manually do,

00:03:04.080 --> 00:03:06.160
he's just recommending that you let

00:03:06.330 --> 00:03:08.940
UV take care of a lot of the project stuff.

00:03:09.130 --> 00:03:11.320
And actually, even with--

00:03:11.640 --> 00:03:13.200
and we'll take a look at a little bit more

00:03:13.220 --> 00:03:14.680
of what's in pyproject.toml.

00:03:15.000 --> 00:03:18.080
But he's recommending that you go ahead and check in the UV

00:03:18.180 --> 00:03:18.440
lock.

00:03:18.660 --> 00:03:21.940
So if you're letting uv handle your virtual environment,

00:03:22.280 --> 00:03:25.360
it's gonna create a lock file, and if you commit that,

00:03:25.740 --> 00:03:28.760
then uv run later will use that

00:03:28.800 --> 00:03:30.660
and use all of the stuff in the lock file,

00:03:31.020 --> 00:03:33.460
and you, instead of running Python,

00:03:34.040 --> 00:03:37.360
you clone the repo, run uv run on your project,

00:03:37.600 --> 00:03:40.880
and it's gonna grab everything out of the lock file.

00:03:41.120 --> 00:03:42.420
It's just like pin dependencies.

00:03:42.640 --> 00:03:43.180
It's pretty sweet.

00:03:43.500 --> 00:03:45.600
- Yep, I 100% agree with him.

00:03:46.060 --> 00:03:47.080
Check in the uv lock file.

00:03:47.620 --> 00:03:51.400
And then you don't also, you don't even have to do uv run if you don't want, you can just

00:03:51.460 --> 00:03:54.940
do uv sync and it will also use the pin dependencies in the lock file.

00:03:55.080 --> 00:04:00.360
And then, because some systems, they require to run kind of with their setup.

00:04:00.960 --> 00:04:07.200
For example, Pyramid, you need to use PSERV and then it's like configuration file or flask,

00:04:07.450 --> 00:04:09.100
you can do like flask run or Django.

00:04:09.200 --> 00:04:11.520
Like, so if you still want to stick with that, you can just do uv sync.

00:04:11.950 --> 00:04:14.800
So uv sync will grab all the, everything out of the lock file then.

00:04:15.320 --> 00:04:15.480
Yes.

00:04:16.019 --> 00:04:16.120
- Exactly.

00:04:17.579 --> 00:04:18.060
- And--

00:04:18.060 --> 00:04:19.739
- I think it might even create the virtual environment,

00:04:19.940 --> 00:04:21.400
though I haven't actually tried that yet.

00:04:21.480 --> 00:04:21.940
- Yeah, it does.

00:04:22.380 --> 00:04:24.440
Yeah, if you don't have one already, it'll create it.

00:04:24.560 --> 00:04:26.960
And also, if you already had one,

00:04:27.320 --> 00:04:30.380
and it was out of sync, like uv sync,

00:04:30.560 --> 00:04:32.280
that's kind of what the part of the sync does.

00:04:32.600 --> 00:04:34.960
If somebody updated some of the requirements,

00:04:35.340 --> 00:04:37.260
so the uv lock had changed,

00:04:37.660 --> 00:04:41.380
then uv sync will rewrite the virtual environment.

00:04:41.740 --> 00:04:42.200
So--

00:04:42.220 --> 00:04:42.500
- Nice.

00:04:43.360 --> 00:04:47.300
And so he's showing also that his version

00:04:47.420 --> 00:04:50.260
of how to specify the Python version

00:04:50.400 --> 00:04:53.320
is to just specify it within your pyproject.toml

00:04:53.380 --> 00:04:56.140
and uv will grab that and install it if necessary.

00:04:57.300 --> 00:05:01.340
And then also interesting discussion around version

00:05:01.580 --> 00:05:04.540
because pyproject.toml requires a version

00:05:04.700 --> 00:05:06.380
but with a lot of applications

00:05:06.620 --> 00:05:08.760
we don't really utilize the version

00:05:09.560 --> 00:05:12.020
because it's just code that you're pushing and running.

00:05:12.140 --> 00:05:16.540
So he said, "Just set it, if you don't care about the version, just set it to zero,

00:05:16.760 --> 00:05:19.660
and then people will realize you're not using it."

00:05:19.660 --> 00:05:20.560
So...

00:05:20.560 --> 00:05:21.600
The world's most common version.

00:05:22.100 --> 00:05:22.580
Yeah.

00:05:22.840 --> 00:05:28.120
And then also a discussion around the separation of dependency groups that came in recently

00:05:28.580 --> 00:05:32.560
that uv handles nicely in PyProject TOML files.

00:05:33.160 --> 00:05:39.300
And that allows you to separate your dependencies based on really what the application needs

00:05:39.560 --> 00:05:40.920
versus what you need for development.

00:05:41.700 --> 00:05:49.320
this will work then you can run. In production it won't install your like pytest and stuff,

00:05:49.960 --> 00:05:54.620
but it'll install everything else. But when you're creating a virtual environment locally to develop,

00:05:54.880 --> 00:06:01.340
it'll grab those also. So very cool to have all of this together. And then build system,

00:06:01.850 --> 00:06:11.680
I didn't really realize that you could specify uv as a build backend. And I'm going to have to

00:06:11.680 --> 00:06:16.460
hatchling in mind and, I believe several people have pointed out that hatchling is

00:06:16.540 --> 00:06:20.620
the default. And the reason that we, when we played with this the very, very first time

00:06:20.620 --> 00:06:25.220
it didn't show up with any build back in is because we created in, application mode,

00:06:25.300 --> 00:06:29.040
but I think if we created a package mode, there's a way to say like, well, what really

00:06:29.100 --> 00:06:32.440
kind of project are you creating? Then it specifies the build back in explicitly, I

00:06:32.440 --> 00:06:36.560
think. So anyway, a lot of, a lot of options there, but yeah, very cool.

00:06:36.760 --> 00:06:40.580
Yeah, and actually just an enjoyable video too.

00:06:40.580 --> 00:06:41.560
I like what he's doing there.

00:06:41.780 --> 00:06:42.420
So check it out.

00:06:42.910 --> 00:06:43.540
Very nice.

00:06:44.240 --> 00:06:48.640
Well, let's talk about async and await.

00:06:49.080 --> 00:06:52.100
So there's this cool project called AIO Limiter,

00:06:52.510 --> 00:06:55.980
an efficient implementation of a rate limiter for async I/O.

00:06:56.110 --> 00:06:59.100
And this comes to us from Martin Peters.

00:06:59.640 --> 00:07:01.860
Martin Peters, at least at one point,

00:07:02.060 --> 00:07:06.200
was the most prolific Stack Overflow Python person.

00:07:06.560 --> 00:07:13.900
period. So that was fun. And this project is a something that got created as a result

00:07:13.900 --> 00:07:19.460
of an answer on Stack Overflow by him. So not a big surprise. I've, I'll beat on the

00:07:19.580 --> 00:07:23.480
dead horse a little bit, Brian. I feel like there's a really, there's a big missing piece

00:07:23.880 --> 00:07:30.440
for async and await in Python. And that is any sort of mechanism or control or, or understanding

00:07:30.440 --> 00:07:35.660
or adjustment or whatever of the underlying running of async code in general.

00:07:36.240 --> 00:07:36.380
Right?

00:07:36.520 --> 00:07:41.100
If I call an async function and I say a way to thing, how does it run?

00:07:41.380 --> 00:07:42.360
Well, you don't know.

00:07:43.000 --> 00:07:46.540
It might be running in an event loop that you've created, it might be running in one

00:07:47.020 --> 00:07:48.800
that you, a framework created.

00:07:49.020 --> 00:07:53.400
You don't sometimes often, most of the time let's say, you don't get a choice on how that

00:07:53.440 --> 00:07:54.020
loop is created.

00:07:54.420 --> 00:07:58.580
For example, if you're using FastAPI, FastAPI creates a loop and says, "Here, you can use

00:07:58.660 --> 00:07:59.020
this one.

00:07:59.560 --> 00:08:06.020
like it. You know what I mean? Whereas systems like.NET, they've got thread pools and async

00:08:06.740 --> 00:08:11.420
I/O pools and contexts and stuff that you can say, "Hey, on this one, I want you to

00:08:11.480 --> 00:08:15.200
limit to 10. So if you're doing work, just do 10 at a time. When you're done with one,

00:08:15.640 --> 00:08:18.380
allow the other ones to come in, otherwise queue them and just make them away." Right?

00:08:18.480 --> 00:08:23.540
Stuff like that is kind of missing. So all these projects are trying to backfill that

00:08:23.600 --> 00:08:27.879
kind of functionality into Python's async and await. And this is cool. So it does give

00:08:27.880 --> 00:08:32.180
you like suppose you're working on a project and you're using an external API

00:08:32.360 --> 00:08:36.000
and the API says you have a rate limit of five per second if you go over that

00:08:36.020 --> 00:08:40.719
we're gonna start failing and telling you status code 429 too many requests

00:08:40.780 --> 00:08:45.460
wait however long and try again but that becomes like really janky right so with

00:08:45.520 --> 00:08:48.920
this thing what you can do is I can create a rate limiter and say I'm

00:08:49.120 --> 00:08:54.039
willing to allow a hundred calls within a 30-second window or the example I gave

00:08:54.040 --> 00:08:56.960
five calls within a one-second window or whatever, right?

00:08:57.140 --> 00:08:57.720
Something like that.

00:08:58.200 --> 00:09:00.740
And then you just put that into a async with block

00:09:01.120 --> 00:09:03.280
and then stuff that happens in that window

00:09:03.400 --> 00:09:04.980
will be limited by this rate limit.

00:09:05.380 --> 00:09:05.780
- Okay.

00:09:06.060 --> 00:09:06.460
- Cool, right?

00:09:06.740 --> 00:09:08.960
So it makes it really easy to handle those kinds of things.

00:09:09.440 --> 00:09:13.280
But often it's not like I'm going to make all of the calls here,

00:09:13.740 --> 00:09:14.620
you know what I mean?

00:09:15.279 --> 00:09:18.360
It's I want all the async calls in the system

00:09:18.620 --> 00:09:19.760
to be limited in this way,

00:09:19.900 --> 00:09:22.480
not the ones that I'm controlling the particular function of,

00:09:22.480 --> 00:09:25.520
which is sort of the crux of my complaint that I started with.

00:09:26.020 --> 00:09:26.680
But this is nice.

00:09:26.710 --> 00:09:28.500
You create one of these somewhere,

00:09:28.760 --> 00:09:30.540
and then anywhere you use this rate limit

00:09:30.800 --> 00:09:34.380
as a context manager, it is subject to that rate limiting.

00:09:34.700 --> 00:09:36.140
So it doesn't have to be the same function.

00:09:36.450 --> 00:09:38.740
It doesn't have to be all the codes are happening

00:09:38.800 --> 00:09:40.440
at the same time within the block.

00:09:40.900 --> 00:09:43.100
So, you know, that's a pretty nice thing, right?

00:09:43.180 --> 00:09:45.120
As long as you just put that in all the places you need it.

00:09:45.380 --> 00:09:47.380
Like, for example, one of the problems you can do is

00:09:47.660 --> 00:09:48.920
you're getting too many requests.

00:09:48.930 --> 00:09:50.140
You can overwhelm your database,

00:09:50.340 --> 00:09:53.480
and because you're awaiting it asynchronously,

00:09:53.560 --> 00:09:55.060
you could just keep feeding it to the database,

00:09:55.360 --> 00:09:56.740
even if the database is slowing down

00:09:56.740 --> 00:09:57.840
and slowing down and slowing down.

00:09:57.860 --> 00:09:59.260
So like in your data access layer,

00:09:59.500 --> 00:10:01.320
you could just wrap all of your queries

00:10:01.320 --> 00:10:02.840
in one of these things that say,

00:10:03.140 --> 00:10:05.620
don't let more than, I don't know, 10 per second

00:10:05.760 --> 00:10:08.000
or whatever is reasonable for your database.

00:10:08.180 --> 00:10:10.040
That's kind of low, but you know what I mean.

00:10:10.160 --> 00:10:11.540
Like you can sort of control that.

00:10:11.840 --> 00:10:15.300
- So you might like have one of these rate limiter

00:10:15.480 --> 00:10:19.320
for your database and then maybe one for an external API or-

00:10:19.440 --> 00:10:22.160
- Yes, theoretically, and they could be different, right?

00:10:22.480 --> 00:10:23.800
- Yeah, okay, that makes sense.

00:10:24.380 --> 00:10:26.600
- Yeah, anyway, yeah, I thought this was kinda cool,

00:10:26.740 --> 00:10:29.900
and people who are worried about trying to solve

00:10:29.980 --> 00:10:32.140
that problem, then they can use this

00:10:32.240 --> 00:10:33.020
as one of the tools there.

00:10:35.160 --> 00:10:36.740
- Computers are so fast, sometimes we're like,

00:10:36.940 --> 00:10:38.520
it's too fast, slow down a little bit.

00:10:38.880 --> 00:10:40.620
- Yeah, it's like, let's make it allow it

00:10:40.620 --> 00:10:42.640
to do all the work and not wait on any of it,

00:10:42.780 --> 00:10:45.260
like, usually good, sometimes bad.

00:10:45.720 --> 00:10:46.360
- Sometimes bad.

00:10:47.120 --> 00:10:48.420
- But the thing on the end doesn't like it.

00:10:49.120 --> 00:10:49.620
- Yep.

00:10:50.340 --> 00:10:51.640
- Yeah, and out in the audience we got a,

00:10:51.760 --> 00:10:52.880
"Wow, cool," says Aziz.

00:10:53.120 --> 00:10:54.960
"I had this limit problem a lot."

00:10:54.960 --> 00:10:55.440
Yeah, awesome.

00:10:55.840 --> 00:10:56.140
Hope it helps.

00:10:56.620 --> 00:10:58.180
- Yeah, hope it limits your problems.

00:10:58.680 --> 00:11:00.400
- It does limit, it will limit your problems.

00:11:01.440 --> 00:11:01.820
What's next?

00:11:02.000 --> 00:11:02.540
- That was weak.

00:11:02.920 --> 00:11:05.040
So, I wanna talk about SpyStuff.

00:11:05.880 --> 00:11:10.820
So, Lucas Lange wrote an article about SpyStuff.

00:11:10.920 --> 00:11:13.440
Actually, "A Peek into a Possible Future

00:11:13.620 --> 00:11:15.239
"of Python in the Browser."

00:11:15.240 --> 00:11:19.520
who, there's a, it's a kind of a fun article also,

00:11:19.660 --> 00:11:20.760
but a great picture as well,

00:11:20.820 --> 00:11:21.880
some cool picture of the mountains.

00:11:22.320 --> 00:11:25.580
Anyway, and you know, he's,

00:11:26.240 --> 00:11:28.320
I trust what he, I trust his opinion

00:11:28.540 --> 00:11:30.120
because of his involvement with Python and everything,

00:11:30.300 --> 00:11:34.340
but this is interesting about a lot of the core Python people

00:11:34.380 --> 00:11:37.380
really involved with thinking about the web.

00:11:38.040 --> 00:11:41.200
So there's a section about looking back on,

00:11:42.600 --> 00:11:44.540
I haven't read this, or seen this,

00:11:44.640 --> 00:11:46.600
but apparently there was a Gary Bernhardt talk

00:11:46.720 --> 00:11:48.340
about the birth and death of JavaScript.

00:11:48.640 --> 00:11:49.760
I'll have to go back and look at that.

00:11:50.960 --> 00:11:52.980
And then, but basically talking about the history

00:11:53.100 --> 00:11:53.820
of Python and--

00:11:53.820 --> 00:11:54.380
- Wait, wait, wait, wait, wait.

00:11:54.540 --> 00:11:57.620
If you have not seen the birth and death of JavaScript,

00:11:58.200 --> 00:11:59.620
it needs to go to the top of your list.

00:11:59.940 --> 00:12:00.180
- Okay.

00:12:00.180 --> 00:12:03.000
- The birth and death of JavaScript is a seminal video

00:12:03.180 --> 00:12:05.820
that is both hilarious and very insightful.

00:12:06.200 --> 00:12:06.580
- Okay, well--

00:12:06.600 --> 00:12:08.180
- And the JavaScript is part of the joke.

00:12:09.399 --> 00:12:11.280
- Okay, JavaScript, all right.

00:12:11.959 --> 00:12:14.079
Well, then he goes on to talk about Pyodide

00:12:14.080 --> 00:12:26.940
other things and using NumPy and Cython and stuff. But the real thrust here is a new research

00:12:27.000 --> 00:12:33.980
project called SPI. S, capital S, capital P, lower Y, I guess. So that's SPI stuff.

00:12:36.260 --> 00:12:41.599
The article says the SPI is a research project in its early stages. At the moment, don't

00:12:41.600 --> 00:12:44.600
attempt to use it yet unless you plan to contribute.

00:12:44.960 --> 00:12:46.440
But maybe you do plan to contribute.

00:12:47.880 --> 00:12:51.220
Both incomplete implementation-wise and design-wise,

00:12:51.420 --> 00:12:53.400
but so early stages.

00:12:53.700 --> 00:12:55.120
But it sounds pretty cool.

00:12:55.280 --> 00:12:57.300
So there's this-- I like the idea.

00:12:57.520 --> 00:13:00.700
So there's this-- I'm going to jump down to the demo,

00:13:00.740 --> 00:13:01.780
see if we can get it to play.

00:13:02.240 --> 00:13:04.700
So-- ooh, I had video sound too, but I

00:13:04.700 --> 00:13:05.500
don't think you hear that.

00:13:05.640 --> 00:13:07.560
But anyway, there's a demo of it working,

00:13:08.060 --> 00:13:09.400
of some shapes shifting around.

00:13:09.720 --> 00:13:12.420
And that's actually running in the browser already,

00:13:12.760 --> 00:13:14.920
but you just can't, I guess it's not complete yet.

00:13:15.180 --> 00:13:20.300
But this idea of having things that look like Python.

00:13:20.580 --> 00:13:24.100
So when you're, there's like blue code and red code

00:13:24.120 --> 00:13:24.700
is the idea.

00:13:25.040 --> 00:13:27.580
And the blue code is stuff that just like acts like Python.

00:13:28.720 --> 00:13:31.200
And that's great for debugging and stuff.

00:13:31.380 --> 00:13:33.920
And because people are used to writing in Python.

00:13:34.580 --> 00:13:36.640
And then there's a redshift model of,

00:13:36.920 --> 00:13:38.820
'cause that's what we do a lot is like,

00:13:39.000 --> 00:13:40.420
whether we should compile it or not.

00:13:40.700 --> 00:13:45.760
But this will pre-compute a lot of the stuff

00:13:45.860 --> 00:13:48.600
that's blue into a pre-compiled version.

00:13:49.140 --> 00:13:52.160
Anyway, all the little compilation parts

00:13:52.160 --> 00:13:53.460
to make things run faster.

00:13:53.960 --> 00:13:56.340
But I really like the idea that you've got a level

00:13:56.480 --> 00:13:59.200
where you're running it just as pure Python

00:13:59.460 --> 00:14:03.380
and then you can deploy it and it runs as a compiled part.

00:14:03.720 --> 00:14:06.840
So anyway, I'm probably getting this wrong at early stages,

00:14:07.020 --> 00:14:10.720
but we've got links to this article and then to the Spy Project itself,

00:14:11.760 --> 00:14:14.220
which a lot of activity just recently.

00:14:14.480 --> 00:14:18.980
So anyway, I like that and mostly, I don't know why I brought this up.

00:14:20.500 --> 00:14:23.800
The, the story of Python in the web browser, better and better.

00:14:24.180 --> 00:14:24.800
So anyway,

00:14:25.500 --> 00:14:30.960
I also bookmarked this article as something super interesting that should,

00:14:31.100 --> 00:14:32.980
you know, might be worth talking and reading up on.

00:14:33.200 --> 00:14:34.160
So thanks for covering it.

00:14:34.240 --> 00:14:34.380
Yeah.

00:14:34.400 --> 00:14:35.480
And if you've got a deeper,

00:14:36.100 --> 00:14:36.620
- We're on the verge.

00:14:36.800 --> 00:14:38.700
- You mentioned we could bring it up later again as well.

00:14:39.320 --> 00:14:40.640
- Yeah, yeah, it's early days,

00:14:40.700 --> 00:14:41.780
so maybe there'll be more news on it.

00:14:42.640 --> 00:14:44.760
I'm very excited about the possibility

00:14:44.980 --> 00:14:46.200
of Python in the browser.

00:14:47.220 --> 00:14:48.900
It'll uncork some amazing stuff

00:14:48.980 --> 00:14:51.220
if that really gets running seamlessly.

00:14:52.620 --> 00:14:54.700
- And really, I'm saying the browser,

00:14:54.780 --> 00:14:56.740
but really what we're also meaning is that

00:14:57.240 --> 00:14:59.600
if we could not have different front-end

00:14:59.640 --> 00:15:00.860
and back-end languages,

00:15:01.720 --> 00:15:04.640
so if we do all the dynamic front-end stuff with Python,

00:15:04.800 --> 00:15:05.120
be cool.

00:15:05.760 --> 00:15:06.000
Exactly.

00:15:06.640 --> 00:15:06.860
Exactly.

00:15:07.020 --> 00:15:11.160
Like, so I think that the browser manufacturers could do significantly

00:15:11.360 --> 00:15:17.200
more to make this better for, for example, every one of them ships a

00:15:17.380 --> 00:15:19.160
JavaScript runtime that's optimized.

00:15:19.300 --> 00:15:19.440
Right.

00:15:19.700 --> 00:15:24.980
Not a single one of them ships the WebAssembly version of Ruby or the web

00:15:25.020 --> 00:15:29.880
assembly version of CPython, you know, Pyodide or the WebAssembly version of

00:15:29.960 --> 00:15:31.940
.NET for Blazor or all these things.

00:15:32.070 --> 00:15:35.540
And so all of those projects are like, well, it'd be great to use this.

00:15:35.700 --> 00:15:37.800
but it's really slow to download the whole runtime

00:15:37.960 --> 00:15:39.460
on each page separately.

00:15:39.960 --> 00:15:40.060
- Yeah.

00:15:40.360 --> 00:15:41.200
- Every browser could say,

00:15:41.740 --> 00:15:44.980
"We will provide and keep up to date

00:15:45.060 --> 00:15:46.840
"as part of our binaries,"

00:15:46.840 --> 00:15:49.060
or just off of the internet or whatever as you download it,

00:15:49.600 --> 00:15:52.420
"a shared Python runtime, a shared Ruby runtime,

00:15:52.560 --> 00:15:55.800
"a shared.NET runtime," and so on, and they don't.

00:15:55.900 --> 00:15:56.020
- Yeah.

00:15:56.400 --> 00:15:58.740
- Right, but all these complaints about,

00:15:58.820 --> 00:16:00.860
"Well, the web frontend's too slow

00:16:00.940 --> 00:16:02.220
"'cause you gotta download all this stuff,"

00:16:02.240 --> 00:16:03.740
like, yes, you do now,

00:16:03.760 --> 00:16:07.820
but it could theoretically be that they say, well, we're going to support like an

00:16:08.120 --> 00:16:12.080
open sort of management of these, these binary, these WebAssembly runtimes that

00:16:12.080 --> 00:16:12.960
you might need to download.

00:16:13.480 --> 00:16:16.980
Sure, the extras you got to download every time like JavaScript, but the core

00:16:17.200 --> 00:16:22.440
runtime of 10 megs, we'll like update that with our browser or just update it as it

00:16:22.500 --> 00:16:23.160
changes on the web.

00:16:23.290 --> 00:16:24.040
I wish they would do that.

00:16:25.400 --> 00:16:25.760
Right.

00:16:25.840 --> 00:16:26.760
I mean, you know, they do it for JavaScript.

00:16:27.680 --> 00:16:28.880
I mean, come on now.

00:16:29.260 --> 00:16:29.480
Right.

00:16:29.620 --> 00:16:32.860
It's like, it sounds crazy, but at the same time they do it for JavaScript and

00:16:32.860 --> 00:16:33.440
they write their own.

00:16:33.480 --> 00:16:35.620
All right, they wouldn't even have to write their own.

00:16:35.660 --> 00:16:38.040
They just got to allow the run of random others.

00:16:38.240 --> 00:16:39.440
Okay, enough of that.

00:16:39.600 --> 00:16:41.100
Let's talk about reloading stuff in the browser.

00:16:41.340 --> 00:16:42.360
Instead, that sounds fun.

00:16:42.800 --> 00:16:44.980
So there's two projects I want to tell you about.

00:16:45.520 --> 00:16:49.020
One is the big heavyweight does so much stuff

00:16:49.080 --> 00:16:51.020
to help you write web applications,

00:16:51.600 --> 00:16:54.820
type in the editor, and have that stuff magically change.

00:16:55.180 --> 00:16:57.520
For example, by default, if I run a Flask app

00:16:58.020 --> 00:17:01.600
and I go over to the, I run it and I open it up in a browser,

00:17:01.960 --> 00:17:03.200
and I see the page I'm working on,

00:17:03.240 --> 00:17:05.540
and then I go over and I edit the Jinja template.

00:17:05.900 --> 00:17:09.400
I hit save, and I refresh the browser, nothing happens.

00:17:09.449 --> 00:17:12.560
I have to go back to Flask, restart Flask,

00:17:14.040 --> 00:17:15.699
go back to the browser, reload the browser,

00:17:15.819 --> 00:17:16.780
now I can see my changes.

00:17:17.360 --> 00:17:19.620
You can level that up one by going to Flask

00:17:19.620 --> 00:17:21.100
and say you're running in debug mode,

00:17:21.199 --> 00:17:24.600
so if you see any changes, please rerun Flask

00:17:24.959 --> 00:17:27.199
and reload the templates if I edit the templates.

00:17:27.740 --> 00:17:29.600
Then you can just edit your thing, save it,

00:17:29.700 --> 00:17:32.800
go over to your browser, hit refresh, see the changes.

00:17:33.220 --> 00:17:35.580
But what would be nicer if I could have like two thirds

00:17:35.640 --> 00:17:36.880
of my screen be my editor,

00:17:37.620 --> 00:17:39.260
one third of my screen be the web browser.

00:17:39.380 --> 00:17:43.300
And as I type, I see stuff just changing on the page.

00:17:43.860 --> 00:17:45.480
So if I put a CSS class on a thing,

00:17:45.620 --> 00:17:47.760
I don't have to go to the other app and do anything.

00:17:47.780 --> 00:17:50.160
It just literally just the changes that apply

00:17:50.200 --> 00:17:51.340
like every second or so, right?

00:17:52.160 --> 00:17:55.620
So that's what this Relodium thing is, but it does a lot.

00:17:56.020 --> 00:17:58.760
So I want to put this out there for people as a cool option.

00:17:59.240 --> 00:18:00.540
I'm not sure I'm going to put it out there

00:18:00.600 --> 00:18:01.460
as a recommendation yet.

00:18:01.920 --> 00:18:02.620
So let me tell you.

00:18:02.920 --> 00:18:07.760
So for example, it will not just do the experience I told you about, but it will

00:18:07.940 --> 00:18:09.980
actually rerun every function.

00:18:10.490 --> 00:18:13.320
If you make a change to a function, it will rerun it and you can actually

00:18:13.520 --> 00:18:16.240
have it doing like live profiling.

00:18:16.900 --> 00:18:24.100
So as you, as you type there, it'll give you a profiled output of the thing and so

00:18:24.200 --> 00:18:24.260
on.

00:18:24.380 --> 00:18:27.620
So if you kind of want to explore it, it gives you like that idea more broadly.

00:18:27.780 --> 00:18:29.440
So it works there.

00:18:29.500 --> 00:18:33.400
it comes with a PyCharm plugin which is what the little animation is so you can

00:18:33.440 --> 00:18:37.560
actually see a visual representation of like the performance time and how it's

00:18:37.580 --> 00:18:41.760
running and reworking and so on. Okay so that's pretty neat. Comes with an AI

00:18:41.980 --> 00:18:47.160
thing I'm gonna skip that I don't know what that is or care. It has yeah so

00:18:47.460 --> 00:18:51.160
generally if you make a change to a function it will re-execute the current

00:18:51.260 --> 00:18:55.440
function providing immediate feedback and if there's an error it doesn't die

00:18:55.480 --> 00:18:58.979
it just goes well okay once you fix it things are going to be good and it'll

00:18:58.980 --> 00:19:03.000
start working again. So it's kind of durable to that, you know. And it'll

00:19:03.280 --> 00:19:07.020
refresh files throughout the entire project, looking at dependencies. So if I

00:19:07.080 --> 00:19:10.860
make a change to like one bit, then it'll change the others, you know, like with

00:19:10.900 --> 00:19:15.120
new import or whatever. For Django, it does exactly what I was telling you, like

00:19:15.180 --> 00:19:20.800
as you type, not just as you type HTML, but as you type Python. So the example

00:19:20.880 --> 00:19:24.319
they have here is they, they're doing a query for all objects and then they

00:19:24.320 --> 00:19:29.900
slice it to do a limit, paging and limiting type of business, and as they change the numbers

00:19:30.220 --> 00:19:34.920
in the slice in Python, the web browser is automatically updating the results without

00:19:35.020 --> 00:19:35.580
them touching it.

00:19:35.860 --> 00:19:36.520
That's pretty cool.

00:19:37.080 --> 00:19:38.120
Yeah, it's pretty cool, right?

00:19:39.400 --> 00:19:44.520
Similarly for Flask, it automatically reloads Flask, but again, it says, look, it'll hot

00:19:44.600 --> 00:19:50.280
reload the Flask app, but if you just set Flask debug to be true, Flask will already

00:19:50.360 --> 00:19:51.320
do that, you know what I mean?

00:19:52.160 --> 00:19:56.660
So the one thing it doesn't do is it doesn't refresh the page as you type on one side.

00:19:57.020 --> 00:19:58.700
The stuff on the right doesn't change, right?

00:19:58.960 --> 00:20:03.320
Another thing it does, it'll for SQLAlchemy because it's like running functions over and

00:20:03.340 --> 00:20:06.900
over and over, it might start to do insert, insert, insert to the database.

00:20:07.120 --> 00:20:11.900
So it does these auto runs and transactions that roll back so it doesn't tweak the database.

00:20:12.230 --> 00:20:12.920
Oh, interesting.

00:20:13.360 --> 00:20:13.440
Yeah.

00:20:13.580 --> 00:20:15.660
And it also does hot reload for pandas.

00:20:16.020 --> 00:20:19.900
So if you're messing with your data frame or things like that, it'll just automatically

00:20:20.100 --> 00:20:21.200
be updating as you type.

00:20:21.520 --> 00:20:23.240
- All right, pretty interesting, right, Brian?

00:20:23.580 --> 00:20:23.800
- Yeah.

00:20:24.120 --> 00:20:25.300
- Yeah, I don't know if I talked about it before,

00:20:25.400 --> 00:20:27.200
but just since people might want

00:20:27.260 --> 00:20:29.080
a less intrusive version of that.

00:20:29.710 --> 00:20:30.780
So I have this project called

00:20:31.080 --> 00:20:32.440
Server Hot Reload over on GitHub,

00:20:32.800 --> 00:20:34.360
and it's a single JavaScript file.

00:20:34.760 --> 00:20:38.660
And if you just include the JavaScript file in your page,

00:20:38.960 --> 00:20:40.340
it will give you the same functionality

00:20:40.800 --> 00:20:43.300
for web apps that will reload the template.

00:20:43.840 --> 00:20:47.300
So for example, if you just include the JavaScript

00:20:47.480 --> 00:20:48.340
at the top of the page,

00:20:48.760 --> 00:20:50.620
and then Flask, if you run it with Flask debug,

00:20:50.880 --> 00:20:54.580
or Pyramid automatically reloads in debug mode.

00:20:54.630 --> 00:20:56.100
You can set that in the config file,

00:20:56.260 --> 00:20:58.640
and I'm sure you can do similar stuff with Django.

00:20:59.360 --> 00:21:01.160
And then you just browse on one side,

00:21:01.560 --> 00:21:02.940
code on the other, and you just start typing,

00:21:03.560 --> 00:21:05.640
and off it goes, and even detects if you set it up right,

00:21:05.670 --> 00:21:08.400
or even like reload the page if you change an image

00:21:08.860 --> 00:21:11.280
that was being used, and things like that.

00:21:11.380 --> 00:21:14.560
So, super cool, but this one, it doesn't go all crazy.

00:21:14.660 --> 00:21:18.300
It doesn't require an IDE plugin and all that kind of stuff.

00:21:18.460 --> 00:21:22.680
Basically what it does is it looks at the response from the server and says, "Is the

00:21:22.900 --> 00:21:24.660
hash of the HTML changed?

00:21:24.900 --> 00:21:26.320
If yes, reload the page.

00:21:26.600 --> 00:21:29.180
If it's not changed, then don't reload the page," that kind of thing.

00:21:29.460 --> 00:21:36.280
So anyway, two ways to basically work in your editor, start typing, and having some kind

00:21:36.320 --> 00:21:41.700
of output web or in Relodium, other places, just automatically changing as you type so

00:21:41.700 --> 00:21:42.900
you don't have to manage that.

00:21:42.940 --> 00:21:43.860
You're just like, "Oh, what's this class?

00:21:43.960 --> 00:21:44.760
Oh, that looks really great.

00:21:44.840 --> 00:21:46.720
No, we need more padding here, da-da-da," off it goes.

00:21:47.140 --> 00:21:50.520
- So the server one probably doesn't do the,

00:21:50.900 --> 00:21:53.440
like if you change Python or--

00:21:53.460 --> 00:21:55.480
- Technically no, it doesn't do that.

00:21:55.780 --> 00:21:58.360
However, if you set Flask to do that automatically

00:21:58.820 --> 00:22:01.060
and then it re-requests the page, then yes it does.

00:22:01.160 --> 00:22:01.540
You know what I mean?

00:22:01.800 --> 00:22:02.300
- Okay, got it.

00:22:02.680 --> 00:22:05.600
- So if you're willing to use the framework tools,

00:22:05.660 --> 00:22:06.100
then it does.

00:22:06.460 --> 00:22:08.440
- Okay, okay, very good, cool.

00:22:08.600 --> 00:22:10.700
- Yeah, but it's nowhere near as intense,

00:22:10.800 --> 00:22:12.620
which I think for some people is a drawback

00:22:12.680 --> 00:22:15.720
and other people is a plus, depending on where you are.

00:22:16.200 --> 00:22:16.880
- Okay, nice.

00:22:17.480 --> 00:22:19.080
- All right, that's it for all of our items, isn't it?

00:22:19.800 --> 00:22:21.040
- Yeah, it is.

00:22:21.320 --> 00:22:23.200
- Well then, what have you got for extras?

00:22:24.400 --> 00:22:27.940
- I got just a pet project of mine

00:22:28.020 --> 00:22:29.600
that I wanted to talk about.

00:22:30.520 --> 00:22:32.860
So the Complete pytest course has been out for a while,

00:22:33.060 --> 00:22:35.780
and there's a couple things about it that are a little,

00:22:36.120 --> 00:22:38.720
that I'd really kind of like to change,

00:22:38.820 --> 00:22:39.760
so I'm working on some changes.

00:22:40.360 --> 00:22:42.380
First of all, if you see, if you go to the,

00:22:42.740 --> 00:22:45.120
and look at it, it says there's 162 lessons.

00:22:45.660 --> 00:22:51.220
It seems a little scary and the reason is because I've chopped it all up into, so there's

00:22:51.280 --> 00:22:57.400
16 chapters in the book, the course covers the entire book, 16 chapters, each video covers

00:22:57.640 --> 00:23:04.680
a section of a chapter and that's where, plus welcome videos and stuff, that's where the

00:23:04.680 --> 00:23:05.840
162 comes in.

00:23:06.120 --> 00:23:12.179
But that's a little, there's actually 162 videos which is a little intimidating, especially

00:23:12.180 --> 00:23:15.080
if you're looking at one and you kind of like,

00:23:15.320 --> 00:23:15.920
there's a lot here.

00:23:17.200 --> 00:23:19.900
But I mean, it's all good if you like to go

00:23:19.950 --> 00:23:22.840
in just like a few minutes at a time, that's great.

00:23:23.200 --> 00:23:25.860
But some people wanna just chunk through an entire chapter

00:23:25.980 --> 00:23:27.440
in like a lunch break or something.

00:23:28.060 --> 00:23:31.200
So the alternate version that I'm working on

00:23:31.720 --> 00:23:34.740
is chopping this up into just chapters.

00:23:35.120 --> 00:23:36.940
So most chapters will be one video.

00:23:37.920 --> 00:23:41.279
And then you can just chunk through

00:23:41.280 --> 00:23:43.720
like just watching one video, you can watch it in a weekend,

00:23:43.920 --> 00:23:45.640
or not a weekend, in like, you know,

00:23:45.840 --> 00:23:46.960
20 minutes or something like that.

00:23:47.580 --> 00:23:50.640
There's a couple chapters, chapter two and chapter three

00:23:51.080 --> 00:23:52.860
are pretty big, writing test functions,

00:23:53.160 --> 00:23:55.700
and then fixtures, pretty big concepts.

00:23:56.120 --> 00:23:57.920
So they're a little longer, so I'm chopping those

00:23:58.080 --> 00:24:01.940
not into one video, but like three videos.

00:24:03.040 --> 00:24:06.080
And so, when I get all done,

00:24:07.200 --> 00:24:10.100
the new version will be not 162 lessons,

00:24:10.260 --> 00:24:12.540
but like 20 lessons or something like that.

00:24:13.600 --> 00:24:15.600
And then I'll probably make that the default

00:24:15.860 --> 00:24:17.580
and I'll just have both of them available

00:24:17.780 --> 00:24:21.660
because some people might like the little more granularity

00:24:21.800 --> 00:24:24.760
and it's not more effort on me to have both of them around.

00:24:24.900 --> 00:24:26.200
So they'll both be around.

00:24:26.480 --> 00:24:27.440
Anyway, that's what I'm up to.

00:24:29.040 --> 00:24:29.200
- Cool.

00:24:30.220 --> 00:24:31.560
Yeah, I like the small little videos.

00:24:31.940 --> 00:24:34.060
I think it's a way better reference material.

00:24:34.220 --> 00:24:35.040
You don't wanna have to go like,

00:24:35.120 --> 00:24:37.760
where in that 15 minute video was the thing I wanted?

00:24:38.480 --> 00:24:39.620
- Yeah, that's the benefit.

00:24:39.940 --> 00:24:42.560
The other thing is I like to, for videos,

00:24:42.560 --> 00:24:45.560
I like to probably set them at like 1.2 speed

00:24:45.560 --> 00:24:49.640
or 1.3 speed the first time, or 1.25, maybe 1.4,

00:24:49.840 --> 00:24:52.160
to get an overview really quickly.

00:24:53.039 --> 00:24:55.220
And you have to reset that for every video,

00:24:55.380 --> 00:24:57.220
and that's somewhat a little annoying.

00:24:57.260 --> 00:24:57.800
- That's a hassle.

00:24:58.280 --> 00:24:58.380
- Yeah.

00:24:59.040 --> 00:24:59.860
- That is a hassle.

00:25:00.180 --> 00:25:01.480
All right, well let's see what I got for extra.

00:25:01.600 --> 00:25:03.520
I got an oldie, something fun here.

00:25:04.120 --> 00:25:07.640
So there was a Hacker News thread or Reddit thread.

00:25:08.440 --> 00:25:09.360
I'm gonna go with Hacker News.

00:25:09.520 --> 00:25:11.140
Pretty sure it was Hacker News talking about,

00:25:11.520 --> 00:25:12.820
hey, could some people recommend

00:25:13.960 --> 00:25:17.740
some cool, legit programmer fiction books?

00:25:18.520 --> 00:25:21.840
Right, like I want a spy thriller

00:25:22.040 --> 00:25:24.260
that has to do with programming but that's not stupid.

00:25:24.680 --> 00:25:27.220
Right, it's not like, whoa, this is VB6, I know that.

00:25:27.540 --> 00:25:29.080
I'm gonna track their IP, like, you know what?

00:25:29.180 --> 00:25:30.140
That's not how it works.

00:25:31.180 --> 00:25:34.160
More Mr. Robot, less Jurassic Park or whatever that was.

00:25:34.160 --> 00:25:34.640
I can't remember.

00:25:35.100 --> 00:25:37.960
So, the book that I thought was really cool

00:25:37.980 --> 00:25:40.060
I'll give a shout out to is by Mark Russinovich

00:25:40.120 --> 00:25:41.280
who is the CTO of Azure.

00:25:41.620 --> 00:25:43.300
And apparently I bought this book in 2012

00:25:43.500 --> 00:25:44.060
just to give you a sense.

00:25:44.160 --> 00:25:47.040
So it's not brand new, but it is a super cool series

00:25:47.340 --> 00:25:51.020
as long as you keep in mind like its computer world was 2012

00:25:51.799 --> 00:25:53.640
so people can check that out if they're interested.

00:25:53.960 --> 00:25:55.940
Also, Warp on Windows.

00:25:56.380 --> 00:25:58.560
I'm a big fan of Warp, the terminal.

00:25:59.000 --> 00:26:01.000
It's been working out super, super well.

00:26:01.360 --> 00:26:03.960
I tried ghost TT or ghost DD or whatever,

00:26:04.380 --> 00:26:04.940
however you say that.

00:26:06.140 --> 00:26:07.440
Just, I cannot do it.

00:26:07.560 --> 00:26:08.200
I can't do it.

00:26:08.360 --> 00:26:10.040
Like, it doesn't even let you like select

00:26:10.500 --> 00:26:11.680
text with hotkeys and stuff.

00:26:11.680 --> 00:26:13.960
It just puts like control H and stuff in there.

00:26:14.340 --> 00:26:17.020
And then until you can work with it as an editor,

00:26:17.600 --> 00:26:19.020
no, I can't do it.

00:26:19.440 --> 00:26:21.240
So, I mean, I know there's some way,

00:26:21.280 --> 00:26:23.280
like you can hold shift and arrow,

00:26:23.480 --> 00:26:26.020
but you can't do like control shift arrow to do

00:26:26.420 --> 00:26:27.600
like word by word.

00:26:27.920 --> 00:26:29.480
And you can't do, like you can do a home,

00:26:29.560 --> 00:26:30.520
but you can't do like shift home.

00:26:30.540 --> 00:26:32.560
These are like really weird, like editing and stuff

00:26:32.620 --> 00:26:33.900
where like some of it just starts putting

00:26:33.960 --> 00:26:35.740
escape characters into the thing.

00:26:36.360 --> 00:26:37.640
I don't remember exactly what it was

00:26:37.640 --> 00:26:38.840
'cause when I saw it, I'm like, okay,

00:26:39.220 --> 00:26:40.300
we'll come back to this some other time.

00:26:40.680 --> 00:26:41.880
Anyway, if you are on Windows

00:26:42.200 --> 00:26:43.180
and you're looking for a better terminal,

00:26:43.580 --> 00:26:46.100
and I know Windows has fewer options

00:26:46.400 --> 00:26:49.380
and less good options than the other places

00:26:49.780 --> 00:26:52.140
for a variety of terminals, like there's Windows Terminal,

00:26:52.280 --> 00:26:54.040
and then, I don't know, is there anything else?

00:26:54.080 --> 00:26:54.380
I'm not sure.

00:26:54.440 --> 00:26:55.760
There's definitely Command Prompt.

00:26:56.240 --> 00:26:58.460
- Well, PowerShell runs within Windows Terminal.

00:26:58.660 --> 00:27:01.500
Like you can run Git Bash or PowerShell

00:27:01.740 --> 00:27:03.840
or whatever the DOS-like stuff.

00:27:03.880 --> 00:27:05.640
You can run all that in Windows Terminal.

00:27:05.700 --> 00:27:06.540
- Oh, right, okay.

00:27:06.780 --> 00:27:07.140
- Right?

00:27:08.700 --> 00:27:10.040
You can do the same in Warp.

00:27:10.120 --> 00:27:11.520
You can choose, do I want PowerShell,

00:27:11.600 --> 00:27:13.260
do I want Git Bash or whatever.

00:27:13.680 --> 00:27:16.420
But the thing that is the outer bit of it,

00:27:16.700 --> 00:27:19.900
you know, the app itself, there's not many options.

00:27:20.000 --> 00:27:21.820
So this is a cool thing that people can check out.

00:27:21.860 --> 00:27:23.160
I'll link to the video 'cause it's fun,

00:27:23.340 --> 00:27:25.200
but you can just go to warp.dev or wherever it is.

00:27:25.880 --> 00:27:26.060
Okay.

00:27:27.060 --> 00:27:33.580
Our friends over at Teaching Python Podcast, they are participating in being

00:27:33.660 --> 00:27:37.060
part of the PyCon 2025 Education Summit.

00:27:37.680 --> 00:27:45.580
And they're pointing out that, Hey, the applications are going to be, you know,

00:27:45.840 --> 00:27:47.740
sending a proposal very, very soon.

00:27:48.280 --> 00:27:51.900
So that was, I think last Friday and today is Monday.

00:27:52.000 --> 00:27:54.840
So, just recently opened up and they said the main theme is,

00:27:55.400 --> 00:27:57.660
in the age of AI, how do we maintain the creative,

00:27:58.260 --> 00:28:00.120
empathetic, and critical thinking skills we need

00:28:00.120 --> 00:28:01.940
to make us human and great coders?

00:28:02.320 --> 00:28:03.640
We want to know, and so there's a whole bunch

00:28:03.700 --> 00:28:05.720
of ideas around this.

00:28:05.860 --> 00:28:09.360
So, we've got Kelly and Sean and a bunch of other people

00:28:09.400 --> 00:28:12.720
participating in this, so if that resonates with you,

00:28:12.760 --> 00:28:13.160
check it out.

00:28:13.400 --> 00:28:15.760
- No, I was just chuckling because even before AI,

00:28:15.920 --> 00:28:17.840
we hadn't figured that out as far as I could tell.

00:28:18.880 --> 00:28:20.220
- Yeah, I don't really know the answer,

00:28:20.300 --> 00:28:22.020
So I'm going to ask ChatGPT, I'll get back to you.

00:28:22.800 --> 00:28:22.900
[laughing]

00:28:22.900 --> 00:28:22.980
Okay.

00:28:23.940 --> 00:28:24.340
[laughing]

00:28:26.020 --> 00:28:27.720
Yeah, one more extra here real quick.

00:28:28.000 --> 00:28:32.740
I just noticed that Granian, which is powering Python by ZFM, by the way, and many, many other things,

00:28:33.380 --> 00:28:37.540
just came out with their 2.0 release right there, seven hours ago.

00:28:37.880 --> 00:28:39.680
How's that for fresh, shocking news?

00:28:39.880 --> 00:28:39.980
Breaking news.

00:28:39.980 --> 00:28:40.680
Breaking news.

00:28:42.419 --> 00:28:42.820
[imitating drum roll]

00:28:43.640 --> 00:28:46.320
As far as I can tell, there's a bunch of cool changes here.

00:28:46.320 --> 00:28:50.740
One thing that's not cool is as far as I can tell it doesn't run FastAPI apps.

00:28:50.900 --> 00:28:58.360
So if you have Gradient, powering your FastAPI app, you might test this before you just update.

00:28:58.600 --> 00:29:02.900
There's also breaking changes in the CLI of like how you specify certain constraints and stuff.

00:29:03.180 --> 00:29:06.080
That's easy enough to fix because it tells you this constraint such and such,

00:29:06.080 --> 00:29:12.600
but I think there's something going on where at least all of my FastAPI apps stopped working when I switched to this,

00:29:12.600 --> 00:29:16.240
but all the other ones like Cort and Flask and Pyramid all work fine.

00:29:16.440 --> 00:29:16.900
- Interesting.

00:29:17.340 --> 00:29:17.940
- Don't know why.

00:29:18.300 --> 00:29:21.420
And Cort is async first just like FastAPI.

00:29:21.500 --> 00:29:24.120
So I don't know what's going on, but they were not having it.

00:29:24.300 --> 00:29:27.900
So I just pinned the version to less than two for those

00:29:28.060 --> 00:29:29.660
until whatever happens here gets figured out.

00:29:29.740 --> 00:29:30.860
So there's just a little PSA.

00:29:31.140 --> 00:29:31.880
All right, with that.

00:29:32.780 --> 00:29:34.720
- So seven hours ago, you already tried it?

00:29:35.500 --> 00:29:36.100
- Not on purpose.

00:29:36.780 --> 00:29:38.400
I tried it three hours after it was released.

00:29:38.860 --> 00:29:40.140
I needed to ship something else,

00:29:40.200 --> 00:29:43.700
but my deployment process is check something in the Git

00:29:44.080 --> 00:29:45.780
and then have it go rebuild the Docker images

00:29:45.920 --> 00:29:46.640
and restart them.

00:29:47.140 --> 00:29:48.720
And that's all, check all the dependencies,

00:29:48.960 --> 00:29:50.040
is there anything we can update?

00:29:50.260 --> 00:29:54.280
Like, does Ubuntu have security fixes we need to apply?

00:29:54.560 --> 00:29:56.040
Can we update the web server

00:29:56.140 --> 00:29:57.700
in case there's a security fix for it?

00:29:57.780 --> 00:29:59.480
And then we'll rerun the dependencies

00:29:59.900 --> 00:30:01.060
and we'll restart it.

00:30:01.500 --> 00:30:02.620
And then it didn't restart,

00:30:02.680 --> 00:30:03.720
I'm like, wait a minute, what?

00:30:03.820 --> 00:30:05.660
Why, what's going on here?

00:30:05.760 --> 00:30:06.540
This is not good.

00:30:07.200 --> 00:30:08.559
So that's how I learned

00:30:08.560 --> 00:30:10.220
that there's a new release of "Granny."

00:30:10.580 --> 00:30:10.900
- Okay.

00:30:11.760 --> 00:30:12.080
- You know what I mean?

00:30:12.120 --> 00:30:14.440
It's not like I was like, "Oh, I gotta try it that quick."

00:30:15.180 --> 00:30:17.760
It tried itself on me and then it didn't go so well,

00:30:17.840 --> 00:30:19.060
so I scrambled to fix it.

00:30:19.260 --> 00:30:20.080
- Okay, got it.

00:30:20.140 --> 00:30:20.640
- Yeah, yep.

00:30:21.200 --> 00:30:22.440
Okay, joke?

00:30:23.040 --> 00:30:23.780
- I'd love a joke.

00:30:24.940 --> 00:30:25.540
- Tabs or spaces?

00:30:25.700 --> 00:30:27.080
This one has to do with tabs or spaces.

00:30:27.520 --> 00:30:28.900
I'll tell you a joke before the joke,

00:30:28.980 --> 00:30:31.720
a pre-joke, if you will, to get everyone in the mood.

00:30:31.820 --> 00:30:32.720
This is like the bad joke,

00:30:33.080 --> 00:30:34.360
the bad comedian that shows up

00:30:34.360 --> 00:30:35.640
before the one you actually came to see.

00:30:36.020 --> 00:30:38.940
So we were at PyCon, I don't know.

00:30:39.420 --> 00:30:40.820
I think this might've even been in Portland.

00:30:40.940 --> 00:30:41.780
This was a while ago.

00:30:42.120 --> 00:30:44.440
And there was some company that was clearly

00:30:44.920 --> 00:30:46.700
not very tuned into Python.

00:30:46.820 --> 00:30:48.600
They were just a coder company, right?

00:30:48.640 --> 00:30:50.360
And they were like coming to sell their coder tools

00:30:50.360 --> 00:30:51.140
to the Python people.

00:30:51.400 --> 00:30:54.200
And so as they wanted to make a spicy t-shirt

00:30:54.580 --> 00:30:58.320
and the spicy t-shirt said, "Tabs or spaces, fight."

00:30:58.320 --> 00:31:00.060
Like this is the stupidest shirt I've seen

00:31:00.340 --> 00:31:01.080
at the whole conference.

00:31:01.840 --> 00:31:03.380
I mean, tabs are basically disallowed.

00:31:03.420 --> 00:31:04.600
They're not exactly disallowed,

00:31:04.620 --> 00:31:05.780
but they're pretty much disallowed.

00:31:06.020 --> 00:31:07.940
- Like that's not an argument, it's over.

00:31:08.060 --> 00:31:10.160
- And you're like, you're trying to set up as a debate,

00:31:10.180 --> 00:31:13.200
like you could do two spaces, four spaces and fight,

00:31:13.520 --> 00:31:16.220
but you can't do tabs versus spaces at a Python conference.

00:31:17.200 --> 00:31:19.200
Anyway, but people are going around with shirts nonetheless.

00:31:19.660 --> 00:31:21.100
I think I got one to cut the lawn in.

00:31:21.420 --> 00:31:25.500
- Okay, well, on that topic, two spaces or four spaces?

00:31:25.980 --> 00:31:27.800
- Four, unless I'm doing JavaScript then two,

00:31:28.080 --> 00:31:29.720
'cause for some reason the tools seem to default

00:31:29.780 --> 00:31:31.020
to two for JavaScript, you?

00:31:32.360 --> 00:31:38.540
like four usually, but I'm noticing that I'm using two frequently as well.

00:31:38.900 --> 00:31:39.600
So, okay.

00:31:40.400 --> 00:31:41.120
- Very contrarian.

00:31:41.540 --> 00:31:41.640
Okay.

00:31:42.060 --> 00:31:45.060
You're an enigma wrapped in a fuzzy cloud.

00:31:45.100 --> 00:31:45.300
Okay.

00:31:46.100 --> 00:31:47.500
How about this for, this is the real joke.

00:31:47.580 --> 00:31:50.480
So I don't know if this is better or worse, but this is what people came for.

00:31:51.060 --> 00:31:51.620
Code puns.

00:31:52.200 --> 00:31:52.660
You ready, Brian?

00:31:53.080 --> 00:31:53.180
- Yeah.

00:31:53.880 --> 00:31:56.340
- A Python programmer walks into a bar and opens a tab.

00:31:56.660 --> 00:31:59.840
The bartender tells them to sit at the table since they will need four spaces.

00:32:04.799 --> 00:32:06.440
That's what I got for y'all.

00:32:10.440 --> 00:32:11.420
No it's hilarious, see?

00:32:11.520 --> 00:32:12.460
That's why people listen.

00:32:13.000 --> 00:32:14.140
Yeah, yeah, yeah.

00:32:14.320 --> 00:32:17.100
Oh no, I'm like advertising it poorly.

00:32:17.240 --> 00:32:18.240
That was hilarious, man.

00:32:18.420 --> 00:32:18.720
Good joke.

00:32:19.100 --> 00:32:20.320
Now, there's actually a bunch more here.

00:32:20.560 --> 00:32:22.000
We've talked about this place before, right?

00:32:22.260 --> 00:32:22.380
Yeah.

00:32:23.799 --> 00:32:24.320
Let's see.

00:32:24.680 --> 00:32:25.500
They're not all good.

00:32:25.860 --> 00:32:27.100
Why did the four loops stop running?

00:32:27.340 --> 00:32:28.000
It took a break.

00:32:28.799 --> 00:32:29.200
Yeah.

00:32:29.420 --> 00:32:30.860
How do you convert a JavaScript bug?

00:32:31.040 --> 00:32:33.380
You console it, like it's console log and so on.

00:32:34.140 --> 00:32:34.440
There we go.

00:32:38.000 --> 00:32:39.520
- No, it's good, thanks.

00:32:39.960 --> 00:32:40.880
- I think it was hilarious, I know.

00:32:41.540 --> 00:32:43.060
I hear the flaws, no, not really.

00:32:43.840 --> 00:32:44.720
But that's what I brought anyway.

00:32:47.160 --> 00:32:48.060
- Good talking with you again,

00:32:48.520 --> 00:32:49.900
and thanks everybody for listening.

00:32:50.600 --> 00:32:51.560
- Yeah, you bet, bye all.

