WEBVTT

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

00:00:04.800 --> 00:00:12.660
This is episode 411 recorded. We got the 411 today. 411 recorded November 25th, 2024.

00:00:12.660 --> 00:00:13.940
And I'm Brian Okken.

00:00:13.940 --> 00:00:15.060
And I'm Michael Kennedy.

00:00:15.060 --> 00:00:18.160
And this episode is brought to you by us.

00:00:18.160 --> 00:00:25.440
So we have links in the show notes, but check out Talk Python Training and Pythontest.com for some courses.

00:00:25.440 --> 00:00:28.480
And Patreon supporters, thank you for sticking it out with us.

00:00:29.280 --> 00:00:43.300
Also, we have lots of links in the show notes for connecting with us on social media because we've got links for Fosstodon on Mastodon and also Bluesky for all of us here.

00:00:43.300 --> 00:00:47.100
We've got Python Bytes and Brian Okken and M. Kennedy.

00:00:47.100 --> 00:00:49.540
M. Kennedy is at mkennedy.codes.

00:00:49.540 --> 00:00:51.120
So check that out on Bluesky.

00:00:51.120 --> 00:00:52.500
But all the links are in the show notes.

00:00:52.500 --> 00:00:55.260
And thank you, everyone, for showing up for the live show.

00:00:55.260 --> 00:00:57.740
I love having you guys here and commenting.

00:00:58.560 --> 00:01:01.500
If you're listening later, we thank you also.

00:01:01.500 --> 00:01:03.920
But if you'd like to listen sometimes.

00:01:03.920 --> 00:01:08.120
It's usually 10 a.m. Pacific time, sometimes other times.

00:01:08.120 --> 00:01:12.300
And you can go to pythonbytes.fm/live to get that.

00:01:12.720 --> 00:01:25.520
And finally, if you are listening and you're wondering about any link that we cover in the show, you can go to our page, the notes page on pythonbytes.fm.

00:01:25.520 --> 00:01:28.960
But you can also click on the link to get in the newsletter.

00:01:28.960 --> 00:01:31.580
And we'll just send you those links right in your email inbox.

00:01:31.960 --> 00:01:33.660
I have two more thoughts in there really quick, Brian.

00:01:33.660 --> 00:01:35.100
We haven't talked about this before.

00:01:35.100 --> 00:01:35.320
Okay.

00:01:35.320 --> 00:01:36.600
I think the newsletter is awesome.

00:01:36.600 --> 00:01:40.680
People seem to be really enjoying it and connecting with it, the people who are subscribers there.

00:01:40.900 --> 00:01:43.820
But I don't even want to necessarily say this out loud to encourage it.

00:01:43.820 --> 00:01:46.600
But if you don't listen to the show, you maybe miss one or something.

00:01:46.600 --> 00:01:48.400
You're still going to get those in your inbox.

00:01:48.400 --> 00:01:50.120
And you can just peruse through real quick.

00:01:50.120 --> 00:01:52.020
Oh, look at these two interesting things that they found.

00:01:52.020 --> 00:01:52.860
That's number one.

00:01:52.960 --> 00:01:55.280
Number two, this is also all of the stuff.

00:01:55.280 --> 00:01:57.420
Our show notes are super detailed.

00:01:57.420 --> 00:02:03.400
And so people put our RSS feed for the podcast into their regular RSS reader.

00:02:03.400 --> 00:02:05.160
It's real similar as well.

00:02:05.160 --> 00:02:13.540
So there's reason to add this RSS feed to maybe reader or whatever feed bin or whatever you're using outside of just listening to the podcast.

00:02:13.540 --> 00:02:14.660
That's a great hack.

00:02:14.660 --> 00:02:15.580
I like that.

00:02:15.580 --> 00:02:18.580
Speaking of hacking, you want to talk about hacking?

00:02:18.580 --> 00:02:20.200
Yeah, you hacked some website.

00:02:20.200 --> 00:02:22.380
I hacked some website hard.

00:02:22.660 --> 00:02:23.540
I hacked it hard.

00:02:23.540 --> 00:02:27.800
And Python Bytes is on the docket to get the same hacking.

00:02:27.800 --> 00:02:35.140
So for as long as there has been a Talk Python and for as long as there's been a Python Bytes, they've been running on Pyramid.

00:02:35.140 --> 00:02:37.760
The Pyramid web framework created by Chris McDonough.

00:02:37.760 --> 00:02:39.120
Super cool framework.

00:02:39.120 --> 00:02:40.200
I really, really love it.

00:02:40.200 --> 00:02:44.840
But the truth is, the sad truth is, it's just not getting updates these days.

00:02:44.840 --> 00:02:48.860
So if you want to do async programming, you have to do async programming.

00:02:48.860 --> 00:02:50.300
Sometimes it's hard to avoid it.

00:02:50.300 --> 00:02:51.040
It's not supported.

00:02:51.040 --> 00:02:52.060
It doesn't support types.

00:02:52.360 --> 00:02:53.540
It doesn't do a lot of things.

00:02:53.540 --> 00:03:03.420
And even though it's great and simple, it felt kind of like a bit of a liability to be having all of our code written on frameworks that don't really get updates.

00:03:03.420 --> 00:03:05.680
So I rewrote Talk Python.

00:03:05.680 --> 00:03:07.380
First, talkpython.fm.

00:03:07.380 --> 00:03:07.940
Not the courses.

00:03:07.940 --> 00:03:08.740
Not Python Bytes.

00:03:08.740 --> 00:03:09.780
Just Talk Python.

00:03:09.780 --> 00:03:12.080
Because it's a medium-sized level of complexity.

00:03:12.080 --> 00:03:13.400
More complex than Python Bytes.

00:03:13.400 --> 00:03:17.400
Way less complex than the course section e-commerce website.

00:03:17.400 --> 00:03:19.720
Just to see how would that go.

00:03:19.720 --> 00:03:21.260
Is this a good idea or a bad idea?

00:03:21.260 --> 00:03:23.260
Turns out it's a pretty awesome idea.

00:03:23.360 --> 00:03:24.860
So I rewrote Talk Python.

00:03:24.860 --> 00:03:25.640
This is the topic.

00:03:25.640 --> 00:03:26.540
In court.

00:03:26.540 --> 00:03:30.060
And I wrote up a long post of my thoughts on it.

00:03:30.060 --> 00:03:31.180
Why did I do this?

00:03:31.180 --> 00:03:32.360
What did I consider?

00:03:32.360 --> 00:03:34.660
A lot of people are like, why didn't you consider framework X?

00:03:34.700 --> 00:03:36.180
You're crazy not to consider that.

00:03:36.180 --> 00:03:37.820
I'm like, I did consider that.

00:03:37.820 --> 00:03:40.400
And I wrote it down why I didn't end up picking it.

00:03:40.400 --> 00:03:45.180
So if people are thinking about changing frameworks, here's a nice write-up of an example.

00:03:45.180 --> 00:03:51.280
Even if you're thinking about async flask, aka court, for now, until those get merged, if they ever get merged.

00:03:51.280 --> 00:03:51.920
It's really cool.

00:03:51.920 --> 00:03:56.720
Like, for example, our database layer is Beanie, which is Pydantic plus MongoDB.

00:03:56.720 --> 00:03:57.860
Super awesome.

00:03:57.860 --> 00:03:59.860
It only supports async code.

00:03:59.860 --> 00:04:00.480
That's it.

00:04:00.480 --> 00:04:02.560
Pyramid only supported synchronous code.

00:04:02.880 --> 00:04:11.700
So I had to write this janky translation layer that would curry every request over to an async thing, wait for its response, and then turn it back into async request.

00:04:11.700 --> 00:04:14.180
There was, like, weirdness that was there, right?

00:04:14.180 --> 00:04:15.960
And I'm just like, could I just not do this?

00:04:15.960 --> 00:04:16.720
You know?

00:04:16.720 --> 00:04:21.620
And so I went to solve that technical debt issue that's been dragging around for a long time.

00:04:21.620 --> 00:04:22.280
Chose court.

00:04:22.280 --> 00:04:23.560
So a few things.

00:04:23.560 --> 00:04:25.100
First of all, what did I consider?

00:04:25.100 --> 00:04:30.420
I considered FastAPI, Litestar, as in lightstar.dev, super cool framework.

00:04:30.680 --> 00:04:37.340
If you wanted something like FastAPI but kind of batteries included, like Django, Litestar is the winner.

00:04:37.340 --> 00:04:38.840
Litestar was really close.

00:04:38.840 --> 00:04:40.460
FastAPI was a real contender.

00:04:40.460 --> 00:04:43.940
Django, you always got to consider Django, but decided not to go with that.

00:04:43.940 --> 00:04:50.320
Hugo, actually, I consider, like, what do you think, how much of our site do you think we could rewrite in just a static site generator like Hugo?

00:04:50.320 --> 00:04:51.360
I think a lot of it.

00:04:51.360 --> 00:04:56.460
Yeah, I was actually thinking about doing testing code over again in Hugo at some point.

00:04:56.460 --> 00:04:56.820
Yeah.

00:04:56.820 --> 00:05:04.740
By the way, this site that we're looking at here with the blog post, this is a sub-Hugo site within the court site in Talk Python, by the way.

00:05:04.740 --> 00:05:05.440
Wow.

00:05:05.680 --> 00:05:06.380
I think it's really great.

00:05:06.380 --> 00:05:17.280
But there's certain things, like on Talk Python, there's a guest list, and there's all the episodes, and there's the analytics of who downloaded which episode, and then who sponsors those different episodes.

