WEBVTT

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

00:00:05.760 --> 00:00:10.400
This is episode 55, recorded December 6th, 2017.

00:00:10.400 --> 00:00:11.420
I'm Michael Kennedy.

00:00:11.420 --> 00:00:12.400
And I'm Brian Okken.

00:00:12.400 --> 00:00:13.640
And Brian, can you believe it's December?

00:00:13.640 --> 00:00:15.240
Yeah, it's getting cold out.

00:00:15.240 --> 00:00:19.820
It's getting cold. I look outside, it's the middle of the day, and it's still basically dark.

00:00:19.820 --> 00:00:21.400
So I guess we're getting there.

00:00:21.400 --> 00:00:21.660
Yeah.

00:00:21.660 --> 00:00:26.180
So before we get into our picks for the week, though, let's just say thanks to DigitalOcean.

00:00:26.180 --> 00:00:29.720
They have a ton of awesome servers for you.

00:00:29.940 --> 00:00:32.400
The websites I run run on DigitalOcean.

00:00:32.400 --> 00:00:33.980
So we'll tell you more about that later.

00:00:33.980 --> 00:00:39.160
However, one option, I guess one of the servers I have actually runs Flask.

00:00:39.160 --> 00:00:42.320
And Brian, I hear you're kind of digging Flask these days.

00:00:42.320 --> 00:00:47.780
Yeah, I am actually going through Miguel Grimberg's Flask mega tutorial.

00:00:47.780 --> 00:00:50.420
So I'm pretty excited about that.

00:00:50.420 --> 00:00:58.920
And I got actually from the, I think I took the advice from you to try something simple like Flask at first,

00:00:59.000 --> 00:01:00.720
not to slam Flask.

00:01:00.720 --> 00:01:03.380
But it is pretty low barrier to entry.

00:01:03.600 --> 00:01:06.540
And I knew Miguel was rewriting this mega tutorial.

00:01:06.540 --> 00:01:10.580
So I begged and pleaded and got an early copy of the rewrite.

00:01:10.580 --> 00:01:12.720
So I'm partway through it right now.

00:01:12.720 --> 00:01:16.040
But he did a Kickstarter to try to rewrite it.

00:01:16.040 --> 00:01:17.560
The first one was in 2012.

00:01:17.560 --> 00:01:21.320
And his Kickstarter was very successful, I think.

00:01:21.320 --> 00:01:25.400
His part one of the rewrite is available right now today.

00:01:25.560 --> 00:01:26.180
Yeah, that's awesome.

00:01:26.180 --> 00:01:29.220
And I know Miguel's been putting a ton of work into the rewrite.

00:01:29.220 --> 00:01:32.280
I was so excited to see his Kickstarter be successful.

00:01:32.280 --> 00:01:38.180
He added a bunch of stretch goals to do additional sections.

00:01:38.180 --> 00:01:43.420
He has an ebook version and a video version coming out of it, coming out as rewards from it.

00:01:43.420 --> 00:01:44.540
He hasn't done the videos yet.

00:01:44.540 --> 00:01:46.600
He and I were actually just talking today about the videos.

00:01:46.600 --> 00:01:48.140
So that'll be fun.

00:01:48.660 --> 00:01:53.100
But yeah, so if you want to learn how to get going Flask, his work is really great.

00:01:53.100 --> 00:01:54.200
And so definitely check it out.

00:01:54.200 --> 00:01:57.960
He does have, what he's going to do is he's going to release one part every week.

00:01:57.960 --> 00:02:01.540
But if you can't wait that long, you can buy his ebook.

00:02:01.540 --> 00:02:03.320
I think it's just like 10 bucks or something.

00:02:03.320 --> 00:02:04.320
Yeah, totally affordable.

00:02:04.580 --> 00:02:05.820
And that's what I'm reading right now.

00:02:05.820 --> 00:02:09.520
And yeah, his video, he says he's planning on January for the video version.

00:02:09.520 --> 00:02:09.860
Yep.

00:02:09.860 --> 00:02:10.860
Very cool.

00:02:10.860 --> 00:02:11.300
Very cool.

00:02:11.300 --> 00:02:12.300
Speaking of new releases.

00:02:12.300 --> 00:02:13.800
New releases and the web.

00:02:13.800 --> 00:02:14.660
Amazing stuff.

00:02:14.660 --> 00:02:17.140
Django 2.0 is released.

00:02:17.140 --> 00:02:19.840
And this is a huge, huge change.

00:02:19.840 --> 00:02:26.060
It has been many, many moons since major point release of Django has come out.

