Episode Transcript
Transcripts are displayed as originally observed. Some content, including advertisements may have changed.
Use Ctrl + F to search
0:00
and welcome to Python Bites, where
0:02
we deliver Python news and headlines
0:04
directly to your earbuds. This is
0:06
episode 422, recorded March 3rd, 2025.
0:09
I am Michael Kennedy. And I am Brian Ockin. And
0:11
this episode is brought to you by us. Check
0:14
out Brian's PyTest courses. Check out
0:16
the ones over at Talk Python
0:19
Training. We're up to almost 475
0:21
hours, 275 hours.
0:24
We're not that many. 275 hours of courses
0:26
over at Talk Python. So are there many
0:28
tattoos from there? And Brian's book. and Patreon
0:30
supporters and all these things. Thank you so
0:32
much. Also, we're continuing to improve and involve
0:34
our newsletter, which gives you, I think, insights
0:37
into the episode that we maybe didn't explicitly
0:39
call out and certainly are not in the
0:41
show today. So head over to pythonbytes .fm,
0:43
click on newsletter, put in your email. We
0:46
will be kind and gentle to it, but
0:48
we'll send you cool stuff usually the day
0:50
of or after the day after the show.
0:52
Yeah. So with that said, Brian, how
0:55
do we start our show today? Let's start
0:57
it with a video, kind of. Wait, isn't
0:59
this already a video of people want to watch
1:01
it? Yeah. Yeah. Very mad
1:04
at you. Yeah. So I am trying
1:06
to add this to the stage. What's
1:08
going on? Oh, the wrong. Yeah. Anyway,
1:11
there we go. Technical difficulties
1:13
that won't make any sense to anybody listening.
1:16
So we don't normally cover video because
1:19
it's, I don't know. I don't know
1:21
why. But I don't watch a lot
1:23
of Python videos, I guess. But
1:26
this one is a do
1:28
not miss. So Hennick put
1:30
out a video called my
1:32
2025 UV -based Python project
1:34
layout for production apps. And
1:37
I was paid attention to this partly
1:39
to see what he was up to,
1:41
and I like UV. But
1:43
also, when you
1:46
watch it, his example is
1:48
a fast API app. in
1:51
his world, it's an app is usually
1:53
like, you know, really a website app.
1:56
And later he's going to go on
1:58
to talk about Docker, I think, because
2:00
this is a part one, part one
2:02
of a series. But, but this one's
2:04
already enough that I think it's really
2:06
useful. And especially in a lot of
2:08
this, some of the stuff I deal
2:11
with, I think of as an app
2:13
as anything that's packaged
2:15
kind of like it's not a
2:17
package. It's not something you put
2:19
on PyPI, but it's a
2:21
bunch of your own code that you
2:24
normally would have used a requirements .txt
2:26
file and I like his model
2:28
better. So I'm going to jump in.
2:30
I got a couple tabs because it's
2:33
kind of hard to like navigate. Anyway,
2:35
snapshot videos. So I stopped them
2:37
where I wanted to. So
2:39
the Video is great.
2:42
It's about 25 minutes long. It's pretty quick
2:44
to watch. Here
2:46
we've got the project layout.
2:49
So his project layout is
2:51
using a source layout. And
2:54
really, there's no requirements file. All
2:56
of the requirements are in the pyproject
2:59
.toml. And instead of a custom lock
3:01
file or one you manually do, he's
3:04
just recommending that you let UV take
3:06
care of a lot of the project
3:08
stuff. And actually, even with SOF, and
3:10
we'll take a look a little bit
3:13
more what's in pyproject .toml. But he's
3:15
recommending that you go ahead and check
3:17
in the UV lock. So if you're
3:19
letting UV handle your virtual environment, it's
3:21
going to create a lock file. And
3:24
if you commit that, then UV run
3:26
later will use that and use all
3:28
of the stuff in the lock file.
3:31
And you instead of running Python,
3:34
you clone the repo, run UV run
3:36
on your project. And it's going to grab
3:38
Everything out of the lock files. It's
3:40
just like pin dependencies. It's pretty sweet.
3:42
Yeah, I 100 % agree with him check
3:44
in the lock file And then you
3:46
don't also you don't even have to do
3:48
UV run if you don't want you
3:50
can just do UV sync And it
3:52
will also use the pin dependencies in lock
3:55
file and then because some systems They
3:57
required to run kind of with their setup
3:59
for example pyramid you need to use
4:01
p serve and it's like configuration file
4:03
or flask, you can do like flask run
4:05
or Django. So if you still want
4:07
to stick with that, you can just
4:09
do UV sync. So UV sync will grab
4:12
all the everything out of the lock
4:14
file then. Yes, exactly. And
4:17
I think it might even create the virtual
4:19
environment, though I haven't actually tried that. Yeah,
4:21
it does. Yeah. If you don't have one
4:24
already, it'll create it. And also, if you
4:26
already had one and it was out of
4:28
sync, Like UV sync, that's kind of what
4:30
the part of the sync does. If
4:33
somebody updated some of the requirements, so
4:35
the UV lock had changed,
4:38
then UV sync will rewrite
4:40
the virtual environment. Nice.
4:44
He's showing also that his version
4:46
of how to specify the Python
4:49
version is to just specify it
4:51
within your pyproject .toml, and UV
4:53
will grab that and install it
4:55
if necessary. You
4:59
know, also interesting discussion around version
5:01
because PyProject .tomo requires a version,
5:03
but with a lot of applications,
5:05
we don't really utilize the version
5:07
because it's just code that you're
5:09
pushing and running. So he said,
5:11
just set it. If you don't
5:13
care about the version, just set
5:15
it to zero and then people
5:17
will realize you're not using it.
5:19
So the world's most common version.
5:22
Yeah. And And then also a
5:24
discussion around the separation of dependency
5:26
groups that came in recently, that
5:29
UV handles nicely in PyProject
5:31
Tomo files. And that
5:33
allows you to separate your dependencies
5:36
based on really what the application
5:38
needs versus what you need for
5:40
development. And this will
5:42
work. Then you can run. If
5:44
you're in production, it won't install
5:46
your dependent. You're like PyTest and
5:48
stuff, but it will install everything
5:50
else. But when you're creating a
5:52
virtual. virtual environment locally to develop,
5:54
it'll grab those also. So very
5:56
cool to have all of this
5:58
together. And then build system,
6:01
I didn't really realize that you
6:03
could specify UV as a build
6:05
backend, and I'm going to have
6:07
to play with that. That's pretty cool. So how
6:09
are you muted? I put Hatchelain
6:11
in mind, and I believe
6:14
several people have pointed out that Hatchelain is
6:16
the default. And the reason when we played
6:18
with this the very, very first time it
6:20
didn't show up with any build back in
6:22
is because we created in application mode. But
6:24
I think if we created in package mode,
6:27
there's a way to say, well, what really
6:29
kind of project are you creating? Then it
6:31
specifies the build back in explicitly, I think.
6:33
So anyway, a lot of options
6:35
there. But yeah, very cool. Yeah. Actually,
6:38
just an enjoyable video, too. I like what
6:40
he's doing there. So check it out. Very
6:43
nice. Well, let's
6:45
talk. about async and
6:47
await. So there's this
6:50
cool project called AIO Limiter, an
6:52
efficient implementation of a rate limiter
6:54
for async IO. And this comes
6:57
to us from Martin Peters. Martin
6:59
Peters, at least at one point,
7:02
was the most prolific stack
7:04
overflow Python person. So that was
7:06
fun. And this project is
7:08
a something that got created as
7:11
a result of an answer on
7:13
Stack Overflow by him. So
7:15
not a big surprise. I'll
7:18
beat on the dead horse a little bit, Brian.
7:21
I feel like there's a really, there's
7:23
a big missing piece for async and
7:25
await in Python. And that is any
7:27
sort of mechanism or control or, or
7:30
understanding or adjustment or whatever of the
7:32
underlying running of async code in general.
7:34
Right. If I call, if I call
7:36
an async function and I say a
7:38
way to thing, how does it run?
7:41
Well, you don't know. It
7:43
might be running in an event loop that you've
7:45
created. It might be running in one that you,
7:48
a framework created. You don't, sometimes, often, most of
7:50
the time, let's say, you don't get a choice
7:52
on how that loop is created. For example, if
7:54
you're using fast API, fast API creates a loop
7:56
and says, here, you can use this one. Hope
7:59
you like it. You know
8:01
what I mean? Whereas systems
8:03
like .NET, they've got thread
8:05
pools and async .io. pools
8:07
and contexts and stuff that you can say, hey, on this
8:10
one, I want you to limit to 10. So if you're
8:12
doing work, just do 10 at a time. When you're done
8:14
with one, allow the other ones to come in, otherwise cue
8:16
them and just make them wait, right? Stuff like that is
8:18
kind of missing. So all these
8:21
projects are trying to backfill that kind of
8:23
functionality into Python's async in a way. And
8:25
this is cool. So it does give you,
8:27
like suppose you're working on a project and
8:30
you're using an external API, the API says
8:32
you have a rate limit of five per
8:34
second. If you go over that, we're going
8:36
to start failing. and telling you status code
8:39
429, too many requests, wait however
8:41
long and try again. But that becomes
8:43
like really janky, right? So with
8:45
this thing, what you can do is I
8:47
can create a rate limiter and say, I'm
8:50
willing to allow 100 calls within a 30
8:52
second window or the example I gave, five
8:54
calls within a one second window or whatever,
8:56
right? Something like that. And then you just
8:58
put that into a async with block and
9:01
then stuff that happens in that window will
9:03
be limited by this rate limit. Okay.
9:05
Cool, right? So it makes it really easy to
9:07
handle those kinds of things. But often
9:09
it's not like, I'm going to make all
9:12
of the calls here. You know what
9:14
I mean? I want all the
9:16
async calls in the system to be limited
9:18
in this way, not the ones that I'm
9:20
controlling the particular function of, which is sort
9:22
of the crux of my complaint that I
9:24
started with. But this is nice. You create
9:27
one of these somewhere, and then anywhere you
9:29
use this rate limit as a context manager,
9:31
it is subject. to that rate limiting. So
9:33
it doesn't have to be the same function.
9:35
It doesn't have to be all the codes
9:37
are happening at the same time within the
9:39
block. So, you know, that's a pretty nice
9:41
thing, right? As long as you just put
9:44
that in all the places you need it.
9:46
Like for example, one of the problems you
9:48
can do is you're getting too many requests.
9:50
You can overwhelm your database and because you're
9:52
awaiting and doing it asynchronously, you could just
9:54
keep feeding it to the database, even if
9:56
the database is slowing down and slowing down
9:58
and slowing down. So like in your data
10:01
access layer, you could just wrap all of
10:03
your queries in one of these things to
10:05
say, don't let more than, I know, 10
10:07
per second or whatever is reasonable for your
10:09
database. That's kind of low, but you know
10:11
what I mean? Like you can sort of
10:13
control that. So you might like have one
10:15
of these rate limiter for your database and
10:18
then maybe one for an external API or...
10:20
Yes, theoretically and they could be different, right?
10:22
Yeah, okay, that makes sense. Yeah,
10:24
anyway. Yeah, I thought this was
10:26
kind of cool. And people who are worried
10:28
about trying to solve that problem, then they
10:30
can use this as one of the tools
10:32
there. Computers
10:35
are so fast, sometimes we're like, it's too
10:37
fast, slow down a little bit. Yeah, it's
10:39
like, let's make it a lot of do
10:41
all the work and not wait on any
10:43
of it. Like, usually good, sometimes bad. Sometimes
10:46
bad. But the thing on the end doesn't
10:48
like it. Yep. Yeah, and out
10:50
in the audience, we got a, wow, cool,
10:52
says Aziz. I had this limit problem a
10:54
lot. Awesome. Hope it helps. Yeah. Hope it
10:57
limits your problems. It does limit.
10:59
It will limit your problems. What's
11:01
next? That was weak. So I want to
11:03
talk about spy stuff. So
11:06
Lucas Langa wrote an article
11:08
about spy stuff. Actually, a
11:10
peek into a possible future
11:12
of Python in the browser.
11:18
Kind of a fun article also, but a great picture as
11:20
well. Some cool pictures of the mountains. Anyway. And,
11:24
you know, he's, I trust what
11:26
he, what, I trust his opinion because
11:28
of his involvement with Python and everything,
11:30
but this is interesting about a
11:32
lot of the core Python people really
11:35
involved with thinking about the web. So
11:38
there's a section about looking back
11:40
on, I haven't read
11:42
this, but, or seen this, but apparently there was
11:44
a Gary Bernhardt talk about. the birth and death
11:47
of JavaScript. I'll have to go back and look
11:49
at that. And then
11:51
basically talking about the history of Python.
11:53
If you have not seen the birth
11:56
and death of JavaScript, it needs to
11:58
go to the top of your list.
12:00
The death of JavaScript is a seminal
12:02
video that is both hilarious and very,
12:04
very insightful. OK, well, JavaScript is part
12:07
of the joke. OK,
12:09
JavaScript. All right. Well,
12:11
then it goes on to talk about
12:13
Piedite and other things. And
12:16
and using NumPy and Cython
12:19
and stuff. But
12:21
the real thrust here
12:23
is a new research
12:25
project called SPI. S
12:27
capital S, capital P,
12:29
lower Y, I guess.
12:32
So that's SPI stuff. The
12:36
article says the SPI is a research
12:38
project in its early stages at the
12:40
moment. Don't attempt to use it yet.
12:42
Unless you plan to contribute, but maybe
12:45
you do plan to contribute It's both
12:47
incomplete implementation wise and design wise but
12:49
but so early stages, but it sounds
12:52
pretty cool So there's this this I
12:54
like the idea so there's this I'm
12:56
gonna jump down to the demo. See
12:58
if we can get it to play
13:01
Oh had video sound too, but I
13:03
don't think you hear that anyway There's
13:05
demo of it working of some shapes
13:08
shifting around and that's actually we're running
13:10
in the browser already But you just
13:12
can't. I guess it's not complete yet.
13:14
But this this idea of having having
13:17
things that look like Python. So when
13:19
you're when you're there's like blue code
13:21
and red code is the idea. And
13:24
the blue code is stuff that just
13:26
like acts like Python. And and that's
13:28
great for debugging and stuff. And because
13:30
you could people are used to writing
13:33
in Python. And then there's a
13:35
redshift model of because that's what we do
13:37
a lot is like whether we should compile
13:39
it or not. But this will like
13:42
pre -compute a lot of the
13:44
stuff that's blue into a pre
13:47
-compiled version. Anyway, all the little
13:49
compilation parts to make things run
13:51
faster. But I really like the
13:53
idea that you've got a level
13:55
where you're running it just as
13:57
pure Python and then you can
13:59
deploy it and it runs as
14:01
a compiled part. So anyway, I'm
14:03
probably getting this wrong at early
14:05
stages, but we've got links to
14:07
this article and then to the
14:09
spy project itself. which
14:12
a lot of activity just recently.
14:14
So anyway, I like that.
14:16
And mostly, I don't know why I brought this
14:18
up. The story
14:20
of Python and the web browser better
14:23
and better. So anyway. I
14:25
also bookmarked this article as something super
14:28
interesting that should, you know, might be
14:30
worth talking and reading up on. So
14:32
thanks for covering it. Yeah. If
14:35
you got a deeper, we're on the verge. mentioned we
14:37
could bring it up later again as well. Yeah, yeah,
14:39
it's early days, so maybe there'll be more news on
14:41
it. I'm very excited about
14:43
the possibility of Python in the browser.
14:47
It'll uncork some amazing stuff if
14:49
that really gets running seamlessly. And
14:52
really, I'm saying the browser, but really
14:55
what we're also meaning is that if
14:57
we could not have different front -end
14:59
and back -end languages, so
15:01
if we do all the dynamic front
15:04
-end stuff with Python, be cool. Yep,
15:06
exactly, exactly. So, I think
15:08
that the browser manufacturers could do
15:10
significantly more to make this better.
15:13
Yeah. For example, every
15:15
one of them ships a JavaScript runtime.
15:18
That's optimized, right? Not a single one
15:20
of them ships the WebAssembly version of
15:23
Ruby or the WebAssembly version of CPython,
15:25
you know, Pyodide. or the WebAssembly version
15:27
of .NET for Blazor or all these
15:29
things. And so all of those projects
15:32
are like, well, it'd be great to
15:34
use this, but it's really slow to
15:36
download the whole runtime on each page
15:39
separately. Every browser could say,
15:42
we will provide and keep up to
15:44
date as part of our binaries, or
15:46
just off of the internet or whatever
15:49
as you download it, a shared Python
15:51
runtime, a shared Ruby runtime, a shared
15:53
.NET runtime, and so on. And they
15:55
don't, right? All these
15:58
complaints about well the web front ends too
16:00
slow because you got to download all this
16:02
stuff like yes You do now, but it
16:04
could theoretically be that they say well We're
16:06
gonna support like an open sort of management
16:09
of these these binary these web assembly run
16:11
times that you might need to download Sure
16:13
the extras you got to download every time
16:15
like JavaScript, but the the core runtime of
16:17
10 megs will like update that with our
16:20
browser or just Yeah, as it changes on
16:22
the web. I wish they would do that.
16:24
Yeah, right. I mean you know for JavaScript
16:27
I mean, come on now. All right,
16:29
it sounds crazy, but at the same time, they do
16:31
it for JavaScript and they write their own. All
16:34
right, they wouldn't even have to write their own. They
16:36
just got to allow the running of others. Okay, enough
16:39
of that. Let's talk about reloading stuff in
16:41
the browser. Instead, that sounds fun. So there's
16:43
two projects I wanted to tell you about.
16:45
One is the big heavyweight does so much
16:48
stuff to help you write web applications, type
16:50
in the editor and have that stuff magically
16:52
change. For example, by default, if I run
16:54
a Flask app and I go over to
16:57
the... I run it and I open it
16:59
up in the browser and I see the
17:01
page I'm working on and then I go
17:03
over and I edit the Ginger template. I
17:06
hit save and I refresh the browser. Nothing
17:09
happens. I have to go back
17:11
to Flask, restart Flask. Go
17:14
back to the browser, reload the browser. Now
17:16
I can see my changes. You can level
17:18
that up one by going to Flask and
17:20
say you're running into bug mode. So if
17:22
you see any changes, please rerun Flask. and
17:24
reload the templates if I edit the templates.
17:27
Then you can just edit your thing, save
17:29
it, go over to your browser, hit refresh,
17:32
see the changes. But what would be nicer if
17:34
I could have like two thirds of my screen
17:36
be my editor, one third of my
17:38
screen be the web browser. And as I type,
17:40
I see stuff just changing on the page. So
17:42
if I put a CSS class on a thing,
17:45
I don't have to go to the other app
17:47
and do anything. It just literally just the changes
17:49
apply like every second or so, right? So
17:52
that's what this Relodium thing is. but it
17:54
does a lot. So I want
17:56
to put this out there for people as
17:58
a cool option. I'm not sure I'm going
18:00
to put it out there as a recommendation
18:02
yet. So let me tell you. So for
18:04
example, it will not just do the experience
18:07
I told you about, but it will actually
18:09
rerun every function. If you make
18:11
a change to a function, it will
18:13
rerun it and you can actually have
18:15
it doing like live profiling. So as
18:18
you, as you type there, it'll give
18:20
you a profiled output. The
18:22
thing and so on so if you kind
18:24
of want to explore it it gives you
18:27
like that idea more broadly so it works
18:29
There it comes with a pie charm plug
18:31
-in, which is what the little animation is
18:33
so you can actually see a visual representation
18:35
of Like the performance time and how it's
18:37
running and reworking and so on okay, so
18:39
that's pretty neat comes with an AI thing
18:41
I'm gonna skip that I don't know what
18:44
that is or care it has Yeah.
18:46
So generally, if you make a change to
18:49
a function, it will re -execute the
18:51
current function, providing immediate feedback. And if there's
18:53
an error, it doesn't die, it just
18:55
goes, well, okay, once you fix it, things
18:57
are going to be good and it'll
18:59
start working again. So it's kind of durable
19:02
to, to that, you know, and it'll
19:04
refresh files throughout the entire project, looking at
19:06
dependencies. So if I make a change
19:08
to like one bit, then it'll change the
19:10
others, you know, like with the import or
19:12
whatever. For Django, it does exactly what I
19:15
was telling you, like as you type, not
19:17
just as you type HTML, but as you
19:19
type Python. So the example they have
19:21
here is they're doing a query for all
19:24
objects and then they slice it to
19:26
do a limit, paging, limiting type of business.
19:28
And as they change the numbers in
19:30
the slice in Python, the
19:32
web browser is automatically updating the results
19:34
without them touching it. That's pretty cool.
19:36
Yeah, it's pretty cool, right? Yeah.
19:39
Similarly for Flask, it automatically reloads
19:41
Flask. But again, it says,
19:44
look, it'll hot reload the Flask app. But
19:46
if you just set flask debug to be
19:48
true, flask will already do that. You
19:50
know I mean? So the
19:52
one thing it doesn't do is it doesn't
19:55
refresh the page as you type on one
19:57
side, the stuff on the right doesn't change,
19:59
right? Another thing it does, it'll, for SQL
20:01
alchemy, because it's like running functions over and
20:04
over and over, it might start to do
20:06
insert, insert, insert to the database. So it
20:08
does these auto runs and transactions that roll
20:10
back so it doesn't tweak the database. Oh,
20:13
interesting. Yeah, and it also does hot reload
20:15
for pandas. So if you're messing with your
20:17
data frame or things like that, it'll just
20:20
automatically be updated as you type. All right,
20:22
pretty interesting, right, Brian? Yeah. Yeah, I don't
20:24
know if I talked about it before, but
20:26
just since people might want a less intrusive
20:29
version of that. So I have this project
20:31
called server hot reload over on GitHub, and
20:33
it's a single JavaScript file. And if you
20:36
just include the JavaScript file in your page,
20:38
it will give you the same functionality. or
20:41
web apps that will reload the template.
20:43
So, for example, if you just include
20:45
the JavaScript at the top of the
20:47
page, and then a Flask, if you
20:49
run it with Flastabug, or Pyramid automatically
20:51
reloads in debug mode, you can set
20:53
that in the config file, and I'm
20:55
sure you can do some more stuff
20:58
with Django. And then you just
21:00
browser on one side, code on the other,
21:02
and you just start typing, and off it
21:04
goes, and even detects if you set it
21:07
up right, or even, like, reload the page
21:09
if you change an image that was being
21:11
used in things like that. So super cool.
21:13
But this one, it doesn't go all crazy.
21:16
It doesn't require an IDE plugin and all
21:18
that kind of stuff. It basically what it
21:20
does is it looks at the response from
21:22
the server and says, is the hash of
21:25
the HTML changed? If yes, reload the page.
21:27
If it's not changed, then don't reload the
21:29
page, that kind of thing. So anyway, two
21:31
ways to basically work in your editor, start
21:34
typing and having some kind of output
21:36
web or in the reloading of other
21:38
places. It's automatically changing as you
21:41
type so you don't have to manage that.
21:43
You're just like, oh, what's this class? Oh,
21:45
that looks really great. No, we need more
21:47
padding here. So the server one probably doesn't
21:49
do the, like, if you change Python. Technically,
21:53
no. It doesn't do that. However, if you
21:55
set Flask to do that automatically and then
21:57
it re -requests the page, then yes, it
21:59
does. You know what I mean? So
22:02
if you're willing to use the
22:04
framework tools, then it does. OK.
22:07
OK. Very good. Cool. Yeah. But it's nowhere
22:09
near as intense, which I think for some
22:11
people is a drawback and other people is
22:13
a plus, depending on where you are. OK,
22:15
nice. All right. That's it for all of
22:18
our items, isn't it? Yeah, it
22:20
is. Well then, what have you got
22:22
for extras? I
22:24
got just a pet project of
22:26
mine that I wanted to talk
22:29
about. So the complete pie
22:31
test course has been out for a while. And
22:33
there's a couple of things about it that are
22:35
a little that I'd recommend. really kind of like
22:37
to change. So I'm working on some changes. First
22:40
of all, if you see, if you go to
22:42
the, and look at it, it says there's 162
22:44
lessons. That seems a little scary. And
22:47
the reason is because, is because I've
22:49
chopped it all up into, so there's
22:51
16 chapters in the book. The course
22:53
covers the entire book, 16 chapters. I've
22:55
checked each video covers a section of
22:58
a chapter. And that's where plus welcome,
23:00
like you know, welcome videos and stuff.
23:02
That's where the 162 comes in. But
23:04
Um, that's a little, there's actually 162
23:06
videos, which is a little intimidating. Um,
23:09
especially if, if you're, you're looking at
23:11
one and you kind of like, there's
23:13
a lot here. Um, uh, but I
23:15
mean, it's all good. If you, if
23:17
you like to go in just like
23:19
a few minutes at a time, that's
23:22
great. But some people want to just
23:24
chunk through an entire chapter and like
23:26
a lunch break or something. So the
23:28
alternate verse. Version that I'm working on
23:30
is chopping this up into just chapters.
23:33
So most chapters will be one video
23:35
and and then you can you can
23:37
just, you know, chunk through like just
23:39
watching one video. You can watch it
23:41
in a weekend or not a weekend
23:43
in like, you know, 20 minutes or
23:46
something like that. There's a
23:48
couple chapters, chapter two and chapter
23:50
three are pretty big writing test
23:52
functions and then fixtures, pretty big
23:55
concepts. So they're a little
23:57
longer. So I'm chopping those not into
23:59
one video, but like three videos. And
24:03
so when I get all
24:05
done, the new version
24:07
will be not 162 lessons, but
24:10
like 20 lessons or something like
24:12
that. And then I'll
24:14
probably make that the default and I'll just
24:16
have both of them available because some people
24:18
might like the little more granularity and it's
24:21
not more effort of me to have both
24:23
of them around. So they'll both be around.
24:25
Anyway, that's what I'm up to. Cool.
24:29
Yeah, I like the small little videos. I
24:32
think it's the way better reference material. You
24:34
want to have to go like, where in
24:36
that 18 minute video was the thing I
24:38
wanted? Yeah. Yeah, that's the benefit. The other
24:41
thing is I like to, for videos, I
24:43
like to probably set them at like 1
24:45
.2 speed or 1 .3 speed the first
24:48
time or 1 .25, maybe 1 .4 to
24:50
like get an overview really quickly. And
24:53
you have to reset that for every
24:55
video. And that's somewhat a little annoying.
24:57
That's a hassle. Yeah. Anyway, that is
24:59
a hassle. All right. Well, let's see
25:01
what I got for extras. I got
25:03
an oldie, something fun here. So there
25:05
was a hacker news thread or Reddit
25:07
thread. I'm gonna go with hacker news
25:09
pretty sure was hacker news talking about
25:11
hey could some people recommend some cool
25:13
legit programmer fiction books hmm right like
25:15
I want to I want to a
25:17
spy thriller that has to do with
25:19
programming but that's not stupid right it's
25:21
not whoa this is vb6 I know
25:23
that I'm gonna track their IP like
25:25
you know what that's not how it
25:27
works more mr. robot a less Jurassic
25:29
Park or whatever I was I can't
25:32
remember So, the book that I thought
25:34
was really cool, give a shout out
25:36
to is by Mark Rusunovich, who is
25:38
the CTO of Azure. And apparently I
25:40
bought this book in 2012, just to
25:42
give you a sense. So it's not
25:44
brand new, but it is a super
25:46
cool series. As long as you keep
25:48
in mind that like its computer world
25:50
was 2012. So people can
25:52
check that out if they're interested. Also,
25:54
Warp on Windows. I'm a big
25:56
fan of Warp. terminal. It's
25:59
been working out super, super well. I
26:01
tried GhostTT or GhostTT or whatever
26:03
you say that. Just
26:06
I cannot do it. I can't do it.
26:08
Like it doesn't even let you like select
26:10
text with hotkeys and stuff. It just puts
26:12
like control H and stuff in there. And
26:14
until you can work with it as an
26:16
editor. No, I can't do
26:18
it. So I mean, I know there's some
26:21
way like you can hold shift and arrow,
26:23
but you can't do like control shift arrow
26:25
to do. like word by word and you
26:27
can't do like you can do home but
26:29
you can do like shift all these are
26:32
like really weird like editing stuff where like
26:34
some of it just starts putting escape characters
26:36
into the thing. I don't remember exactly enough
26:38
what it was because when I saw it,
26:40
I'm like, okay, we'll come back to this
26:43
some other time. Anyway, if you are on
26:45
Windows, you're looking for a better terminal and
26:47
I know Windows has fewer options and less
26:49
good options than the other places for a
26:51
variety of terminals like there's Windows terminal and
26:54
then I don't know if there's anything else.
26:56
I'm not sure there's definitely a prompt. Well,
26:58
PowerShell runs within Windows Terminal. You can run
27:00
Git Bash or PowerShell or whatever the DOS
27:02
-like stuff. You can run all that in
27:05
Windows Terminal. You can
27:07
do the same in Warp. You can
27:09
choose. Do I want PowerShell? Do I
27:11
want Git Bash or whatever? But
27:14
the thing that is the outer bit of
27:16
it, the app itself. There's
27:19
not many options. So this is a cool thing that people can
27:21
check out. I'll link to the video because it's fun, but you
27:23
can just go to warp .dev or wherever it is. Okay.
27:26
Our friends over at Teaching Python
27:28
Podcast, they are
27:31
participating and being part
27:33
of the Python 2025
27:35
Education Summit. And
27:38
they're pointing out that, hey, hey,
27:40
hey, the applications are
27:42
going to be You
27:45
can send in a proposal very, very
27:47
soon. So that was, I
27:49
think, last Friday and today is Monday. So
27:51
just recently opened up and they said the
27:53
main theme is in the age of AI,
27:56
how do we maintain the creative empathetic and
27:58
critical thinking skills we need to make us
28:00
human and great coders? We want to know.
28:02
And so there's a whole bunch of ideas
28:05
around this. So we've got Kelly and Sean
28:07
and a bunch of other people participating in
28:09
this. So if that resonates with you, check
28:11
it out. No, I was just chuckling because
28:13
even before AI, we hadn't figured that out
28:16
as far as I could tell. Yeah,
28:19
I don't really know the answer, so I'm going to ask ChatGPTL to
28:21
get back to you. Okay. Yeah,
28:26
one more extra here real quick. I
28:28
just noticed that Grainian, which is powering Pythonbytes .fm,
28:30
by the way, and many, many other things, just
28:33
came out with their 2 .0
28:35
release right there seven hours ago.
28:37
How's that for French? Breaking news.
28:40
Breaking news. As
28:43
far as I can tell, there's a bunch of
28:45
cool changes here. One thing that's not cool is
28:47
as far as I can tell, it doesn't run
28:50
fast API apps. So if you
28:52
have gradient powering your fast API app,
28:54
you might test this before you just
28:56
update. There's also breaking changes in the
28:58
CLI of like how you specify certain
29:00
constraints and stuff. That's easy enough to
29:02
fix because it tells you this constraint
29:04
such and such, but I think there's
29:06
something going on. where at least all
29:08
of my FastAPI apps stopped working when
29:10
I switched to this. But all the
29:12
other ones, like Kort and Flask and
29:14
Pyramid, all work fine. Interesting. Weird. Don't
29:16
know why. And Kort is async first,
29:18
just like FastAPI. So I don't know
29:20
what's going on, but they were not
29:22
having it. So I just pinned the
29:24
version to less than two for those
29:26
until whatever happens here gets figured out.
29:28
So there's just a little PSA. All
29:30
right, with that. So seven
29:33
hours ago, you've already tried it? Not
29:35
on purpose. I tried it three
29:37
hours after it was released. I needed to
29:39
ship something else, but my deployment process is
29:42
check something in to get and then have
29:44
it go rebuild the Docker images and restart
29:46
them. And that's all check all
29:48
the dependencies. Is there anything we can update
29:50
like as a boom to have like security
29:52
fixes we need to apply? Can we update
29:55
the web server in case there's a security
29:57
fix for it? And then we'll rerun the
29:59
dependencies and we'll like restart it. And then
30:01
it didn't restart. I'm like, wait a minute,
30:03
what? Why? What's going on here? This is
30:05
not good. So that's how I
30:08
learned that there's a new release of Grandia.
30:10
Yeah. Okay. You know what I mean? It's
30:12
not like I was like, oh, I got to try it that quick. It
30:15
tried itself on me and then it didn't
30:17
go so well. So I scrambled to fix
30:19
it. Okay. Yeah. Yeah. Okay.
30:22
Joke. I'd love a joke. Tabdra
30:25
Spaces. This one has to do with Tabdra Spaces.
30:27
I'll tell you a joke before the joke. A
30:29
pre -joke, if you will, to get everyone in
30:31
the mood. This is like the bad joke. the
30:33
bad comedian that shows up before the one you
30:35
actually came to see. So we were at PyCon,
30:38
I don't know. I think this might have
30:40
even been in Portland. This was a while
30:42
ago. And there was some company that was
30:44
clearly not very tuned in to Python. They
30:47
were just a coder company, right? And they
30:49
were like coming to sell their coder tools
30:51
to the Python people. And so is they
30:53
wanted to make a spicy t -shirt. And
30:55
the spicy t -shirt said tabs are spaces
30:57
fight. This is the stupidest shirt I've seen
31:00
at the whole conference. I mean,
31:02
tabs are basically disallowed. They're not exactly disallowed,
31:04
but they're pretty much disallowed. Like, that's not
31:06
an argument. It's over. And you're like, you're
31:08
trying to set up as a debater. Like,
31:10
you could do two spaces, four spaces, and
31:13
fight, but you can't do tabs versus spaces
31:15
at a Python conference. Yeah. Anyway, but people
31:17
are going around those shirts nonetheless. I
31:20
think I got one to cut the lawn
31:22
in. Okay. Well, let's, on that topic, two
31:24
spaces or four spaces? Four. Unless
31:26
I'm doing JavaScript then too, because for some reason
31:28
the tools seem to default to two for JavaScript.
31:30
You? Like four
31:33
usually, but I'm noticing that
31:35
I'm using two frequently as
31:38
well. OK. Very
31:40
contrary. OK. You're an enigma
31:42
wrapped in a fuzzy cloud.
31:44
OK. How about this first? This
31:46
is the real joke. So I don't know if this is better
31:48
or worse, but this is what people came for. Code
31:51
puns. You ready, Brian? Yeah. A
31:53
Python programmer walks into a bar and opens
31:55
a tab. The bartender tells them to sit
31:57
at the table since they will need four
31:59
spaces. That's
32:04
That's what I got for y 'all. No
32:10
it's hilarious. See, this is why people listen.
32:13
Yeah, yeah, yeah. Oh no, I'm like I'm
32:15
a pair of poorly. That was hilarious, man.
32:17
Good joke. Now, there's actually a
32:19
bunch more here. We've talked about this
32:21
place before, right? Yeah. Let's
32:23
see. They're not all good. Why did the four
32:26
loops stop running? It took a break. Yeah.
32:28
How do you comfort a JavaScript bug? You
32:31
console it, like console log and so
32:33
on. There we go. No,
32:37
it's good. Thanks. It was hilarious,
32:40
I I know. I hear the flaws. No,
32:42
not really. But that's what
32:44
I brought anyway. No. Good
32:47
talking to you again, And thanks
32:49
everybody for listening. Yeah, you you bet.
32:51
Bye all. all.
Podchaser is the ultimate destination for podcast data, search, and discovery. Learn More