00:05:17.280 --> 00:05:18.580
And there's ad dashboard.

00:05:18.580 --> 00:05:22.140
There's, like, a bunch of stuff that's not real obvious when you're looking at it from the outside.

00:05:22.240 --> 00:05:24.500
Oh, it's just like a blog kind of with attachment.

00:05:24.500 --> 00:05:30.360
Like, it's actually way more complicated on the sort of iceberg part that people don't see, and I decided not to do that.

00:05:30.360 --> 00:05:32.380
And, of course, Flask, which is interesting.

00:05:32.380 --> 00:05:38.660
So, anyway, I think FastAPI is awesome, but it's really focused on APIs, though you can make it work for websites.

00:05:38.660 --> 00:05:41.700
I don't think it's primarily the thing for websites, right?

00:05:41.700 --> 00:05:45.980
One of my goals here, by the way, was I want a super popular framework.

00:05:45.980 --> 00:05:50.260
I want one where if you say, hey, I wrote my website in this.

00:05:50.260 --> 00:05:51.780
What framework did you choose?

00:05:51.840 --> 00:05:53.620
There's a real good chance somebody says, me too.

00:05:53.620 --> 00:05:57.580
You know, and Pyramid, just as much as I love it, didn't check that box these days.

00:05:57.580 --> 00:06:04.920
And I also would have put Cord in that category, except for the fact that it's really maintained by the Flask people now.

00:06:04.920 --> 00:06:05.900
Yes, exactly.

00:06:05.900 --> 00:06:09.140
I almost didn't consider Cord at all, and I ended up going with it.

00:06:09.140 --> 00:06:14.780
And that's because I talked to David Lord about how it's been brought into the same organization as Flask.

00:06:14.780 --> 00:06:17.320
They're working, like, they're both contributing to both.

00:06:17.320 --> 00:06:21.660
There's attempts to sort of bring Cord into Flask properly.

00:06:21.660 --> 00:06:23.060
So maybe one day they'll go over.

00:06:23.060 --> 00:06:31.360
And if I change my mind, literally all I have to do is find and replace lowercase Flask and uppercase Cort with uppercase Flask.

00:06:31.360 --> 00:06:32.680
And it's back to Flask, right?

00:06:32.680 --> 00:06:34.920
It's a very, very small tie-in.

00:06:34.920 --> 00:06:35.440
You know what I mean?

00:06:35.680 --> 00:06:39.120
So for that reason, I felt like Cort was worth consideration.

00:06:39.120 --> 00:06:39.480
Okay.

00:06:39.480 --> 00:06:43.560
So FastAPI, awesome, obviously, but too API-focused.

00:06:43.560 --> 00:06:46.280
Same thing for Litestar, also not as that popular.

00:06:46.280 --> 00:06:51.120
It's more popular than Pyramid, but it's not in the, of course you're using that.

00:06:51.120 --> 00:06:52.100
Django is awesome.

00:06:52.340 --> 00:07:04.860
I mean, it's actually, I learned by doing this research, going through the PSF, JetBrains, Python developer survey, that if you look at the most popular framework, Flask is to a decimal point more popular than Django.

00:07:04.860 --> 00:07:12.020
But if you look at web developers who use a web framework, Django is more than twice as popular than Flask.

00:07:12.020 --> 00:07:13.200
That's pretty interesting, right?

00:07:13.200 --> 00:07:13.700
Yeah.

00:07:13.920 --> 00:07:16.820
Yeah, so a lot of machine learning models or something running there.

00:07:16.820 --> 00:07:20.780
Anyway, I go through why I'm not a huge fan of, didn't want to adopt.

00:07:20.780 --> 00:07:22.560
Django, you can read that up if you care to.

00:07:22.560 --> 00:07:24.700
I think Hugo's sites will be so neat.

00:07:24.700 --> 00:07:26.240
They're like, they can't go down.

00:07:26.240 --> 00:07:32.460
Technically, the data center can go down, but there's no runtime reason that a static site goes down, and that's pretty glorious.

00:07:32.460 --> 00:07:35.700
So I did the upgrade in two steps.

00:07:35.700 --> 00:07:42.700
I first said, let's go and rewrite everything in Cort, but just keep the synchronous code there.

00:07:42.780 --> 00:07:46.780
Because one of the big challenges is to rewrite the entire stack to be async, right?

00:07:46.780 --> 00:07:52.180
And so let's just get it running the way it is, but on the Cort framework, aka Flask, not Pyramid.

00:07:52.180 --> 00:07:57.660
So that took about a day, maybe like a long day, 10 hour day or something, you know?

00:07:57.660 --> 00:07:59.120
Got that bad boy knocked out.

00:07:59.120 --> 00:08:06.140
And then, you know, that was 2,280 lines changed, 3,000 lines of code deleted for that part.

00:08:06.140 --> 00:08:07.500
That is a good chunk.

00:08:07.500 --> 00:08:10.460
And then I rewrote it in async.

00:08:10.600 --> 00:08:17.220
After I got that all tested and deployed, like immediately, that's another 1,600 lines of code, 1,700 lines of code changed.

00:08:17.220 --> 00:08:19.220
But yeah, awesome performance.

00:08:19.220 --> 00:08:25.920
Okay, so about a day to convert to Cort, and then you went to async.

00:08:25.920 --> 00:08:27.060
How long to do that?

00:08:27.060 --> 00:08:31.640
I'd say maybe eight hours, a slightly, six hours, six to eight hours, let's say six hours.

00:08:31.640 --> 00:08:34.640
Less than a hard day, like a regular day of work.

00:08:34.640 --> 00:08:37.600
Not a, I'm done for the day.

00:08:37.600 --> 00:08:41.600
But yeah, we're talking, you know, five times faster performance.

00:08:41.980 --> 00:08:43.920
That's pretty, that's pretty awesome, actually.

00:08:43.920 --> 00:08:44.560
That's pretty good.

00:08:44.560 --> 00:08:45.720
Yeah, it's really, really nice.

00:08:45.720 --> 00:08:47.260
And I was able to get rid of that.

00:08:47.260 --> 00:08:50.960
And a lot of that, like half of that speed is from this, okay, you've got a request.

00:08:50.960 --> 00:08:54.180
Send it over to some async background thread that can async run it.

00:08:54.180 --> 00:08:55.280
Wait for the response.

00:08:55.280 --> 00:08:56.680
Okay, I got the response stash.

00:08:56.680 --> 00:09:01.620
Grab the response back and then send it back over to the sync reverse version to return.

00:09:01.720 --> 00:09:04.320
Like all of that coordination added a lot.

00:09:04.320 --> 00:09:09.560
Not a lot of CPU pounding overhead, but just delays here and there, you know what I mean?

00:09:09.560 --> 00:09:09.960
Yeah.

00:09:09.960 --> 00:09:11.080
Anyway, that's it.

00:09:11.080 --> 00:09:15.460
And finally, if you have a whole bunch of different pages, you want to make sure they're not broken.

00:09:15.460 --> 00:09:20.580
The way that I tested that most of it wasn't broken was I just went to the sitemap, which

00:09:20.580 --> 00:09:22.040
has a thousand pages in it.

00:09:22.040 --> 00:09:27.160
And I just wrote a Python program to just request every single URL in the sitemap and make sure

00:09:27.160 --> 00:09:29.560
it didn't 404 or 500 or anything like that.

00:09:29.560 --> 00:09:30.940
The all passed, push to production.

00:09:30.940 --> 00:09:31.400
Let's go.

00:09:31.660 --> 00:09:35.040
So did you already have a list of all the links or did you?

00:09:35.040 --> 00:09:35.340
Yeah.

00:09:35.340 --> 00:09:41.240
Because you generally want a sitemap for SEO and Google and Bing and all those things because

00:09:41.240 --> 00:09:45.220
that's what they use to discover like how much of our site can we index and what might we

00:09:45.220 --> 00:09:49.360
miss if you're not directly linking to it, but you want to make it known basically, right?

00:09:49.360 --> 00:09:53.200
So over here in the sitemap, we've got like, you know, check out the scroll bar.

00:09:53.200 --> 00:09:55.000
You can just grab all the links out of there.

00:09:55.000 --> 00:09:55.600
Exactly.

00:09:55.600 --> 00:09:56.560
So I take each one of those.

00:09:56.560 --> 00:09:58.780
So here's the one catch.

00:09:58.780 --> 00:10:00.760
One person ran into an issue.

00:10:01.600 --> 00:10:02.780
Oh man, I missed that one.

00:10:02.780 --> 00:10:05.180
And it's when you submit forms, right?

00:10:05.180 --> 00:10:09.220
The page that is shown when something is processed and submitted.

00:10:09.220 --> 00:10:10.960
I got one or two errors there.

00:10:10.960 --> 00:10:15.180
One little admin thing that only affected me, but somebody signed up for the mailing list.

00:10:15.180 --> 00:10:17.900
The mailing list has a page that's special if you sign up successfully.

00:10:17.900 --> 00:10:18.600
So thanks.

00:10:18.600 --> 00:10:19.580
And here's a few other things.

00:10:19.980 --> 00:10:22.320
Somehow I forgot to check the result of that.

00:10:22.320 --> 00:10:26.340
And there was some kind of bug in there that was easy to fix, but hard to discover.

00:10:26.340 --> 00:10:28.240
Ooh, links not in the sitemap.

00:10:28.240 --> 00:10:28.860
Yeah.

00:10:28.860 --> 00:10:29.280
Yeah.