00:02:26.060 --> 00:02:27.940
I mean, after all, it's only version two, right?

00:02:27.940 --> 00:02:29.220
This is a huge deal.

00:02:29.220 --> 00:02:32.340
And it's a lot of cool new features.

00:02:32.640 --> 00:02:37.340
One of the things that they added that I really like, and I don't know, it's always made me

00:02:37.340 --> 00:02:42.480
just crazy when I looked at Django is the fact of writing regular expressions for the routing,

00:02:42.480 --> 00:02:46.980
which is I want to take this URL and figure out which view method that goes to.

00:02:46.980 --> 00:02:49.900
That used to be a regular expression, which was painful.

00:02:49.900 --> 00:02:53.680
Now it's much more like Flask and Pyramid.

00:02:53.680 --> 00:02:57.860
You just put little identifiers, like variable names in cutout URL.

00:02:57.860 --> 00:02:59.300
And then that's how it maps over.

00:02:59.300 --> 00:03:00.120
And you even have types.

00:03:00.200 --> 00:03:06.480
You can say it has to map to slash users slash user ID colon enter.

00:03:06.480 --> 00:03:07.500
I think enter goes first.

00:03:07.500 --> 00:03:09.880
But there's this nice routing syntax.

00:03:09.880 --> 00:03:16.660
There's some nice responsive design changes, better querying over some of the query sets.

00:03:16.660 --> 00:03:18.040
These are all cool.

00:03:18.040 --> 00:03:25.260
They have a new versioning, what they're calling loose form of semantic versioning.

00:03:25.260 --> 00:03:32.320
So if you look at the possible versions, we have two, maybe it'll be a 2.1 and then a 2.2.

00:03:32.320 --> 00:03:37.720
And then that 2.2, maybe that's something they're calling stable long-term support LTS.

00:03:37.720 --> 00:03:39.320
So it might be 2.2 LTS.

00:03:39.320 --> 00:03:42.840
And then if they go anything beyond the LTS, that's a three.

00:03:42.840 --> 00:03:45.320
Then a 3.1, then a 3.2 LTS.

00:03:45.320 --> 00:03:52.660
So anytime you go into new territory past the LTS version, it's a major version increment now.

00:03:52.660 --> 00:03:52.980
Okay.

00:03:52.980 --> 00:03:53.700
It's interesting.

00:03:53.700 --> 00:03:54.220
Yeah.

00:03:54.220 --> 00:03:59.620
So I suspect that we'll see major Django version numbers coming faster because of that.

00:03:59.620 --> 00:04:00.660
But I'm not sure.

00:04:00.660 --> 00:04:01.480
I guess we'll have to see.

00:04:01.480 --> 00:04:04.900
And then there is some exciting thing about Python 3.

00:04:05.080 --> 00:04:06.000
Yeah, it's very exciting.

00:04:06.000 --> 00:04:09.120
The legacy Python is dealt yet another blow.

00:04:09.120 --> 00:04:15.920
So Django has had a significant disproportionate influence on the adoption of Python 3.

00:04:15.920 --> 00:04:20.960
For example, when they switched their tutorials by default to use Python 3 versus Python 2,

00:04:20.960 --> 00:04:26.500
that dramatically changed the usage by numbers on PyPI.

00:04:26.680 --> 00:04:30.460
And so now they've actually dropped support for Python 2.

00:04:30.460 --> 00:04:34.640
It's the first version of Django that says, you know, Python 2, that's, you know, thanks.

00:04:34.640 --> 00:04:36.060
But that's not for us.

00:04:36.060 --> 00:04:37.660
It's Python 3 only going forward.

00:04:37.660 --> 00:04:37.880
Yeah.

00:04:37.880 --> 00:04:44.840
And because of that, I've seen a few people mention on Twitter that working with the code base is a lot easier now

00:04:44.840 --> 00:04:49.520
because there aren't a lot of backwards compatible things in there.

00:04:49.520 --> 00:04:52.180
They were able to clean up the code base quite a bit for this.

00:04:52.180 --> 00:04:53.340
So I think it's great.

00:04:53.340 --> 00:04:54.400
I think it's great as well.

00:04:54.400 --> 00:04:59.680
And yeah, it definitely makes working on new features easier because you don't have to write them twice in some sense.

00:04:59.680 --> 00:05:01.460
And there's a bunch of small changes.

00:05:01.460 --> 00:05:03.140
I don't want to read them all off to you.

00:05:03.140 --> 00:05:11.700
But just to give you like a sense, down in Django contrib.auth, luckily they're doing password hashing and folding.

00:05:11.700 --> 00:05:16.380
So not just hashing with salt, but then you take that and you hash that and you take that and you hash that.

