#422: You need 4 spaces

#422: You need 4 spaces

Released Monday, 3rd March 2025
Good episode? Give it some love!
#422: You need 4 spaces

#422: You need 4 spaces

#422: You need 4 spaces

#422: You need 4 spaces

Monday, 3rd March 2025
Good episode? Give it some love!
Rate Episode

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.

Rate

Join Podchaser to...

  • Rate podcasts and episodes
  • Follow podcasts and creators
  • Create podcast and episode lists
  • & much more

Episode Tags

Do you host or manage this podcast?
Claim and edit this page to your liking.
,

Unlock more with Podchaser Pro

  • Audience Insights
  • Contact Information
  • Demographics
  • Charts
  • Sponsor History
  • and More!
Pro Features