00:10:29.280 --> 00:10:33.340
Or they might even be there, but you've got to do an HTTP post with data to discover them.

00:10:33.340 --> 00:10:36.440
Not a get because get will show the form, but it won't process the form.

00:10:36.440 --> 00:10:37.660
You know, that was what it was.

00:10:37.660 --> 00:10:38.220
Okay.

00:10:38.220 --> 00:10:43.600
I forgot to await something in the resulting post handler, basically, is what it was.

00:10:43.600 --> 00:10:44.160
Oh, nice.

00:10:44.160 --> 00:10:47.800
You have an interactive user base so they can let you know.

00:10:48.520 --> 00:10:48.920
Exactly.

00:10:48.920 --> 00:10:52.520
Century sent me a little message that said, you know what?

00:10:52.520 --> 00:10:54.480
There's a crash.

00:10:54.480 --> 00:10:55.640
Oh, okay.

00:10:55.640 --> 00:10:56.060
Yeah.

00:10:56.060 --> 00:10:56.980
Anyway, very cool.

00:10:56.980 --> 00:11:02.240
So hopefully, you know, I kind of want an extra detail because, yeah, I think it's just on its own.

00:11:02.240 --> 00:11:07.420
It's interesting, but I think more so the reason I wanted to cover this is I think it's relevant for other people who are like,

00:11:07.420 --> 00:11:12.500
oh, you know, we are on, you know, cherry pie and maybe we shouldn't be anymore.

00:11:12.500 --> 00:11:16.740
Maybe we should pick another one of the top three out of the list like Michael did.

00:11:16.740 --> 00:11:19.260
And I don't know, I'm sure it'll help some people on this journey.

00:11:19.260 --> 00:11:20.080
Yeah, cool.

00:11:20.080 --> 00:11:20.560
Nice.

00:11:20.560 --> 00:11:21.200
Thanks.

00:11:21.200 --> 00:11:23.780
Well, I want to talk about PyPI a little bit.

00:11:23.780 --> 00:11:26.340
PyPI now supports.

00:11:26.340 --> 00:11:27.920
You want to make an attestation about it?

00:11:27.920 --> 00:11:29.720
I don't even know what that word means.

00:11:29.720 --> 00:11:33.760
But PyPI now supports digital attestation.

00:11:33.760 --> 00:11:36.040
Yeah, okay.

00:11:36.040 --> 00:11:36.800
What does that mean?

00:11:36.800 --> 00:11:39.720
Well, I'm not sure what it really means, but it's a supply chain thing.

00:11:39.720 --> 00:11:46.360
So PyPI package maintainers can now publish signed digital attestations when publishing.

00:11:46.640 --> 00:11:50.640
In order to further increase trust in the supply chain security of their projects.

00:11:50.640 --> 00:11:52.320
That sounds cool.

00:11:52.320 --> 00:12:02.040
Additionally, there's a new API to new APIs available for consumers and installers to verify published attestations.

00:12:02.040 --> 00:12:02.800
Oh, my God.

00:12:02.800 --> 00:12:03.900
This sounds like a lot of work.

00:12:03.900 --> 00:12:05.440
Fortunately, it's not.

00:12:06.280 --> 00:12:14.100
So if you are a package, we're going to link to the Python package index blog.

00:12:14.100 --> 00:12:15.800
And this is written by Dustin Ingram.

00:12:15.800 --> 00:12:26.180
Talking about this, there's some discussion about why they didn't do signed identity key pair things.

00:12:26.760 --> 00:12:41.260
But the gist is, if you're already using GitHub Actions and trusted publishing, and you're using the GitHub Action PyPI publish, a little hook thing for GitHub Actions, it'll just work for you.

00:12:41.260 --> 00:12:42.760
You just need to make sure that there's a...

00:12:42.760 --> 00:12:44.760
The version is, I think it's...

00:12:44.760 --> 00:12:46.320
Well, there's another article that I looked at.

00:12:46.320 --> 00:12:47.140
I think it's 11.

00:12:47.140 --> 00:12:48.960
Let's peek over there.

00:12:48.960 --> 00:12:56.320
So this other article, there's another article, PyPI introduces digital attestation to strengthen PyPI packaging security.

00:12:56.320 --> 00:12:58.280
This is written by Sarah Gooding.

00:12:58.840 --> 00:13:05.860
And the gist of it here is, oh, yeah, version 1.11.0 is the one that you need to use.

00:13:05.860 --> 00:13:07.680
Now, what if you want to use something else?

00:13:07.680 --> 00:13:09.400
If you don't use...

00:13:09.400 --> 00:13:11.680
If you don't like GitHub Actions, you're using something else.

00:13:11.680 --> 00:13:18.080
Well, there is plans for other trusted publisher environments are planned.

00:13:18.080 --> 00:13:25.360
And then if you don't even want to do that, if you want to do it manually, it's not recommended, but you can do this manually.

00:13:25.360 --> 00:13:28.180
So you're not locked into GitHub Actions.

00:13:28.360 --> 00:13:28.960
It's just...

00:13:28.960 --> 00:13:32.180
I think that was a reasonable choice for them to implement first.

00:13:32.180 --> 00:13:33.560
You got to have...

00:13:33.560 --> 00:13:34.520
One of them has to be first.

00:13:34.520 --> 00:13:35.540
So that's what they did.

00:13:35.540 --> 00:13:39.160
Like I said, there's another article by Sarah Gooding.

00:13:39.160 --> 00:13:40.120
Also very good.

00:13:40.120 --> 00:13:42.120
It also walks through what the...

00:13:42.120 --> 00:13:43.120
What the...

00:13:43.120 --> 00:13:48.900
The viewing the UI for the new API for viewing what the file looks like.

00:13:48.900 --> 00:13:55.980
And the cool thing about this is, okay, this seems sort of technical and okay, like, you know, security on supply chains and all that.

00:13:55.980 --> 00:13:56.600
Yeah, yeah, yeah.

00:13:56.780 --> 00:13:58.560
But really, like, who cares?

00:13:58.560 --> 00:14:00.020
Well, we all care, really.

00:14:00.020 --> 00:14:08.040
But also, one of the things that I realized is there's links on PyPI for projects to say where the source code is.

00:14:08.040 --> 00:14:09.240
But we just...

00:14:09.240 --> 00:14:10.360
You just put that there.

00:14:10.360 --> 00:14:12.160
It's not guaranteed to be linking.

00:14:12.160 --> 00:14:21.520
Now, this is where the attestation makes it so that PyPI can verify that the object really is from the source code.

00:14:21.780 --> 00:14:22.620
So there is...

00:14:22.620 --> 00:14:23.200
You're not lying.

00:14:23.200 --> 00:14:30.380
Like, there's nobody in the middle lying about it and publishing a package that it really isn't from that source code from something else.

00:14:30.380 --> 00:14:31.700
And that's what we want.

00:14:31.700 --> 00:14:38.540
We want our open source projects to be available, easy to install, but also that we can find the source code really readily available.

00:14:38.780 --> 00:14:40.140
So that's what that's all about.

00:14:40.140 --> 00:14:47.740
There's also a cool are we PEP 740 yet that just shows you different, some of the top packages.

00:14:47.740 --> 00:14:54.380
Let's see, the 360 most downloaded packages and whether or not they're supported yet.

00:14:54.380 --> 00:14:55.460
And this is pretty new.

00:14:55.560 --> 00:14:58.380
So there's not that many supported already.

00:14:58.380 --> 00:15:00.080
But Wheel is supported, for instance.

00:15:00.080 --> 00:15:01.060
So you can check that out.

00:15:01.060 --> 00:15:01.500
Yeah.

00:15:01.500 --> 00:15:02.200
Pydantic.

00:15:02.200 --> 00:15:02.860
Pydantic.

00:15:02.860 --> 00:15:03.660
Good job.

00:15:03.660 --> 00:15:04.620
Pydantic people.

00:15:04.620 --> 00:15:05.840
Good job, Pydantic people.

00:15:05.840 --> 00:15:08.480
Just had Samuel Colvin on the show, by the way, on Talk Python.

00:15:08.480 --> 00:15:12.540
So people can hear from the Pydantic folks themselves very soon.

00:15:12.540 --> 00:15:13.040
Yarl?

00:15:13.040 --> 00:15:13.800
What's Yarl?

00:15:13.800 --> 00:15:14.860
I got to check that out.

00:15:14.860 --> 00:15:16.160
I've seen that in my dependencies.

00:15:16.160 --> 00:15:17.360
I don't know what it is.

00:15:17.360 --> 00:15:19.640
It's one of those things that comes along.

00:15:19.640 --> 00:15:20.040
Something.

00:15:20.040 --> 00:15:20.520
Yeah.

00:15:20.520 --> 00:15:21.480
Something library.

00:15:21.480 --> 00:15:22.420
Markdown library?

00:15:22.420 --> 00:15:22.900
I don't know.

00:15:22.900 --> 00:15:23.480
I have no idea.

00:15:23.480 --> 00:15:24.400
I'm making this up.

00:15:24.840 --> 00:15:30.300
And 360, because it's a wheel, there's like a visualization that is a wheel onto little

00:15:30.300 --> 00:15:33.920
slices to show you which ones are there, which ones aren't.

00:15:33.920 --> 00:15:34.200
Yeah.

00:15:34.200 --> 00:15:34.660
Nice.

00:15:34.660 --> 00:15:36.060
360 degrees.

00:15:36.060 --> 00:15:36.880
That's pretty cool.

00:15:36.880 --> 00:15:37.660
They picked 360.