00:05:16.380 --> 00:05:18.820
And then they used to do that 36,000 times.

00:05:18.820 --> 00:05:20.500
Now they do that 100,000 times.

00:05:20.500 --> 00:05:25.720
So it's more computationally expensive to guess the password if somehow the database were to leak.

00:05:25.720 --> 00:05:28.760
And so there's just tons of little cool changes like that throughout there as well.

00:05:28.760 --> 00:05:33.000
But probably the biggest one people will notice is the simplified URL routing.

00:05:33.000 --> 00:05:33.980
Yeah, that's nice.

00:05:33.980 --> 00:05:35.980
So you've got a bunch of rules for us or something, huh?

00:05:35.980 --> 00:05:36.740
I do.

00:05:36.740 --> 00:05:37.480
What's up with that?

00:05:37.580 --> 00:05:41.140
I'm usually somebody that doesn't follow a lot of rules.

00:05:41.140 --> 00:05:49.940
But one of the things I embraced when coming into Python is the notion of that there's kind of a coding style that everyone follows.

00:05:49.940 --> 00:05:53.940
Or a lot of people follow on open source projects, which is PEP 8.

00:05:53.940 --> 00:05:55.280
And then it's extended.

00:05:55.700 --> 00:06:04.280
So there's when I started using type checkers like Lint or at the time I started it, the way to check for PEP 8 was a tool called PEP 8.

00:06:04.280 --> 00:06:06.120
That's now been changed.

00:06:06.120 --> 00:06:08.240
The name has changed to PICodeStyle.

00:06:08.240 --> 00:06:12.300
But now I usually use Flake8 for my Linter.

00:06:12.300 --> 00:06:15.020
And there's a...

00:06:15.020 --> 00:06:17.900
So Flake8 covers PICodeStyle, which is PEP 8.

00:06:18.160 --> 00:06:22.840
And then it covers PyFlakes, which does a lot of traditional Lint stuff to catch bugs.

00:06:22.840 --> 00:06:26.800
And then a McCabe complexity checker.

00:06:26.800 --> 00:06:30.200
And that one, I actually have tried to figure that out several times.

00:06:30.200 --> 00:06:31.720
And I don't know what it does.

00:06:31.720 --> 00:06:31.940
Nice.

00:06:31.940 --> 00:06:37.260
Yeah, cyclomatic complexity is a pretty interesting metric for code maintainability.

00:06:37.260 --> 00:06:43.460
So the idea is how many different decision paths are possible through that code.

00:06:43.460 --> 00:06:44.360
All right.

00:06:44.380 --> 00:06:51.280
So if you had a method of cyclomatic complexity 5, there's five separate execution paths that could go through there.

00:06:51.280 --> 00:06:55.740
There could be one if case that does an early return, another that's an if, elif, elif.

00:06:55.740 --> 00:07:02.700
And taking all the possible ways in which you could go through those conditionals and loops and whatnot, there would be five possibilities.

00:07:02.700 --> 00:07:05.680
So meaning basically you need five tests minimum to cover that.

00:07:05.680 --> 00:07:06.000
Okay.

00:07:06.000 --> 00:07:11.640
I'm not sure what the check is for McCabe, what the complexity number is that they're flagging for.

00:07:12.260 --> 00:07:15.680
But I usually turn it on anyway because I want to know if my code's a little too complex.

00:07:15.680 --> 00:07:23.100
The issue with it is a lot of these spit out an error message with a one-liner explaining what it is.

00:07:23.100 --> 00:07:38.280
And so what I have for us today is called the big old list of rules, which translates all of those errors and warning numbers into very nice one-page descriptions of what they are with links to more information.

00:07:38.660 --> 00:07:39.680
And I really like it.

00:07:39.680 --> 00:07:41.100
I'm going to be using this all the time now.

00:07:41.100 --> 00:07:41.740
That's really cool.

00:07:41.740 --> 00:07:43.320
I feel like there's an opportunity.

00:07:43.320 --> 00:07:48.140
First of all, well done, Grant, for writing this and putting this all out for everyone.

00:07:48.140 --> 00:07:55.000
But I think there's an opportunity for editor of plugins, whether you're using Sublime, Visual Studio Code, or PyCharm, or whatever.

00:07:55.000 --> 00:08:00.460
You could probably get a plugin that would turn that into a hyperlink that shows the details from this list.

00:08:00.460 --> 00:08:01.160
And that would be awesome.

00:08:01.160 --> 00:08:01.620
Oh, yeah.

00:08:01.620 --> 00:08:02.120
That'd be good.