00:15:37.660 --> 00:15:38.400
It is.

00:15:38.400 --> 00:15:38.980
All right.

00:15:38.980 --> 00:15:39.580
A couple of comments.

00:15:39.580 --> 00:15:40.380
Sean Tibor at there.

00:15:40.380 --> 00:15:40.700
Hey, Sean.

00:15:40.700 --> 00:15:43.520
Glad the cryptography package is there.

00:15:43.520 --> 00:15:45.180
Do a test.

00:15:45.180 --> 00:15:47.480
The tested status is for sure.

00:15:47.480 --> 00:15:50.600
And Christian says, trusted publishing is great.

00:15:50.600 --> 00:15:52.680
It's never been easier to publish on PyPI.

00:15:52.680 --> 00:15:53.940
If you're using GitHub, that is.

00:15:54.140 --> 00:15:54.340
Indeed.

00:15:54.340 --> 00:15:59.820
And Brian, you said when I talked about uv build, uv publish last time, time before, whenever,

00:15:59.820 --> 00:16:01.780
you said that you're not even doing that.

00:16:01.780 --> 00:16:02.700
You just let GitHub do it.

00:16:02.700 --> 00:16:03.000
Yeah.

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

00:16:03.360 --> 00:16:03.780
How's that go?

00:16:03.780 --> 00:16:04.620
How do you make that happen?

00:16:05.000 --> 00:16:10.120
Well, we go through this thing, this, what do we call it?

00:16:10.120 --> 00:16:11.760
The package.

00:16:11.760 --> 00:16:13.660
Trusted package provider or something?

00:16:13.660 --> 00:16:14.060
Yeah.

00:16:14.060 --> 00:16:15.280
The trusted publishing.

00:16:15.280 --> 00:16:19.440
There's a, there's, there's like a doc on how to do that.

00:16:19.440 --> 00:16:20.600
Trusted publisher.

00:16:20.980 --> 00:16:22.780
You have to have an API token.

00:16:22.780 --> 00:16:28.620
You like link tokens between GitHub, your GitHub project and, and PyPI.

00:16:28.620 --> 00:16:30.560
So they know about each other.

00:16:30.560 --> 00:16:34.540
And then the, then kind of just add a GitHub action, PyPI publish step.

00:16:34.540 --> 00:16:35.280
So nice.

00:16:35.280 --> 00:16:36.140
I should set that up.

00:16:36.140 --> 00:16:38.960
There's lots of ways to do it though.

00:16:38.960 --> 00:16:39.960
Workflow wise.

00:16:39.960 --> 00:16:47.940
I found personally that my, my favorite way is to, to do the publishing as part of the tag.

00:16:47.940 --> 00:16:51.140
So I'll, I'll do another version.

00:16:51.140 --> 00:16:55.700
That's just like, I'll, I'll publish to, I don't publish everything that I pushed up IPI,

00:16:55.700 --> 00:16:58.000
but, but, or push to GitHub.

00:16:58.000 --> 00:17:02.940
But when I push a, push a tag, then a build is done and the publish happens.

00:17:02.940 --> 00:17:05.000
So it pushes off a tag.

00:17:05.000 --> 00:17:06.160
So just tack it locally.

00:17:06.160 --> 00:17:07.300
Push it and then magic.

00:17:07.300 --> 00:17:07.760
Yeah.

00:17:07.760 --> 00:17:08.280
Nice.

00:17:08.280 --> 00:17:08.960
Awesome.

00:17:08.960 --> 00:17:09.120
Yeah.

00:17:09.120 --> 00:17:10.180
That's a good question though.

00:17:10.180 --> 00:17:15.020
I think we might want to revisit that and, and put an article up, find an article on that

00:17:15.020 --> 00:17:15.920
whole process.

00:17:15.920 --> 00:17:16.420
Yeah.

00:17:16.420 --> 00:17:18.540
Are you looking for a topic for a blog post?

00:17:18.540 --> 00:17:21.000
You feel a little bit rusty.

00:17:21.000 --> 00:17:21.880
I mean, that's what we got to talk about.

00:17:21.880 --> 00:17:23.080
Are you feeling rusty with your blog?

00:17:23.080 --> 00:17:24.600
Django's feeling rusty.

00:17:24.600 --> 00:17:26.460
Django's feeling super.

00:17:26.460 --> 00:17:28.000
I mean, a lot of Pythons feeling rusty.

00:17:28.000 --> 00:17:29.580
That's what I was talking to Samuel Colvin about.

00:17:29.580 --> 00:17:35.900
However, I want to highlight project that is very early in its life, but I think maybe deserves

00:17:35.900 --> 00:17:41.320
some love, some attention anyway from Lily foot Django rusty templates.

00:17:41.320 --> 00:17:45.780
So all of these web frameworks have some variation of templated programming.

00:17:45.780 --> 00:17:50.660
So you've got your HTML and then you'll have some kind of expression, like loop over all of

00:17:50.660 --> 00:17:56.900
my blog posts and like put out the title and the contents in this little wrapper deal or whatever.

00:17:56.900 --> 00:17:57.160
Right.

00:17:57.160 --> 00:17:57.860
They all have them.

00:17:57.860 --> 00:17:58.740
They're all variations.

00:17:58.740 --> 00:18:01.360
They're not as varied as you might imagine.

00:18:01.360 --> 00:18:05.360
And I'm going to actually come back to this whole template thing at the end of the show

00:18:05.360 --> 00:18:05.700
as well.

00:18:05.700 --> 00:18:11.740
However, this one re-implements the Django templating one, right?

00:18:11.740 --> 00:18:16.340
We've got Django, got Jinja, Mako, Chameleon, probably others.

00:18:16.340 --> 00:18:22.060
There's that whole PEP 750 maybe that's bringing templating into the language itself, all this stuff.

00:18:22.140 --> 00:18:22.240
Right.

00:18:22.240 --> 00:18:28.840
So this one re-implements that Django variant of that in Rust with the goal of 100% compatibility

00:18:28.840 --> 00:18:33.700
on output, not necessarily input or the way you program it, but output at least.

00:18:33.700 --> 00:18:36.260
And then error reporting that is at least as good as Django.

00:18:36.260 --> 00:18:41.360
And obviously, why would you do this if you weren't looking for improved performance over

00:18:41.360 --> 00:18:43.040
Django's pure Python implementation?

00:18:43.040 --> 00:18:44.240
These templates can be slow.

00:18:44.480 --> 00:18:50.540
One of the things that can make your website literally suffer to startup if it's under heavy

00:18:50.540 --> 00:18:54.360
load is to restart it and it has to reparse all the templates.

00:18:54.360 --> 00:19:01.320
I go to the extent that I have an app that will see that I can run against the website and it will

00:19:01.320 --> 00:19:08.320
request a representative subset of all the URLs to make sure that the template is loaded and parsed

00:19:08.320 --> 00:19:13.160
because it's a difference of hundreds of milliseconds versus tens of milliseconds, right?

00:19:13.200 --> 00:19:17.420
It could be up to one second to load the page the very first time it hits one of these complicated

00:19:17.420 --> 00:19:17.840
things.

00:19:17.840 --> 00:19:18.240
Yeah.

00:19:18.240 --> 00:19:20.080
And you want your pages fast.

00:19:20.080 --> 00:19:23.120
So when Google and other things hit it, they'll go, oh, that page is fast.

00:19:23.120 --> 00:19:24.820
We'll put it a little higher in search, you know?

00:19:24.820 --> 00:19:26.940
So anyway, this could be interesting.

00:19:26.940 --> 00:19:29.240
So caveat for the world.

00:19:29.240 --> 00:19:33.100
It is net ready for full release and therefore is not on PyPI yet.

00:19:33.100 --> 00:19:36.760
You can check it out if you want to live dangerously or contribute.

00:19:36.760 --> 00:19:37.260
Okay.

00:19:37.260 --> 00:19:38.420
They should push it.

00:19:38.420 --> 00:19:39.780
That's what XeroVerse for.

00:19:40.220 --> 00:19:40.620
Exactly.

00:19:40.620 --> 00:19:45.820
I was shipping stuff that was 0.02 on vacation.

00:19:45.820 --> 00:19:46.520
Come on.

00:19:46.520 --> 00:19:47.040
Yeah.

00:19:47.040 --> 00:19:48.520
Come on.

00:19:48.520 --> 00:19:48.940
Anyway.

00:19:48.940 --> 00:19:50.320
No, that's fine.

00:19:50.320 --> 00:19:51.740
People can do what they want, but.

00:19:51.740 --> 00:19:52.360
Of course.

00:19:52.360 --> 00:19:52.960
Sounds fine.

00:19:52.960 --> 00:19:53.640
I guess it depends.

00:19:53.640 --> 00:19:58.700
Do you feel like it's even anywhere close to potentially usable or is it just you're still

00:19:58.700 --> 00:20:00.380
working on it before it even makes sense?

00:20:00.380 --> 00:20:01.220
Yeah.

00:20:01.220 --> 00:20:02.320
They want.

00:20:02.320 --> 00:20:05.200
You don't want to be, you don't want a bunch of bugs saying this doesn't work yet.

00:20:05.280 --> 00:20:06.160
I know.

00:20:06.160 --> 00:20:07.540
And I said not to use it.

00:20:07.540 --> 00:20:09.860
Yeah.

00:20:09.860 --> 00:20:12.600
But also people, I think it's a cool idea.

00:20:12.600 --> 00:20:14.980
And if you want to help out and help out.

00:20:14.980 --> 00:20:15.600
Yeah, absolutely.

00:20:15.600 --> 00:20:16.100
Nice.

00:20:16.100 --> 00:20:21.320
Are we, I don't want to get too dry, but I want to talk about another pep.

00:20:21.320 --> 00:20:22.440
So PEP it up.

00:20:22.440 --> 00:20:22.980
Pep it up.

00:20:22.980 --> 00:20:23.560
It's a PEP talk.

00:20:23.560 --> 00:20:24.120
Pep talk.

00:20:25.080 --> 00:20:27.500
So Brett Cannon announced.

00:20:27.500 --> 00:20:30.120
So I, this is the first time I'd heard of this.

00:20:30.120 --> 00:20:31.920
When did this post come out?

00:20:31.920 --> 00:20:33.320
This is November 13th.

00:20:33.320 --> 00:20:36.980
That PEP 639 is now supported by PyPI.

00:20:36.980 --> 00:20:43.940
This pep, this is a PEP that lets you specify the license for your code using SPDX expressions.

00:20:43.940 --> 00:20:47.480
Who can't get excited about SPDX expressions?

00:20:47.480 --> 00:20:51.960
And it's easily, it's, and easily include all your licenses with your code.

00:20:52.420 --> 00:20:52.860
Okay.

00:20:52.860 --> 00:20:56.200
I have no idea what SPDX is, but let's jump in a little bit.

00:20:56.200 --> 00:21:01.720
The why am I excited about this is because the last way to be able to do, specify your license

00:21:01.720 --> 00:21:05.700
was you did a little license string thing to say MIT or whatever.

00:21:05.700 --> 00:21:09.900
But then you had a link, maybe a link to license.txt file.

00:21:09.900 --> 00:21:13.300
But there wasn't like, wasn't clear understanding what you should do.

00:21:13.300 --> 00:21:17.900
But you really had to, in order to get the license to show up on PyPI, you had to have a

00:21:17.900 --> 00:21:19.180
trove classifier.

00:21:19.180 --> 00:21:21.500
And I'm not really a fan of trove classifiers.

00:21:21.500 --> 00:21:22.180
I think they're weird.

00:21:22.380 --> 00:21:26.060
So you don't have to do trove classifiers anymore.

00:21:26.060 --> 00:21:33.320
So Brett linked to E Durbin's, or E's PEP 639 is now live.

00:21:33.320 --> 00:21:35.900
So that's just the same thing, but I'll link to it anyway.

00:21:35.900 --> 00:21:37.880
So let's look at this.

00:21:37.880 --> 00:21:44.340
The cool thing about this, I think, is, like I said, you don't have to use the trove classifier

00:21:44.340 --> 00:21:44.660
anymore.

00:21:45.540 --> 00:21:48.180
I'm going to jump down to like, really, what does it look like?

00:21:48.180 --> 00:21:51.940
So we have, there's reasons why and all that stuff.

00:21:51.940 --> 00:21:54.880
But really, it was confusing before, and it's easier now.

00:21:54.880 --> 00:22:00.380
So all you have to do is do something like you have license, a license field, and you can put

00:22:00.380 --> 00:22:01.060
MIT or something.

00:22:01.060 --> 00:22:02.840
So that's the, that's pretty easy.

00:22:03.160 --> 00:22:07.220
And then, but there's like, and so if you have, you can do logic in here.

00:22:07.220 --> 00:22:09.480
You can, if you've got multiple licenses in there.

00:22:09.480 --> 00:22:14.760
And the other thing was projects really, a large project might have more than one license

00:22:14.760 --> 00:22:20.280
because there might be, you may have vendored in part of the system that is, or part of another

00:22:20.280 --> 00:22:23.300
library that is licensed under a different license.

00:22:23.300 --> 00:22:24.020
What do you do there?

00:22:24.020 --> 00:22:28.400
Well, that's one of the great things about this is that there's that logic in there, but you

00:22:28.400 --> 00:22:30.320
can also do the license files key.

00:22:30.320 --> 00:22:34.820
And the license files key is great because you can just, there's more than one.

00:22:34.820 --> 00:22:37.020
You can have more than one and you specify where they all go.

00:22:37.620 --> 00:22:45.520
And it's just a, it's just a list of strings with, with what are those wild cards and stuff

00:22:45.520 --> 00:22:50.080
so that you can regular, with sort of regular expressions so that you can, you can find different

00:22:50.080 --> 00:22:51.640
files through there.

00:22:51.640 --> 00:22:53.840
And you can even have like, I like this version.

00:22:53.840 --> 00:22:58.480
It's got a main license.txt at the top and then a licenses directory.

00:22:58.480 --> 00:23:02.460
So you can have a directory full of licenses for sub components or something.

00:23:02.460 --> 00:23:02.720
Wow.

00:23:02.720 --> 00:23:07.480
It's like creating a list, a set of, set of arguments from a list.

00:23:07.560 --> 00:23:10.720
So you say star args and it explodes it out into positional arguments.

00:23:10.720 --> 00:23:12.780
It's like kind of like that, but for a Toml file.

00:23:12.780 --> 00:23:13.440
That's wild.

00:23:13.440 --> 00:23:14.420
Or is that a YAML?

00:23:14.420 --> 00:23:14.960
I don't know.

00:23:14.960 --> 00:23:15.820
I'm not.

00:23:15.820 --> 00:23:19.240
Well, it's a, it's SPDX or whatever.

00:23:19.240 --> 00:23:24.600
So this, this is a pretty exciting to me.

00:23:24.600 --> 00:23:28.820
I asked Brett like, well, this is still, it's not like, it's not finalized.

00:23:28.820 --> 00:23:30.120
I guess it's provisional.

00:23:30.120 --> 00:23:37.260
PyPI supports it, but they say that it's going to be, they need, it's an implementation of the

00:23:37.260 --> 00:23:39.700
PEP with, in two build backends.

00:23:39.700 --> 00:23:41.620
I don't know what the two build backends.

00:23:41.620 --> 00:23:45.420
That would be like hatchling or poetry or something like that.

00:23:45.420 --> 00:23:45.680
I believe.

00:23:45.680 --> 00:23:46.720
Oh, right.

00:23:46.720 --> 00:23:50.120
Definitely hatchling would, or set up tools or something like that.

00:23:50.120 --> 00:23:54.560
And an implementation, implementation of the PEP and PyPI, which is done.

00:23:54.560 --> 00:23:56.600
So I'm pretty sure this is done.

00:23:56.600 --> 00:23:56.880
Yeah.

00:23:56.880 --> 00:24:00.560
And the first link that you clicked on the discuss, the discourse thread or whatever.

00:24:00.560 --> 00:24:00.920
Yeah.

00:24:00.920 --> 00:24:01.360
Yeah.

00:24:01.360 --> 00:24:02.300
See that second thing?

00:24:02.300 --> 00:24:09.060
Carolina Suma wrote the PDM backend supporting this since such and such version and hatchling

00:24:09.060 --> 00:24:10.180
since another version.

00:24:10.360 --> 00:24:11.900
I believe the conditions have been met.

00:24:11.900 --> 00:24:12.500
Okay.

00:24:12.500 --> 00:24:16.780
So I think this is going to be changed from provisional to something else.

00:24:16.780 --> 00:24:17.300
Hopefully.

00:24:17.300 --> 00:24:19.100
Whatever comes after provisional.

00:24:19.100 --> 00:24:20.540
Probably accepted or whatever.

00:24:20.540 --> 00:24:21.260
Probably accepted.

00:24:21.260 --> 00:24:27.520
Hey, I just want to make a little to Philip and crew in Carolina as well.

00:24:27.520 --> 00:24:32.740
Just, you know, the file that you create for this is license underscore file.

00:24:32.740 --> 00:24:33.680
No extension.

00:24:33.680 --> 00:24:35.300
Think of an extension, please.

00:24:35.300 --> 00:24:36.420
So we can have a default.

00:24:36.420 --> 00:24:38.320
So you can double click it and open it.

00:24:38.320 --> 00:24:41.480
Rather than have to figure out an editor, go into it, drag it into it.

00:24:41.480 --> 00:24:41.700
Right.

00:24:41.700 --> 00:24:45.400
Because without an extension, you can't set a default editor to edit the license file in

00:24:45.400 --> 00:24:46.520
Mac or Windows at least.

00:24:46.520 --> 00:24:49.020
Oh, like say license.txt or something?

00:24:49.020 --> 00:24:49.360
Yeah.

00:24:49.360 --> 00:24:51.720
Or MD or YAML or TOML.

00:24:51.720 --> 00:24:55.060
Or I would say YAML or TOML probably makes the most sense if it has that structure.

00:24:55.060 --> 00:25:00.540
Because then the editors, if you open it in PyTron or VS Code, they'll apply linting to

00:25:00.540 --> 00:25:02.080
it based on the format.

00:25:02.080 --> 00:25:04.820
Whereas right now, it's like, well, whatever.

00:25:04.820 --> 00:25:05.680
Good luck with that.

00:25:05.680 --> 00:25:05.860
Right?

00:25:05.860 --> 00:25:06.380
It's just text.

00:25:06.380 --> 00:25:11.200
Well, so this, like this, these changes that I'm showing are, they're not, they're like YAML

00:25:11.200 --> 00:25:14.700
or TOML or something like that because they're part of the PyProject.toml file.

00:25:14.700 --> 00:25:15.440
Oh, are they?

00:25:15.440 --> 00:25:19.720
Well, somewhere it talked about the license key file or the, yeah, right.