00:08:02.500 --> 00:08:02.640
Yeah.

00:08:02.640 --> 00:08:03.160
Yeah.

00:08:03.160 --> 00:08:06.560
I'm using, so PyCharm does this, checks for a lot of this stuff.

00:08:06.560 --> 00:08:10.380
And yeah, and I usually turn it on for pytest too.

00:08:10.380 --> 00:08:13.300
I have my pytest plugin to check Flake 8.

00:08:13.300 --> 00:08:17.280
Once you find an error trying to fix it, it's good to know what it is.

00:08:17.280 --> 00:08:17.660
Yeah.

00:08:17.660 --> 00:08:19.720
Especially when it's just E112.

00:08:19.720 --> 00:08:21.220
Like, what the heck does that mean, right?

00:08:21.220 --> 00:08:21.820
Yeah.

00:08:22.460 --> 00:08:25.140
I mean, you may be really good and know them, but I don't know.

00:08:25.140 --> 00:08:26.380
Awesome.

00:08:26.380 --> 00:08:35.340
So before we get on to the next item, just want to let everyone know that this podcast and really all the sites that I run are coming to you through DigitalOcean.

00:08:35.340 --> 00:08:37.640
I have, gosh, it's just a growing list.

00:08:37.640 --> 00:08:45.480
I think I probably have eight servers over there now doing all sorts of hard work and working together on various services and database connectivity and whatnot.

00:08:45.680 --> 00:08:53.580
So super excited about working with DigitalOcean and talking about their stuff because it's really, really been great to work with.

00:08:53.580 --> 00:09:07.580
So if you're looking for cheap, reliable, fast servers that are simple and not, you know, a huge mess of a thousand features like you might get somewhere like AWS or Azure, you just want to have a server and work with it in a really nice way.

00:09:07.580 --> 00:09:11.580
Check them out at DigitalOcean.com and let them know that Python Bytes sent you.

00:09:11.580 --> 00:09:11.960
Nice.

00:09:11.960 --> 00:09:12.240
Yeah.

00:09:12.280 --> 00:09:15.440
We could probably contact them with requests as well.

00:09:15.440 --> 00:09:18.480
We could probably like do some sort of API and talk to them.

00:09:18.480 --> 00:09:21.460
But if you want to test it, you need to mock out your request, right?

00:09:21.460 --> 00:09:21.960
Definitely.

00:09:21.960 --> 00:09:28.280
One of the challenges, I think there's a few things that are really make testing sticky, tricky, whatever.

00:09:28.280 --> 00:09:30.540
One of them is time.

00:09:30.540 --> 00:09:34.180
The other one is the network and external services.

00:09:34.180 --> 00:09:37.320
Some of that being requests type things, some of that being databases.

00:09:37.960 --> 00:09:43.200
So any chance you get to cleanly sort of mock that out is really nice.

00:09:43.200 --> 00:09:46.020
And so this one actually comes from a friend of the show, Anthony Shaw.

00:09:46.020 --> 00:09:50.140
And he has this thing called requests static mock.

00:09:50.460 --> 00:09:54.000
And I think we were recently talking about something with mocking requests.

00:09:54.000 --> 00:09:58.380
And he's like, you should check out request static mock.

00:09:58.380 --> 00:09:59.500
And so I did.

00:09:59.500 --> 00:10:00.200
And it's pretty cool.

00:10:00.200 --> 00:10:02.860
So I decided to make it one of the things we're talking about this week.

00:10:03.120 --> 00:10:10.800
And the idea is you can create a request session and then mock that out like, hey, I want that return of 503 service unavailable.

00:10:10.800 --> 00:10:17.540
Or I'd like when you make this request to this URL, return this JSON file as the response.

00:10:17.540 --> 00:10:21.080
So really easy to swap out the testing behavior.

00:10:21.080 --> 00:10:26.640
Like if your code somewhere deep down calls into requests, but you can do it without monkey patching.

00:10:26.760 --> 00:10:32.420
Yeah, that's the neat part is it's without monkey patching or doing a lot of these test based mocks.

00:10:32.420 --> 00:10:33.360
It's pretty cool.

00:10:33.360 --> 00:10:34.300
Yeah, it definitely is.

00:10:34.300 --> 00:10:36.340
Yeah, you don't really mock stuff as much.

00:10:36.340 --> 00:10:37.580
You kind of just plug in the session.

00:10:37.580 --> 00:10:43.500
And, you know, if for people who don't know, the session object is a thing that comes from requests, which is actually pretty interesting.

00:10:43.740 --> 00:10:50.900
So suppose you're going to start talking to a service and every single request has to have an off header.