00:25:19.720 --> 00:25:21.860
And there's a license underscore, right there.

00:25:21.860 --> 00:25:22.280
Go back up.

00:25:22.280 --> 00:25:22.840
Stop.

00:25:23.400 --> 00:25:25.100
license dash files.

00:25:25.100 --> 00:25:26.700
Oh, that's just the key in the file.

00:25:26.700 --> 00:25:27.580
That's not actually a file.

00:25:27.580 --> 00:25:27.780
Okay.

00:25:27.780 --> 00:25:29.820
Then I don't know what I'm talking about.

00:25:29.820 --> 00:25:30.260
Forget that.

00:25:30.260 --> 00:25:31.560
That's the key.

00:25:31.560 --> 00:25:33.840
And so I think that they're usually.

00:25:33.840 --> 00:25:34.760
No, it's fine.

00:25:34.760 --> 00:25:36.800
It'll be picked up by PyProject.toml.

00:25:36.800 --> 00:25:37.160
Yeah.

00:25:37.160 --> 00:25:43.580
But I usually, I used to just have it be raw, but I like the idea of doing a .text file.

00:25:43.580 --> 00:25:44.300
Yeah.

00:25:44.300 --> 00:25:44.820
Anyway.

00:25:44.820 --> 00:25:49.280
Something that applies, that makes the tool apply the linting to it if it's reasonable,

00:25:49.280 --> 00:25:50.580
that would already know how to do that.

00:25:50.580 --> 00:25:51.020
Yeah.

00:25:51.020 --> 00:25:53.360
Do it like a, like a Word doc.

00:25:53.360 --> 00:25:53.820
As.

00:25:53.820 --> 00:25:56.800
Come on.

00:25:56.800 --> 00:25:57.360
I'll have an Excel.

00:25:57.360 --> 00:25:57.900
Come on.

00:25:57.900 --> 00:25:58.960
And not like a doc X.

00:25:58.960 --> 00:26:01.380
Do it, do it like, you know, from like 1995.

00:26:01.380 --> 00:26:02.620
Straight doc.

00:26:02.620 --> 00:26:03.120
Let's go.

00:26:03.120 --> 00:26:03.600
Okay.

00:26:03.600 --> 00:26:04.240
Anyway.

00:26:04.540 --> 00:26:06.640
I think that's where those are items.

00:26:06.640 --> 00:26:07.320
Those are.

00:26:07.320 --> 00:26:07.820
Okay.

00:26:07.820 --> 00:26:10.160
Well, do you have any extras?

00:26:10.160 --> 00:26:11.960
I have a couple of quick ones here.

00:26:11.960 --> 00:26:12.960
I'll go through for us.

00:26:12.960 --> 00:26:13.780
I'll let you do yours.

00:26:13.780 --> 00:26:14.460
Really quickly.

00:26:14.460 --> 00:26:15.900
Python 314.

00:26:15.900 --> 00:26:20.240
Alva 2 was released last week, just after we did our show last week.

00:26:20.240 --> 00:26:22.840
So kind of the most recent one we could talk about, I believe.

00:26:22.840 --> 00:26:30.980
Anyway, it continues on with its PEP 649 deferred evaluation annotation of annotations on Python

00:26:30.980 --> 00:26:37.380
configuration C API and no longer having PGP signatures and improved error messages, among

00:26:37.380 --> 00:26:37.860
other things.

00:26:37.980 --> 00:26:39.580
So check it out if you're interested in that.

00:26:39.580 --> 00:26:41.240
You want to test against it.

00:26:41.240 --> 00:26:42.140
Remember, there will be seven.

00:26:42.140 --> 00:26:43.520
So it's pretty early in there.

00:26:43.520 --> 00:26:46.760
But, you know, you'll be able to influence the direction if you so want.

00:26:46.760 --> 00:26:47.480
Blue sky.

00:26:47.480 --> 00:26:48.980
Brian, we have personalities.

00:26:48.980 --> 00:26:51.160
Python personalities are invading blue sky.

00:26:51.160 --> 00:26:56.760
And I would say I'm really happy with the engagement and how much people are participating

00:26:56.760 --> 00:26:58.320
over there and all those kinds of things.

00:26:58.320 --> 00:26:59.700
It seems really, really great.

00:26:59.700 --> 00:27:00.000
Right?

00:27:00.000 --> 00:27:00.520
Yeah.

00:27:00.520 --> 00:27:01.000
Yeah.

00:27:01.000 --> 00:27:04.140
So we have links for all of our accounts on blue sky over there.

00:27:04.140 --> 00:27:06.960
But the thing I want to highlight is I created a starter pack.

00:27:07.020 --> 00:27:12.040
And I think these starter packs are actually one of the magic growth hacks of blue sky.

00:27:12.040 --> 00:27:14.200
And also a good way for people to get started.

00:27:14.200 --> 00:27:20.020
So here's the common social problem, social network problem is you join and it's crickets.

00:27:20.020 --> 00:27:23.760
And then you follow stuff that you don't care about because it's like you've got no followers.

00:27:23.760 --> 00:27:26.300
So here's a bunch of horrible stuff that you don't want to see.

00:27:26.300 --> 00:27:26.740
Oh, great.

00:27:26.740 --> 00:27:29.060
People ranting about this or that.

00:27:29.060 --> 00:27:29.760
I want none of this.

00:27:29.760 --> 00:27:32.160
I want to just get back to my communities that I care about.

00:27:32.160 --> 00:27:36.380
So for each community, you can create people can create what are called starter packs,

00:27:36.380 --> 00:27:38.640
which is like up to 250 people.

00:27:38.640 --> 00:27:41.520
You can just click one button and say, boom, I'm going to follow those people.

00:27:41.520 --> 00:27:42.480
It's a quick jumpstart.

00:27:42.480 --> 00:27:44.620
So I created a Python personality one.

00:27:44.620 --> 00:27:45.100
I don't know.

00:27:45.100 --> 00:27:46.940
I think it has 60 people, maybe more.

00:27:46.940 --> 00:27:47.280
I'm not sure.

00:27:47.280 --> 00:27:48.400
I'll be able to show you in a second.

00:27:48.400 --> 00:27:50.460
But it's, you know, it's got whoever created it.

00:27:50.460 --> 00:27:55.100
And then it's got who you put like Nina Zakarenko, Dr. Becky, Chris Williams, Cecil Phillips,

00:27:55.100 --> 00:27:58.500
Savannah, Simon Wilson, Peter Wang, and so on.

00:27:58.500 --> 00:27:59.920
So you're in here somewhere, Brian.

00:27:59.920 --> 00:28:03.380
Brett Cannon, who were just covering his article and his PEP and so on.

00:28:03.600 --> 00:28:04.240
See, there you are.

00:28:04.240 --> 00:28:08.020
And so I just want to encourage people, hey, go find some of these starter packs.

00:28:08.020 --> 00:28:08.840
Consider mine.

00:28:08.840 --> 00:28:10.360
Give it a click and so on.

00:28:10.360 --> 00:28:11.800
And how do you do that?

00:28:11.800 --> 00:28:17.360
Well, Will McGugan pointed out that there's this blueskydirectory.com that has all the starter

00:28:17.360 --> 00:28:17.660
packs.

00:28:17.660 --> 00:28:22.840
And you can search for like Python starter packs or motorcycling starter packs or skating

00:28:22.840 --> 00:28:23.560
or whatever you're into.

00:28:23.560 --> 00:28:25.700
So you've got, I don't know who these people are.

00:28:25.700 --> 00:28:26.940
There's some people who created some.

00:28:26.940 --> 00:28:31.120
Like down here a little bit further, you can see like here's the one I created and different

00:28:31.120 --> 00:28:31.460
folks.

00:28:31.460 --> 00:28:34.440
Python core team by Hugo, I believe that is.

00:28:34.440 --> 00:28:35.320
So on, right?

00:28:35.320 --> 00:28:37.600
So there are actually 572 starter packs.

00:28:37.720 --> 00:28:40.420
But I suspect a lot of overlap intersection here.

00:28:40.420 --> 00:28:40.880
Yeah.

00:28:40.880 --> 00:28:46.220
And one of the things I appreciate about checking these out is, is being able to like that.

00:28:46.220 --> 00:28:50.100
Some people are keeping me like keeping these up a little bit, which I appreciate.

00:28:50.100 --> 00:28:51.500
Like Luciano.

00:28:51.500 --> 00:28:53.120
Wait, no, it wasn't Luciano.

00:28:53.120 --> 00:28:57.520
It was, oh, Reuven Lerner has one also that he's trying to keep up.

00:28:57.520 --> 00:29:01.080
And, and I, because I've been on Bluesky for a while.

00:29:01.160 --> 00:29:05.840
So I like went out and looked for Python people early on and there's a ton of Python people

00:29:05.840 --> 00:29:07.340
jumping on the bandwagon right now.

00:29:07.340 --> 00:29:07.680
Right.

00:29:07.680 --> 00:29:09.600
And just yesterday, a bunch joined, you know?

00:29:09.600 --> 00:29:10.000
Yeah.

00:29:10.000 --> 00:29:13.940
So, so it's good to, to look like I was just looking through your list and there was probably

00:29:13.940 --> 00:29:16.580
five or 10 that I hadn't, that I hadn't followed yet.

00:29:16.580 --> 00:29:18.340
And there are people I want to follow.

00:29:18.340 --> 00:29:18.660
So.

00:29:18.660 --> 00:29:19.120
Yeah.

00:29:19.120 --> 00:29:22.420
And I just added somebody two hours ago to it.

00:29:22.420 --> 00:29:26.420
So it's, it's being maintained to the limit till it hits this limit.

00:29:26.420 --> 00:29:27.980
Then I have to start to make tough decisions.

00:29:27.980 --> 00:29:30.420
If, if someone ejects someone else, I don't really want to do that.

00:29:30.420 --> 00:29:34.060
But right now there's 61 people in mind and this directory thing shows you how big the

00:29:34.060 --> 00:29:34.560
list is.

00:29:34.560 --> 00:29:35.340
Care about that.

00:29:35.340 --> 00:29:36.120
All right.

00:29:36.120 --> 00:29:39.660
Part, another really quick thing.

00:29:39.660 --> 00:29:41.280
No, I'm going to save this one until next time.

00:29:41.280 --> 00:29:44.680
Just for, for sake of time, we'll cover that one next, next week.

00:29:44.680 --> 00:29:45.240
All right.

00:29:45.240 --> 00:29:46.740
Well, I've got a few extras.

00:29:46.740 --> 00:29:52.760
I didn't cover this because I didn't really, I don't know if I'm smart enough to cover this,

00:29:52.760 --> 00:29:54.500
but I'll link to it anyway.

00:29:54.500 --> 00:30:02.280
There's a article from Armin Roeniker titled playground wisdom threads, beat async and await.

00:30:02.280 --> 00:30:04.920
And he's not really talking about Python threads.

00:30:04.920 --> 00:30:08.120
He's really talking about, or, or Python async and await.

00:30:08.120 --> 00:30:14.460
I think he is, but also just in general, like programming languages, thinking about threads

00:30:14.460 --> 00:30:16.080
versus thinking about async and await.

00:30:16.080 --> 00:30:22.740
And, and it's just an interesting read in a good article talking about how like we should

00:30:22.740 --> 00:30:27.980
really be making concert concurrency really easy to the point where we don't actually talk

00:30:27.980 --> 00:30:28.800
about concurrency.

00:30:28.800 --> 00:30:29.580
It just works.

00:30:29.680 --> 00:30:34.640
And that seems ludicrous in some respects, if you're used to a low level language, but

00:30:34.640 --> 00:30:40.300
they, his example at the top just sort of like blew me away in thought process of thinking

00:30:40.300 --> 00:30:44.920
about, about the scratch programming language for kids.

00:30:44.920 --> 00:30:51.380
And if you, if you have like, he has an example of like a, a cat and a mouse sprite having code

00:30:51.380 --> 00:30:58.760
that like just, you know, moves 200 times while, or like wild, while mouse X is less than

00:30:58.760 --> 00:31:03.520
200 update the X position by five and sleep for 10 seconds.

00:31:03.520 --> 00:31:06.140
And then do that or do that for a cat also.

00:31:06.140 --> 00:31:07.900
So you got a cat and a mouse chasing each other.

00:31:07.900 --> 00:31:13.220
and the question is really, do those run at the same time or one after another?

00:31:13.220 --> 00:31:18.560
And in scratch, it just is each of these are, are their own thread, their own thing that's

00:31:18.560 --> 00:31:18.920
running.

00:31:19.140 --> 00:31:21.300
And there's no async and await here.

00:31:21.300 --> 00:31:22.380
It just is there.

00:31:22.380 --> 00:31:25.780
And, and I'm not saying that we should all go out and write our frameworks in scratch.

00:31:25.780 --> 00:31:26.080
Now.

00:31:26.080 --> 00:31:31.900
I'm saying it's, it's an interesting idea to, to, to realize that it can be made easy.

00:31:31.900 --> 00:31:37.000
and I both agree and disagree in interesting ways here.

00:31:37.000 --> 00:31:40.760
So I really like what Armin's been doing on his blog lately.

00:31:40.760 --> 00:31:45.260
He's been writing some very thoughtful posts and has me shaking my head in agreement a lot.

00:31:45.260 --> 00:31:46.260
So well done Armin.

00:31:46.460 --> 00:31:51.020
However, I think some of the pushback, I have not read this.

00:31:51.020 --> 00:31:53.900
So it's so easy on me, but I'd like to read it.

00:31:53.900 --> 00:31:54.980
It's on my reading list.

00:31:54.980 --> 00:32:00.420
But I think part of the pushback of, ah, async's having a bit of a, it's just not quite is I

00:32:00.420 --> 00:32:02.980
think there's foundations of async that have not been built yet.

00:32:02.980 --> 00:32:04.240
That should be built.

00:32:04.240 --> 00:32:05.340
Like for example.

00:32:05.340 --> 00:32:09.540
so you're this example here, create a function called move mouse, create a function called

00:32:09.540 --> 00:32:10.020
move cat.

00:32:10.160 --> 00:32:15.040
If this was async and this was C# and you called run, you wrote, you wrote that

00:32:15.040 --> 00:32:17.640
code in C#, but the word async was applied to the functions.

00:32:17.640 --> 00:32:21.000
Basically it would just run like it is like there's nothing left to do.

00:32:21.000 --> 00:32:22.500
And async and await handles that.

00:32:22.500 --> 00:32:29.220
But Python doesn't have the concept of a background management thing that runs all the async stuff

00:32:29.220 --> 00:32:29.960
and keeps it going.

00:32:29.960 --> 00:32:30.300
Right.

00:32:30.300 --> 00:32:33.680
You've got to go to the loop and say, Hey loop, here's another thing to run.

00:32:33.680 --> 00:32:34.880
Start this, please.

00:32:34.880 --> 00:32:39.440
Whereas in a lot of other languages, you, the act of calling an async function coordinates

00:32:39.440 --> 00:32:41.440
behind the scenes in ways you don't have to think about that.

00:32:41.440 --> 00:32:47.620
Start and run that you're given a task of a, object of a running task that's already

00:32:47.620 --> 00:32:49.760
been handled in something you pre-configured.

00:32:49.760 --> 00:32:53.740
Whereas in Python, you're like, I know you think you ran it because it has parentheses like

00:32:53.740 --> 00:32:56.140
a function, but now you've got to go find a place to actually run it.

00:32:56.140 --> 00:32:59.380
And a lot of that, that finding the place is always janky.

00:32:59.380 --> 00:33:03.080
It's like, Oh, asyncio dot get, get event loop exception.

00:33:03.080 --> 00:33:03.960
No event loop.

00:33:03.960 --> 00:33:04.600
Darn it.

00:33:04.600 --> 00:33:05.760
I'll create one some other time.

00:33:05.760 --> 00:33:07.200
Create event loop exception.

00:33:07.200 --> 00:33:08.320
There's already event loop.

00:33:08.320 --> 00:33:10.780
It's like, why, what is going on here?

00:33:10.780 --> 00:33:12.080
Why am I always battling this?

00:33:12.080 --> 00:33:16.520
Or I, there is a loop, but it's, I need to get to it from another thread and it's thread

00:33:16.520 --> 00:33:16.860
local.

00:33:16.860 --> 00:33:20.160
And I, I, how do I connect these two things through variables?

00:33:20.160 --> 00:33:21.180
And I want to use globals.

00:33:21.180 --> 00:33:24.060
Like there's just all this stuff that makes it tricky.

00:33:24.060 --> 00:33:28.460
Whereas there could be a little infrastructure behind the scenes that just, I don't know if it's

00:33:28.460 --> 00:33:31.420
just, I don't know if it might be, it's too late, which would be super unfortunate, but

00:33:31.420 --> 00:33:32.340
it could be.

00:33:32.340 --> 00:33:34.300
I think it can be built on top of it.

00:33:34.300 --> 00:33:34.680
Yeah.

00:33:34.680 --> 00:33:35.040
Maybe.

00:33:35.040 --> 00:33:35.680
Maybe.

00:33:35.680 --> 00:33:41.160
Anyway, I think that that is part of the problem is the challenge is like, it's, it's your job

00:33:41.160 --> 00:33:44.860
to connect the pieces of the plumbing more than it should be.

00:33:44.860 --> 00:33:45.680
That's what I think.

00:33:46.100 --> 00:33:53.000
I've also used, so I've used a, this is in C++, but a concurrency framework that had,

00:33:53.000 --> 00:33:54.060
the default is easy.

00:33:54.060 --> 00:34:01.620
Like the generic, the, the, there is a general thread pool that it's easy to use,

00:34:01.620 --> 00:34:02.660
easy to add things to.

00:34:02.660 --> 00:34:03.800
It's just sort of happens.

00:34:03.800 --> 00:34:09.280
And then there's, and then there's, if you want like a separate thread pool, that's

00:34:09.280 --> 00:34:10.680
just managed separately.

00:34:10.680 --> 00:34:14.840
There's more, more who can go and create it and put it in sort of connecting pieces.

00:34:14.840 --> 00:34:15.180
Yeah.

00:34:15.180 --> 00:34:16.540
So I think that's awesome.

00:34:16.540 --> 00:34:16.800
Right.

00:34:16.800 --> 00:34:19.240
Rather than you always have to do the hard way.

00:34:19.240 --> 00:34:19.700
Yeah.

00:34:19.700 --> 00:34:20.100
Yeah.

00:34:20.100 --> 00:34:25.560
We need a, at least in for simpler cases, there is an easy way that exists.

00:34:25.560 --> 00:34:29.760
And anyway, but I'm also kind of talking out of my hat because I haven't run, I haven't

00:34:29.760 --> 00:34:31.920
written a lot of async Python yet.

00:34:31.920 --> 00:34:32.320
Yeah.