00:10:50.900 --> 00:10:53.160
It has to have maybe a user agent.

00:10:53.160 --> 00:10:56.020
It has some other details, some kind of token type thing.

00:10:56.020 --> 00:10:56.460
Who knows?

00:10:56.460 --> 00:10:58.640
A lot of shared stuff.

00:10:58.640 --> 00:11:07.640
Or if you're going to try to submit a form and then you need to take a session on the server, like a cookie based session, and then go and do other things.

00:11:08.020 --> 00:11:13.720
You can't do that with just straight requests so easily so that you create one of these sessions and it keeps a persistent connection.

00:11:13.720 --> 00:11:17.540
It handles the cookies per, you know, across all the requests and stuff like that.

00:11:17.540 --> 00:11:19.140
So that's really handy.

00:11:19.140 --> 00:11:25.200
And what Anthony's thing does is create a sort of testing session variant of that.

00:11:25.200 --> 00:11:26.140
So it's pretty cool.

00:11:26.140 --> 00:11:27.220
So you can mock that thing out.

00:11:27.220 --> 00:11:27.460
Yeah.

00:11:27.500 --> 00:11:36.260
And the way you put it together, too, is the data that's coming back is just in like a, you can just set it up as like a tree structure in your file system.

00:11:36.260 --> 00:11:39.660
It's kind of like your old school HTML directory.

00:11:39.660 --> 00:11:40.540
That's right.

00:11:40.540 --> 00:11:44.360
With some index.html and all that kind of stuff.

00:11:44.360 --> 00:11:45.980
They just put it in there and it traverses that.

00:11:45.980 --> 00:11:46.300
That's cool.

00:11:46.300 --> 00:11:48.980
It's a nice interface for the developer as well.

00:11:48.980 --> 00:11:49.520
It's cool.

00:11:49.520 --> 00:11:49.760
Yep.

00:11:49.760 --> 00:11:50.700
Well done, Anthony.

00:11:50.700 --> 00:11:55.140
So you're going to give us a bit of a preview of Python 3.7, right?

00:11:55.140 --> 00:11:59.300
Because there's some pretty awesome stuff that just got approved or finalized.

00:11:59.300 --> 00:12:03.360
Data classes, which I didn't know it was on the fence for a while.

00:12:03.360 --> 00:12:09.520
But these are data classes have been approved by Guido and it's PEP557.

00:12:09.520 --> 00:12:13.780
And these are kind of a different form of regular old classes.

00:12:13.780 --> 00:12:16.480
But you can put a decorator on there for a data class.

00:12:16.480 --> 00:12:21.700
And then you can sort of say what your some data elements and what type they are.

00:12:21.700 --> 00:12:22.780
And you can assign defaults.

00:12:23.180 --> 00:12:27.520
And the cool thing about that is you don't have to write your own init statement.

00:12:27.520 --> 00:12:29.500
It kind of generates one for you.

00:12:29.500 --> 00:12:32.320
So the first time I saw these, I'm like, wait, that's not valid Python.

00:12:32.320 --> 00:12:33.080
What is this?

00:12:33.080 --> 00:12:34.220
What language is this?

00:12:34.220 --> 00:12:35.140
Yeah.

00:12:35.140 --> 00:12:41.520
So you could say like class C colon and then just A colon int new line.

00:12:41.520 --> 00:12:43.300
B colon int new line.

00:12:43.300 --> 00:12:48.960
And you just start out with a class when you create it that has an A and a B and those are both none.

00:12:48.960 --> 00:12:49.180
Right.

00:12:49.180 --> 00:12:51.060
Or you can even set default values.

00:12:51.060 --> 00:12:51.880
That's pretty cool.

00:12:51.880 --> 00:12:59.100
It lets you do more of the definers part of the class structure instead of the self dot attribute equals value through the dunder in it.

00:12:59.100 --> 00:13:03.640
But like you said, it still generates that dunder in it and then moves over the default values and all that.

00:13:03.640 --> 00:13:04.880
I kind of like the syntax.

00:13:04.880 --> 00:13:07.580
The first time I saw it, like you said, it's bracing.

00:13:07.820 --> 00:13:15.620
And it's like, this isn't Python, but it's kind of nice that you can just put that in one place and not worry about it too much.

00:13:15.620 --> 00:13:16.400
It's pretty clean.

00:13:16.400 --> 00:13:17.380
Definitely like it.

00:13:17.380 --> 00:13:17.580
Yeah.

00:13:17.580 --> 00:13:25.420
I find myself doing this sometimes and I'll just have to set everything to none or to zero or something like that because it won't work otherwise.

00:13:25.420 --> 00:13:26.240
But guess what?

00:13:26.240 --> 00:13:26.760
It does now.

00:13:26.760 --> 00:13:27.280
It's cool.

00:13:27.280 --> 00:13:35.460
And I also just found out that there is a 370A3 developer build that's out that has this in it.

00:13:35.460 --> 00:13:37.820
So if people want to play with it, they can.

00:13:37.820 --> 00:13:43.380
But I probably wouldn't do much production code with it because 3.7 isn't scheduled until June.

00:13:43.380 --> 00:13:43.760
Okay.

00:13:43.760 --> 00:13:44.020
Yeah.

00:13:44.020 --> 00:13:46.540
So it's a little ways out, but still exciting to see this coming.

00:13:46.540 --> 00:13:48.280
I think this is pretty nice.

00:13:48.520 --> 00:13:54.540
So one of the things that this feels like I think is compared to and looks somewhat similar to is attrs.

00:13:54.540 --> 00:13:56.800
And attrs gets a lot of attention as well.

00:13:56.800 --> 00:13:58.460
What's the story between those two?

00:13:58.460 --> 00:14:01.060
I don't know the history of like how much.

00:14:01.060 --> 00:14:02.460
I know that, hi, Nick.

00:14:02.460 --> 00:14:04.920
Oh, he's going to clobber me again for getting his name wrong.

00:14:04.920 --> 00:14:11.120
But I think he was involved in talking with the core developers and talking about this data class.

00:14:11.120 --> 00:14:11.680
But I'm not sure.

00:14:11.680 --> 00:14:13.960
But anyway, there's a few.

00:14:13.960 --> 00:14:15.560
Adders is still great.

00:14:15.800 --> 00:14:19.440
And these data classes don't do everything that attrs does.

00:14:19.440 --> 00:14:25.620
And it has more validators and converters and a whole bunch more stuff that you can do.

00:14:25.620 --> 00:14:29.080
So it doesn't completely take the place of attrs.

00:14:29.080 --> 00:14:32.740
But for simple cases, I think it's a simpler interface.

00:14:32.740 --> 00:14:33.080
Yeah.

00:14:33.080 --> 00:14:33.380
Okay.

00:14:33.380 --> 00:14:35.000
That sounds good.

00:14:35.000 --> 00:14:42.100
The best example that I heard of why people wanted it in there is because the core developers wanted to use it on Python itself.

00:14:42.260 --> 00:14:48.000
And you can't use non-standard library stuff within the core of Python.

00:14:48.000 --> 00:14:48.260
Yeah.

00:14:48.260 --> 00:14:49.800
I think that's a really interesting point.

00:14:49.800 --> 00:14:51.880
And attrs is changing fast.

00:14:51.880 --> 00:14:53.500
It's still getting a lot done to it.

00:14:53.500 --> 00:15:00.740
And you don't want to hamper it and cover it in quicksand or some sort of tar, right?

00:15:00.740 --> 00:15:06.860
You want to slow it down by sticking it in the standard library and going, well, you can only change very slowly now and only every year.

00:15:07.040 --> 00:15:07.220
Yeah.

00:15:07.220 --> 00:15:10.720
That's some of the reason why requests isn't in the standard library, right?

00:15:10.720 --> 00:15:11.220
Exactly.

00:15:11.220 --> 00:15:11.600
Yeah.

00:15:11.600 --> 00:15:12.000
Same reason.

00:15:12.000 --> 00:15:12.980
All right.

00:15:12.980 --> 00:15:16.060
So for our final thing, I want to start with our first thing.

00:15:16.060 --> 00:15:16.540
Flask.

00:15:16.540 --> 00:15:17.080
Flask.

00:15:17.080 --> 00:15:17.580
Ah.

00:15:17.580 --> 00:15:21.720
My version of Flask I want to talk about is three times faster than your version of Flask.

00:15:21.720 --> 00:15:23.240
So how does it do that?

00:15:23.240 --> 00:15:27.220
So there's this thing called Court, which I haven't done much with Court.

00:15:27.220 --> 00:15:34.660
but it's kind of like a wrapper around some of the AsyncIO stuff, but also an API that can run Flask apps.

00:15:34.660 --> 00:15:35.980
Like I said, I haven't done a ton with it.

00:15:35.980 --> 00:15:44.340
But Court is this thing that you can use that has the same API as Flask, but is AsyncIO friendly.

00:15:44.340 --> 00:15:54.000
So you can plug it into the super, super fast things like uv loop or AsyncPG for asynchronous Postgres, which is pretty awesome.