00:34:32.320 --> 00:34:35.180
I'll give you a really, really, really quickly to wrap the show up.

00:34:35.180 --> 00:34:42.080
But in court, you've got, there's an async event loop managed by the web framework, or

00:34:42.080 --> 00:34:46.060
maybe it's even managed by the app server that then starts the framework.

00:34:46.060 --> 00:34:49.940
But there's a dedicated asyncio event loop for processing requests.

00:34:49.940 --> 00:34:54.280
It doesn't exist until after all of your startup code is done.

00:34:54.280 --> 00:34:59.960
And so if you have any async code to call before you're actually, you're, you're just like

00:34:59.960 --> 00:35:04.480
everything set up, all of the things have been populated, run the start processing requests.

00:35:04.480 --> 00:35:06.640
You basically almost can't do it.

00:35:06.640 --> 00:35:12.220
If like, for example, so for the eight, for Beanie, you have to say, initialize the database

00:35:12.220 --> 00:35:14.600
and get all the connections and stuff going.

00:35:14.600 --> 00:35:19.920
So if you write code to do that and then try to use it in the, in a web view, in a web

00:35:19.920 --> 00:35:22.500
request, it'll crash and say wrong event loop.

00:35:22.500 --> 00:35:26.220
It was initialized on this event loop, but it's running on the court event loop.

00:35:26.220 --> 00:35:28.680
And you're like, well, but how do I start it?

00:35:28.680 --> 00:35:33.600
How do I ask a database question before the web request to start it?

00:35:33.600 --> 00:35:37.260
You know, like I, maybe I want to do something different if the database is initialized or

00:35:37.260 --> 00:35:37.540
not.

00:35:37.540 --> 00:35:38.980
Or I want to, I don't know.

00:35:38.980 --> 00:35:42.440
It's just like, there's all this juggling and there are mechanisms to say, okay, well,

00:35:42.440 --> 00:35:46.960
like you can have some startup code run in a different time, but it's just, it's just

00:35:46.960 --> 00:35:47.160
hard.

00:35:47.480 --> 00:35:47.780
Yeah.

00:35:47.780 --> 00:35:49.900
Anyway, I hope I keep harping on this.

00:35:49.900 --> 00:35:53.980
I'm hoping someone will go like, okay, we're at the core developer language summit.

00:35:53.980 --> 00:35:54.780
Can we simplify?

00:35:54.780 --> 00:35:55.200
Okay.

00:35:55.200 --> 00:35:55.540
Please.

00:35:55.540 --> 00:35:56.060
Okay.

00:35:56.060 --> 00:35:58.520
And then I got a few more, but I'll do them quick.

00:35:58.520 --> 00:36:06.600
The, the Python test community is now on discord that the launch happened in a couple

00:36:06.600 --> 00:36:08.000
of days last, last week.

00:36:08.000 --> 00:36:09.700
And it's going well.

00:36:09.700 --> 00:36:11.740
We've got like 89 people in there so far.

00:36:12.040 --> 00:36:15.960
If you'd like to be a part of it and you're not already, if you, if you're part of the

00:36:15.960 --> 00:36:17.620
community, you got, would have gotten an email.

00:36:17.620 --> 00:36:22.000
If you want to be part of the community and you didn't get the email or you haven't bought

00:36:22.000 --> 00:36:26.000
one of my stuff things before you can head over to courses.pythontest.com.

00:36:26.000 --> 00:36:27.460
And you don't even need one of the courses.

00:36:27.460 --> 00:36:30.240
You can just grab the discord community.

00:36:30.240 --> 00:36:32.940
One it's there and it's on sale.

00:36:32.940 --> 00:36:38.860
It and everything else on the site is on a, on a black Friday sale, 20% off using Turkey

00:36:38.860 --> 00:36:39.640
sale 2024.

00:36:39.640 --> 00:36:41.340
And that's just right on the side.

00:36:41.340 --> 00:36:42.100
I'm posting that.

00:36:42.100 --> 00:36:42.760
It's not a secret.

00:36:42.760 --> 00:36:44.980
However, there is a secret on the book.

00:36:44.980 --> 00:36:49.140
So Python testing with pytest is a 40% off right now.

00:36:49.140 --> 00:36:55.420
And you, you just need to use the black Friday code, which is also the same code Turkey sale

00:36:55.420 --> 00:36:55.840
2020.

00:36:55.840 --> 00:36:58.120
I just wanted to be easy for people to remember.

00:36:58.120 --> 00:37:02.300
So learn pytest easily through sales.

00:37:02.700 --> 00:37:03.660
Test your thing.

00:37:03.660 --> 00:37:04.100
Yeah.

00:37:04.100 --> 00:37:05.140
Enjoy the turkeys.

00:37:05.140 --> 00:37:05.620
Yeah.

00:37:05.620 --> 00:37:07.380
And I'm, I'm having fun with discord.

00:37:07.380 --> 00:37:11.480
I've had to have had to embrace the dancing logos and stuff.

00:37:11.480 --> 00:37:16.880
And I know you can turn them off, but I'm actually realizing that I kind of like them

00:37:16.880 --> 00:37:17.080
now.

00:37:17.080 --> 00:37:18.660
These little doohickey things.

00:37:18.660 --> 00:37:18.840
Yeah.

00:37:18.840 --> 00:37:19.320
It's fun.

00:37:19.320 --> 00:37:20.720
The little giffies or whatever.

00:37:20.720 --> 00:37:21.260
Very funny.

00:37:21.260 --> 00:37:21.700
Yeah.

00:37:21.700 --> 00:37:23.920
Talk Python is going to also have a black Friday sale.

00:37:23.920 --> 00:37:27.220
I don't have it launched yet, but that is my goal for the day.

00:37:27.220 --> 00:37:29.120
So I'll put it in the show notes.

00:37:29.120 --> 00:37:30.140
People can check it out.

00:37:30.140 --> 00:37:32.460
I don't, I'm not a hundred percent on the final, final details,

00:37:32.460 --> 00:37:34.280
but I'm finalizing that today.

00:37:34.280 --> 00:37:35.900
I can't believe November's almost over.

00:37:35.900 --> 00:37:36.520
What even?

00:37:36.520 --> 00:37:37.480
Exactly.

00:37:37.480 --> 00:37:38.420
This is my problem.

00:37:38.420 --> 00:37:45.420
I do not accept that November is almost over, but Hey, it's, it's one, one month less of

00:37:45.420 --> 00:37:46.140
rain for us.

00:37:46.140 --> 00:37:47.260
We're closer to sun again.

00:37:47.260 --> 00:37:47.880
So let's go.

00:37:47.880 --> 00:37:48.320
Yeah.

00:37:48.520 --> 00:37:48.700
All right.

00:37:48.700 --> 00:37:49.380
Are you ready for a joke?

00:37:49.380 --> 00:37:49.980
Yeah.

00:37:49.980 --> 00:37:54.380
So this joke, just everyone, Brian has not seen or heard this.

00:37:54.380 --> 00:37:55.080
This joke.

00:37:55.080 --> 00:38:01.740
Remember we had the AI, the sad girls, AI sing song, sing the MIT license terms.

00:38:01.740 --> 00:38:02.240
Yeah.

00:38:02.340 --> 00:38:10.280
This is like this, but this is a heavy metal rock band singing the verbose output of a curl

00:38:10.280 --> 00:38:10.680
command.

00:38:10.680 --> 00:38:17.160
So if you say curl dash V for verbose, HTPS, Google.com, there's a whole bunch of stuff that

00:38:17.160 --> 00:38:18.220
comes out, a bunch of tech things.

00:38:18.220 --> 00:38:20.940
So we're going to have a heavy metal jam session of this.

00:38:20.940 --> 00:38:23.200
And I want to point out one of your volume is high.

00:38:23.200 --> 00:38:28.380
Turn it down to, if you really hate heavy metal, hard rock, just go ahead and stop here.

00:38:28.380 --> 00:38:29.980
There's, we're not covering anything else.

00:38:29.980 --> 00:38:31.000
I don't want to use it.

00:38:31.000 --> 00:38:31.620
Seriously.

00:38:31.620 --> 00:38:34.640
This is kind of like some intense rock, but it's also pretty funny.

00:38:34.640 --> 00:38:39.480
And I would also like to add on the videos on YouTube, the video I'm linking to the, there's

00:38:39.480 --> 00:38:41.840
a comment that says, hi, I'm the creator of curl.

00:38:41.840 --> 00:38:45.560
And I wholeheartedly endorse this amazing, this masterpiece.

00:38:46.160 --> 00:38:49.280
With that said, if you hate, if you hate hard rock, you're not going to love it.

00:38:49.280 --> 00:38:51.060
So just go ahead and skip ahead.

00:38:51.060 --> 00:38:51.460
Everyone.

00:38:51.460 --> 00:38:52.120
Here we go.

00:39:14.100 --> 00:39:37.220
DLS 1.3 in DLS Handshake Certificate DLS 1.3 in DLS Handshake Certify DLS 1.3 in DLS Handshake Sinist DLS 1.3 out DLS 800 take cyphers back DLS 1.3 out DLS Handshake Sinist

00:39:37.220 --> 00:39:48.320
Well there you have it folks the actual real song is at three and a half minutes and I couldn't I

00:39:48.320 --> 00:39:53.780
couldn't do it I couldn't play the whole thing for you so it's a taster hit the full show um I love it

00:39:53.780 --> 00:39:56.140
DLS Handshake hello

00:39:56.140 --> 00:40:02.540
nice all right everyone Brian see ya