00:15:54.000 --> 00:15:56.260
And there's some really amazing benchmarks there.

00:15:56.420 --> 00:16:04.100
So Flask, along with Django and along with Pyramid and all the others, they don't support any Async and IO stuff.

00:16:04.100 --> 00:16:15.980
And they can't take advantage of basically releasing the thread to go do other work when it's, say, waiting on a database or on a call over request or something like that.

00:16:15.980 --> 00:16:20.000
Just because they're all using Whiskey, that's not how Whiskey works.

00:16:20.620 --> 00:16:31.400
So you can plug in a Court, which basically has the same API as Flask, and you just have to make a few minor changes to get your code to go much faster.

00:16:31.400 --> 00:16:33.540
So here's an article with a demo application.

00:16:33.540 --> 00:16:40.800
They've got benchmarks and stuff saying we're getting roughly three times the speed by just switching a few things around in the app.

00:16:40.800 --> 00:16:41.800
Yeah, I think that's cool.

00:16:41.800 --> 00:16:43.420
I definitely need to try this.

00:16:43.420 --> 00:16:50.580
Yeah, so the things you have to do, obviously, if you want to take advantage of AsyncIO, is you have to make your functions async.

00:16:51.160 --> 00:16:51.320
Right?

00:16:51.320 --> 00:16:53.000
Otherwise, they're just regular functions.

00:16:53.000 --> 00:16:54.080
They go just the same speed.

00:16:54.080 --> 00:16:56.580
So you would put Async in front of your view methods.

00:16:56.580 --> 00:17:06.740
And then when you call into things like databases or web services via request, say, you have to await those to basically tell Python, give up my thread.

00:17:06.740 --> 00:17:07.860
I'm waiting on this.

00:17:07.860 --> 00:17:09.320
And then pick it up when it gets back.

00:17:09.320 --> 00:17:09.620
Right?

00:17:09.620 --> 00:17:12.900
Put me back somewhere farther down in the loop when this returns.

00:17:13.640 --> 00:17:14.880
So that's all cool.

00:17:14.880 --> 00:17:20.240
But your database access has to have some sort of asynchronous component.

00:17:20.240 --> 00:17:21.760
So when you do a query, you can wait on it.

00:17:21.760 --> 00:17:23.240
Otherwise, it's kind of useless again.

00:17:23.240 --> 00:17:29.040
So that's why it's both the Quart but also AsyncPG.

00:17:29.040 --> 00:17:29.960
Right?

00:17:29.960 --> 00:17:30.840
Which is pretty cool.

00:17:30.980 --> 00:17:34.860
So it's not entirely easy to switch over depending on what you're doing.

00:17:34.860 --> 00:17:36.160
Like if you're using SQLAlchemy.

00:17:36.160 --> 00:17:38.940
SQLAlchemy, I don't believe, supports anything with Async.

00:17:38.940 --> 00:17:40.060
So you're kind of out of luck.

00:17:40.060 --> 00:17:42.840
It depends on what you depend upon, actually.

00:17:42.840 --> 00:17:43.200
Okay.

00:17:43.300 --> 00:17:45.120
It's easy to switch if it's going to work at all.

00:17:45.120 --> 00:17:45.500
How's that?

00:17:45.500 --> 00:17:45.780
Yeah.

00:17:45.780 --> 00:17:54.740
And one of the things I think is neat about this, and it's a clever idea, is instead of inventing a completely new framework, it is a completely new framework.

00:17:54.740 --> 00:17:59.000
But they wanted to, like, I think it's a good idea to slow down the learning curve.

00:17:59.000 --> 00:18:00.860
You've got to figure out the Async stuff.

00:18:00.860 --> 00:18:05.260
But you don't really have to refigure out how the framework works because they've said.

00:18:05.260 --> 00:18:06.060
Yeah, that's cool.

00:18:06.060 --> 00:18:07.500
The framework's just like Flask.

00:18:07.500 --> 00:18:09.660
That is such a good observation.

00:18:09.660 --> 00:18:11.020
And it's really right.

00:18:11.880 --> 00:18:14.500
There's HTTP, AIO, HTTP.

00:18:14.500 --> 00:18:15.500
I don't remember the order.

00:18:15.500 --> 00:18:15.780
Sorry.

00:18:15.780 --> 00:18:17.360
But there's that.

00:18:17.360 --> 00:18:18.680
There's Jepronto.

00:18:18.680 --> 00:18:19.580
There's Sanic.

00:18:19.580 --> 00:18:25.300
There's all these other frameworks trying to take advantage of things like uv loop and Async and Await.

00:18:25.300 --> 00:18:27.680
But they're like, and you start from scratch.

00:18:27.680 --> 00:18:29.920
And you learn a totally new framework.

00:18:29.920 --> 00:18:34.740
With this, you could probably go take Miguel's tutorial thing and then go make it faster.

00:18:34.740 --> 00:18:35.360
It's kind of cool.

00:18:35.360 --> 00:18:36.520
And that's what I plan on doing.

00:18:36.520 --> 00:18:37.300
Yeah.

00:18:37.300 --> 00:18:38.380
Perfect.

00:18:38.380 --> 00:18:38.640
Be cool.

00:18:38.640 --> 00:18:39.460
All right.

00:18:39.460 --> 00:18:41.520
Well, that's our news for this week, Brian.

00:18:41.520 --> 00:18:44.340
Anything you got going on over there?

00:18:44.340 --> 00:18:46.680
No, I'm just trying to learn Flask, man.

00:18:46.680 --> 00:18:47.040
Awesome.

00:18:47.040 --> 00:18:48.080
That sounds really fun.

00:18:48.080 --> 00:18:52.020
So are you familiar with the Pythonic staff of Enlightenment?

00:18:52.020 --> 00:18:52.540
Yes.

00:18:52.540 --> 00:18:54.380
I carried it around for a while at PyCon.

00:18:54.380 --> 00:18:54.840
Yes.

00:18:54.840 --> 00:18:55.500
So did I.

00:18:55.940 --> 00:18:57.860
So a lot of people probably don't know about this.

00:18:57.860 --> 00:19:02.720
There's a picture of me with Anthony Shaw, who I mentioned in the mocking bit.

00:19:02.720 --> 00:19:09.060
And me walking around with this giant, I don't know, it's probably four feet tall, this big, heavy staff.

00:19:09.060 --> 00:19:11.920
At the end, it has like a massive Python logo.

00:19:12.560 --> 00:19:24.300
And so one of the guys that was involved in creating that thing originally actually decided, so many people asked for it, he's creating a store where you can buy your very own Pythonic staff of Enlightenment.

00:19:24.300 --> 00:19:28.140
So he's like, hey, would you mind letting people know about the staff?

00:19:28.140 --> 00:19:29.400
I'm like, yeah, this is pretty cool.

00:19:29.400 --> 00:19:30.220
I'll let people know.

00:19:30.220 --> 00:19:30.840
Yeah.

00:19:30.940 --> 00:19:32.000
I haven't checked it out yet.

00:19:32.000 --> 00:19:33.000
Any idea how much it is?

00:19:33.000 --> 00:19:34.480
I think it's like a hundred bucks US.

00:19:34.480 --> 00:19:34.980
Okay.

00:19:34.980 --> 00:19:37.000
I may need one anyway.

00:19:37.000 --> 00:19:37.480
I know.

00:19:37.480 --> 00:19:38.820
Well, Christmas is coming.

00:19:38.820 --> 00:19:41.320
Everyone needs a cool Python staff for Christmas.

00:19:41.320 --> 00:19:42.960
Yeah.

00:19:42.960 --> 00:19:44.260
Anyway, I thought that was fun.

00:19:44.260 --> 00:19:46.260
So I thought I'd throw that in there at the end for you guys.

00:19:46.260 --> 00:19:46.840
That's nice.

00:19:46.840 --> 00:19:47.280
Cool.

00:19:47.280 --> 00:19:47.980
Yeah, indeed.

00:19:47.980 --> 00:19:48.380
All right.

00:19:48.380 --> 00:19:50.460
Well, Brian, great to chat with you as always.

00:19:50.460 --> 00:19:51.500
And thanks everyone for listening.

00:19:51.500 --> 00:19:51.960
Thank you.

00:19:51.960 --> 00:19:55.180
Thank you for listening to Python Bytes.

00:19:55.180 --> 00:19:57.760
Follow the show on Twitter via at Python Bytes.

00:19:57.760 --> 00:20:00.640
That's Python Bytes as in B-Y-T-E-S.

00:20:00.640 --> 00:20:04.080
And get the full show notes at pythonbytes.fm.

00:20:04.080 --> 00:20:08.400
If you have a news item you want featured, just visit pythonbytes.fm and send it our way.

00:20:08.400 --> 00:20:11.120
We're always on the lookout for sharing something cool.

00:20:11.120 --> 00:20:14.500
On behalf of myself and Brian Okken, this is Michael Kennedy.

00:20:14.500 --> 00:20:18.120
Thank you for listening and sharing this podcast with your friends and colleagues.

