WEBVTT

00:00:00.001 --> 00:00:04.580
Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to

00:00:04.580 --> 00:00:09.920
your earbuds. This is episode 287, recorded June 7th, and I am Brian Okken.

00:00:09.920 --> 00:00:10.680
I'm Michael Kennedy.

00:00:10.680 --> 00:00:12.160
It's good to talk to you, Michael.

00:00:12.160 --> 00:00:13.620
Yeah, good to see you again, Brian.

00:00:13.620 --> 00:00:14.160
Yeah.

00:00:14.160 --> 00:00:18.940
Again, we've got our wardrobe matching our background here, which is fantastic.

00:00:18.940 --> 00:00:22.500
Yeah. We like, you know, texted each other in the morning to make sure.

00:00:22.500 --> 00:00:27.840
Feeling purple. I'm going to get a new shirt. No, it's great. Good to see you as always.

00:00:28.180 --> 00:00:30.340
Lots of fun Python things to talk about here.

00:00:30.340 --> 00:00:32.720
Yeah. Yeah. Well, let's jump into the first one.

00:00:32.720 --> 00:00:38.680
The first thing that I want to talk about here is distributing Python applications.

00:00:38.680 --> 00:00:45.320
Now, this is a little bit in the Python GUIs side of thing, something you just can't get enough of

00:00:45.320 --> 00:00:49.500
in terms of like, hey, could we have more ways to do this that are like awesome?

00:00:49.500 --> 00:00:51.840
How about if we had ways that were automatic?

00:00:51.840 --> 00:00:52.660
Yeah.

00:00:52.660 --> 00:01:00.360
So I want to talk about this thing by Brent Bola-Bregretz called AutoPy2exe.

00:01:00.360 --> 00:01:03.760
And it basically does what it says right in the name there.

00:01:03.760 --> 00:01:10.420
Converts a .py file to a .exe using a simple graphical interface.

00:01:10.560 --> 00:01:18.180
Now, this GitHub description is a bit of a Windows bias because it will also create it to Mac apps as well,

00:01:18.180 --> 00:01:21.300
to .app files. So it's not just a Windows thing.

00:01:21.300 --> 00:01:21.640
Cool.

00:01:21.960 --> 00:01:30.920
It's pretty popular. It has 2,000 stars, 400 forks. And what it is, is a UI on top of things like PyToApp or PyInstaller,

00:01:30.920 --> 00:01:37.400
specifically PyInstaller. So what you do is you fire this thing up and out pops this user interface

00:01:37.400 --> 00:01:41.980
that if you're watching the YouTube stream, you can see there's a user interface here.

00:01:41.980 --> 00:01:48.980
And it just says, pick the starting Python file for your application. And you can say, what do you want the output to be?

00:01:48.980 --> 00:01:51.260
One file or one directory?

00:01:51.260 --> 00:01:52.000
Okay.

00:01:52.000 --> 00:01:56.500
I think we all want it to be one file, probably generally, but maybe a directory. I don't know.

00:01:56.500 --> 00:01:59.000
What else you're going to, maybe you want to do some other things there.

00:01:59.280 --> 00:02:08.020
But what I did is I tried this against my URL by little appy thing, which let me pull that up.

00:02:08.020 --> 00:02:18.880
This is something I built a while ago with rumps. It's fantastic. Ridiculously uncomplicated menu bar apps or something like that for Mac.

00:02:18.880 --> 00:02:26.580
And all it is, is a little thing that goes up in your Mac bar and it has like, you know, sluggify text or trim it or lower cases.

00:02:26.580 --> 00:02:39.580
It's just, I'm constantly taking names of like file names and turning them into something I could put as a URL or like a title of a video or something and turning it into something that would be a good URL.

00:02:39.580 --> 00:02:47.040
So that's what this little app is for. But here's the thing is it's a Python app that runs in the menu bar on my Mac with no terminal view.

00:02:47.040 --> 00:02:56.420
And I wanted to be able to distribute it to people. And so the way you get it is you just download a zip file, which is just the zip up dot app executable.

00:02:56.420 --> 00:03:02.420
Right. So I had done a bunch of stuff with the setup and all those kinds of things with pi installer to build this.

00:03:02.420 --> 00:03:10.400
So my test case was, well, let me take this auto pi to exe thing and just point it at that and see what happens.

00:03:10.400 --> 00:03:13.180
And what happened was good things. It was really interesting.

00:03:14.040 --> 00:03:23.080
There's an app dot pi, but there's dependent Python files that it uses. I mean, I'm not a beast. I don't write my entire application in one file.

00:03:23.080 --> 00:03:29.720
Like there's other things broken apart in there and that gets bundled up and it somehow discovered that all those all in.

00:03:29.840 --> 00:03:37.840
So I just picked the top level file and it found the dependencies, you know, the requirements.txt type dependencies and so on.

00:03:37.840 --> 00:03:42.200
And it created a dot app file that as far as I could tell ran just fine.

00:03:42.200 --> 00:03:42.980
That's cool.

00:03:42.980 --> 00:03:43.640
Isn't that cool?

00:03:43.640 --> 00:03:44.620
Yeah, I like it.

00:03:44.620 --> 00:03:47.740
You can decide if it's a window based application.

00:03:47.740 --> 00:03:51.680
So hide the console, which is what I said because I want it to run in the menu bar.

00:03:51.680 --> 00:03:58.260
But if it was a console based app, but you just wanted to distribute it as a single thing with no Python, well, no Python requirements.

00:03:58.260 --> 00:04:00.220
You could create a console based app.

00:04:00.220 --> 00:04:01.220
You set the icon.

00:04:01.220 --> 00:04:03.640
You can add in additional files.

00:04:03.820 --> 00:04:12.800
So if there's like, you know, JSON configuration files or YAML files or images or something like that, you need to take a long, you can configure that there.

00:04:12.800 --> 00:04:16.780
And then there's an advanced section that expands out to be like pages of stuff that I don't remember.

00:04:16.780 --> 00:04:17.760
Same thing for settings.

00:04:17.760 --> 00:04:24.360
And then you just click the big convert to pie to EXE button and you get ironically not an EXE, but a dot app file.

00:04:24.360 --> 00:04:25.440
And there you go.

00:04:25.440 --> 00:04:26.200
That's cool.

00:04:26.200 --> 00:04:26.920
Isn't that cool?

00:04:26.920 --> 00:04:32.500
So for people who are playing around with this, I think they, you know, they even have, they must be listening to us here.

00:04:32.900 --> 00:04:38.040
They even have a little animated GIF of how this all works right on the GitHub.

00:04:38.040 --> 00:04:38.900
That's pretty good.

00:04:38.900 --> 00:04:42.780
So if you want to see how it works, I guess there's not a whole lot, but you browse for the icon.

00:04:42.780 --> 00:04:45.640
You go in there and you check off some things and then you just hit build.

00:04:45.640 --> 00:04:49.020
And it takes a little while, but you know, that's pie to EXE.

00:04:49.020 --> 00:04:49.800
That's how it goes.

00:04:49.800 --> 00:04:55.640
And it just sits there and it cranks away for a while, bundles it all up and yeah, got a little executable.

00:04:55.640 --> 00:05:02.160
So if this is something you want to play with, but you're like, ah, it's kind of a real pain to go and figure out, you know,

00:05:02.200 --> 00:05:11.820
all the setup pie commands in order to get it to do the pie installer commands and whatnot, then, you know, you can definitely give this a shot.

00:05:11.820 --> 00:05:12.520
I think it's pretty neat.

00:05:12.520 --> 00:05:15.360
I think with mine, I didn't use pie to installer.

00:05:15.360 --> 00:05:16.740
I think I use pie to app.

00:05:16.740 --> 00:05:17.120
Yeah.

00:05:17.120 --> 00:05:17.720
That's what I used.

00:05:17.720 --> 00:05:18.900
So pretty neat.

00:05:18.900 --> 00:05:19.320
Yeah.

00:05:19.320 --> 00:05:19.920
Check that out.

00:05:19.920 --> 00:05:20.460
Nice.

00:05:20.580 --> 00:05:23.900
I think people will find it helpful for ways to distribute Python apps.

00:05:23.900 --> 00:05:24.540
Yeah.

00:05:24.540 --> 00:05:27.500
And I like that it looks pretty professional looking.

00:05:27.500 --> 00:05:34.860
And then also, especially, I mean, especially with internal, like internal company stuff, there's, that happens a lot where you want to share something.

00:05:34.860 --> 00:05:35.260
Yeah.

00:05:35.260 --> 00:05:35.840
Around.

00:05:35.840 --> 00:05:36.180
Yeah.

00:05:36.180 --> 00:05:36.280
Yeah.

00:05:36.280 --> 00:05:37.600
Like just download this and run it.

00:05:37.600 --> 00:05:42.660
Please don't ask me how to set up a path so that your Python, that's not Python three, three.

00:05:42.660 --> 00:05:43.540
Yeah.

00:05:43.760 --> 00:05:45.420
So whatever, right, is the one that runs it.

00:05:45.420 --> 00:05:47.180
Nobody needs to know that it's Python underneath.

00:05:47.180 --> 00:05:47.580
So.

00:05:47.580 --> 00:05:48.860
Yeah, exactly.

00:05:48.860 --> 00:05:49.640
So.

00:05:49.640 --> 00:05:50.280
Oh, cool.

00:05:50.280 --> 00:05:50.980
I like it.

00:05:50.980 --> 00:05:54.580
Oh, one other thing, by the way, it's a GUI application.

00:05:54.580 --> 00:05:56.080
It's self-written in Python.

00:05:56.080 --> 00:05:59.260
So you may wonder, well, what is it doing, right?

00:05:59.260 --> 00:06:01.000
Maybe it's bundled itself.

00:06:01.000 --> 00:06:02.860
Obviously, that'd be very meta, right?

00:06:02.860 --> 00:06:07.760
Like if autopy2xc could deliver an autopy2xc itself, that's obviously lovely.

00:06:07.760 --> 00:06:12.720
It reminded me that I have Chrome installed when I ran it.

00:06:13.100 --> 00:06:17.620
So what it does is it runs something in the background, then it fires up Chrome, which

00:06:17.620 --> 00:06:23.160
becomes the UI in this kind of Windows looking Chrome window.

00:06:23.160 --> 00:06:28.060
And it's not quite an Electron app, but it's Electron in a style.

00:06:28.060 --> 00:06:32.060
So anyway, it's an interesting little UI app itself.

00:06:32.060 --> 00:06:34.420
I'm not sure what it's doing, but it works.

00:06:34.420 --> 00:06:35.060
Nice.

00:06:35.060 --> 00:06:35.960
All right.

00:06:35.960 --> 00:06:38.820
Well, I'd like to talk about Jupyter.

00:06:38.820 --> 00:06:40.320
So Jupyter Notebooks.

00:06:40.320 --> 00:06:40.760
Oh, yeah.

00:06:40.760 --> 00:06:41.940
So this is.

00:06:41.940 --> 00:06:42.500
How do you use it?

00:06:42.940 --> 00:06:43.640
How do you use it?

00:06:43.640 --> 00:06:49.100
So like, I was just fascinated by the clickbaitiness of this, but it's okay.

00:06:49.100 --> 00:06:54.240
Eight surprising ways to, eight surprising ways how to use Jupyter Notebooks.

00:06:54.240 --> 00:06:57.760
And I got to say, I didn't know you could do some of this stuff with Jupyter.

00:06:57.760 --> 00:06:58.620
So it's pretty cool.

00:06:58.620 --> 00:07:01.200
So the first one, package development.

00:07:01.200 --> 00:07:02.140
Why would you?

00:07:02.140 --> 00:07:03.100
I don't know why.

00:07:03.100 --> 00:07:08.540
But, you know, some people that are more comfortable in Jupyter than they are in IDE or something.

00:07:08.920 --> 00:07:09.420
Maybe it's good.

00:07:09.420 --> 00:07:16.540
So there's a package called MB Dev that you can use to, and it's by a company called Fast

00:07:16.540 --> 00:07:25.620
AI that you can use to help with package development, including, you know, trying to get your CI working

00:07:25.620 --> 00:07:30.420
and your tests all in one place and demos and documentation and stuff.

00:07:30.500 --> 00:07:31.440
So that's kind of neat.

00:07:31.440 --> 00:07:32.840
Like that idea.

00:07:32.840 --> 00:07:36.120
Oh, I definitely should try to play with that to see how that works.

00:07:36.120 --> 00:07:38.860
Apparently there's a video.

00:07:38.860 --> 00:07:42.040
Somebody gave a talk around it, I guess, maybe.

00:07:42.040 --> 00:07:42.520
Lovely.

00:07:42.520 --> 00:07:43.040
Yeah.

00:07:43.040 --> 00:07:44.340
Build a web app.

00:07:44.340 --> 00:07:47.280
So building a web app with Jupyter.

00:07:47.400 --> 00:07:49.300
I think that's actually a pretty cool idea.

00:07:49.300 --> 00:07:51.920
There's several suggestions using Voila.

00:07:51.920 --> 00:07:53.080
I think we covered that.

00:07:53.080 --> 00:07:55.360
I think, yeah, we've covered that before.

00:07:55.360 --> 00:07:56.720
But the other one, I don't think we have.

00:07:56.720 --> 00:07:57.500
PyPy widgets.

00:07:57.500 --> 00:08:00.340
I'm not sure what that one is.

00:08:00.340 --> 00:08:03.060
So I haven't looked at the widgets thing.

00:08:03.060 --> 00:08:06.020
But, you know, more widgets within your window.

00:08:06.020 --> 00:08:06.340
Sure.

00:08:06.340 --> 00:08:06.700
Why not?

00:08:06.700 --> 00:08:07.600
Why are there no?

00:08:07.600 --> 00:08:08.740
It's a widgets thing.

00:08:08.740 --> 00:08:10.780
You'd think there'd be images on the readme.

00:08:10.780 --> 00:08:11.580
Anyway.

00:08:11.580 --> 00:08:14.880
And then a framework called Mercury.

00:08:14.880 --> 00:08:17.180
And this shows up several times in this.

00:08:17.180 --> 00:08:25.400
So Mercury does a lot of stuff around Jupyter Notebooks and doing extra things.

00:08:25.400 --> 00:08:27.860
So this shows up several times in this list.

00:08:27.860 --> 00:08:33.900
So for one, for creating a web app, which is kind of neat,

00:08:33.900 --> 00:08:36.640
especially if you're sharing data and have interactive stuff,

00:08:36.640 --> 00:08:40.100
you might have doing stuff with a web application.

00:08:40.260 --> 00:08:40.920
That would be cool.

00:08:40.920 --> 00:08:42.240
Slide deck.

00:08:42.240 --> 00:08:43.660
Got to love it.

00:08:43.660 --> 00:08:50.460
I definitely want to try this out because using NB Convert or Mercury,

00:08:50.460 --> 00:08:54.120
apparently Mercury does that too, uses Reveal.js.

00:08:54.120 --> 00:08:57.660
I think a lot of people have tried Reveal.js before for slides.

00:08:57.660 --> 00:09:01.780
But building it within notebooks, building your slide decks within notebooks,

00:09:01.780 --> 00:09:06.240
and then having that just run, that's cool.

00:09:06.240 --> 00:09:07.460
Building a book.

00:09:07.460 --> 00:09:09.440
This is something else that sounds pretty interesting.

00:09:09.440 --> 00:09:14.640
I'd like to try doing some code, a notebook, a book-like thing.

00:09:14.640 --> 00:09:17.260
Now, I don't have, I'm curious about this.

00:09:17.260 --> 00:09:22.180
So the book, you build a website that looks like a book, but that's not a book.

00:09:22.980 --> 00:09:32.020
So it says it can be exported to a PDF file, but I don't see anywhere you're exporting to an EPUB or MOBI.

00:09:32.020 --> 00:09:35.700
So, you know, I call BS on whether that this is a book.

00:09:36.200 --> 00:09:39.420
This is a website that holds book contents as far as I can tell.

00:09:39.420 --> 00:09:40.560
Still cool, though.

00:09:40.560 --> 00:09:41.820
Running a blog.

00:09:41.820 --> 00:09:44.780
This is something I had no idea Nicola could do.

00:09:44.780 --> 00:09:45.920
So Nicola?

00:09:45.920 --> 00:09:46.840
Nicola?

00:09:46.840 --> 00:09:48.180
I don't know how to pronounce that.

00:09:48.180 --> 00:09:50.600
I've ran across it before.

00:09:50.600 --> 00:09:55.260
I'm not sure what we've covered it, but it's a static site generator.

00:09:56.200 --> 00:10:02.660
And it apparently can take notebooks files and just run notebooks as a blog.

00:10:02.660 --> 00:10:04.060
So that's pretty cool.

00:10:04.060 --> 00:10:05.500
Notebooks as a blog.

00:10:05.500 --> 00:10:06.280
Oh, that's interesting.

00:10:06.280 --> 00:10:07.480
Well, yeah.

00:10:07.480 --> 00:10:11.400
Especially if you're going to write about like some Python technique or something, you just do a little demo of it.

00:10:11.400 --> 00:10:15.840
And then publish that as a text thing, or I don't know if it outputs.

00:10:15.840 --> 00:10:17.400
I didn't read it close enough.

00:10:17.400 --> 00:10:23.460
Outputs the exports every notebook to an HTML file and then publish all the files on a static website.

00:10:23.460 --> 00:10:24.320
That's pretty neat.

00:10:24.320 --> 00:10:30.720
Doing reports and dashboards, that's kind of like Jupyter would rock at that.

00:10:30.720 --> 00:10:32.800
And I think we've covered stuff like this before.

00:10:32.800 --> 00:10:39.280
But one of the things in the dashboard section that I thought was neat was this Mercury tool has a schedule option.

00:10:39.700 --> 00:10:47.040
So once you set up the report, you can schedule it to execute, you know, like once a day or every hour or something like that.

00:10:47.040 --> 00:10:54.400
And that's pretty neat to not have it do constantly, but update your dashboard at a time.

00:10:54.400 --> 00:10:55.280
I do like that.

00:10:55.280 --> 00:10:56.060
That's really cool.

00:10:56.060 --> 00:11:00.120
So you could have some kind of dashboard instead of creating it in the full web app.

00:11:00.120 --> 00:11:01.520
You just publish this.

00:11:01.520 --> 00:11:03.520
But obviously you want it to refresh, right?

00:11:03.520 --> 00:11:03.960
Yeah.

00:11:03.960 --> 00:11:04.580
Yep.

00:11:04.580 --> 00:11:06.820
So anyway, that.

00:11:06.820 --> 00:11:07.920
Oh, last one.

00:11:07.920 --> 00:11:08.700
REST API.

00:11:08.980 --> 00:11:12.040
This is interesting.

00:11:12.040 --> 00:11:14.940
I wouldn't have thought to build a REST API with Jupyter.

00:11:14.940 --> 00:11:18.360
So I guess you can do all this stuff.

00:11:18.360 --> 00:11:20.660
Whether or not you should, I guess it's up to you.

00:11:20.660 --> 00:11:21.980
But anyway.

00:11:21.980 --> 00:11:22.880
Yeah, for sure.

00:11:22.880 --> 00:11:28.720
Anthony on the audience says, Nicola works well as a static blog generator, preferred over Pelican.

00:11:28.720 --> 00:11:31.320
Well, that's saying something.

00:11:31.320 --> 00:11:31.960
Nice.

00:11:31.960 --> 00:11:32.720
That is.

00:11:32.720 --> 00:11:33.800
Yeah.

00:11:34.800 --> 00:11:39.360
Brian, wouldn't it be good to know which ones are like more popular, which ones maybe you should depend upon?

00:11:39.360 --> 00:11:40.100
Yeah.

00:11:40.100 --> 00:11:41.020
All right.

00:11:41.020 --> 00:11:41.500
Well, Al.

00:11:41.500 --> 00:11:42.100
I took it over.

00:11:42.100 --> 00:11:42.660
Let's.

00:11:42.660 --> 00:11:44.040
That's all right.

00:11:44.360 --> 00:11:47.780
So this one is from, let me get it right here.

00:11:47.780 --> 00:11:50.620
This one is from Tankala Ashok.

00:11:50.620 --> 00:11:54.680
And they built this one, this thing called pip Trends.

00:11:55.000 --> 00:11:57.900
It's modeled a little bit after npm Trends.

00:11:57.900 --> 00:12:04.160
And it just lets you compare the popularity of packages based on their GitHub statistics.

00:12:04.160 --> 00:12:10.160
So GitHub statistics, you know, that's one metric of popularity, but let's give it a bit of a run.

00:12:10.280 --> 00:12:19.560
So what about if we type Flask says, it immediately pulls up a nice little autocomplete that says Flask, a simple web framework for building complex web applications.

00:12:19.560 --> 00:12:22.920
But then all the other ones like Flask to Postman and so on.

00:12:22.920 --> 00:12:23.920
It's kind of interesting.

00:12:23.920 --> 00:12:26.560
I didn't really, didn't really know about Flask to Postman.

00:12:26.560 --> 00:12:28.840
Maybe that we'll talk about that next time, but let's pick Flask.

00:12:28.840 --> 00:12:34.100
And then immediately, immediately says, well, what else might you consider along with this?

00:12:34.100 --> 00:12:37.060
Like, well, how about FastAPI and Django?

00:12:37.060 --> 00:12:39.120
And what do we have?

00:12:39.120 --> 00:12:41.140
It also suggested Bottle for a little while.

00:12:41.140 --> 00:12:42.680
So we'll throw Bottle in there maybe.

00:12:42.680 --> 00:12:43.700
And let's do a search.

00:12:43.700 --> 00:12:47.680
And it comes up with a graph that honestly surprised me a fair amount.

00:12:47.680 --> 00:12:52.860
There's different levels of popularity, but that's not the first thing that surprised me.

00:12:52.860 --> 00:12:58.980
The first thing that surprised me is the regular cycles that all of these packages seem to go through.

00:12:58.980 --> 00:13:00.260
Does that seem strange to you?

00:13:00.260 --> 00:13:04.440
Well, I've noticed it before and I don't really know what's going on.

00:13:04.440 --> 00:13:05.160
Is it the weekends?

00:13:05.160 --> 00:13:05.880
Yes.

00:13:05.880 --> 00:13:06.580
Very good.

00:13:06.580 --> 00:13:08.720
So four or five was the weekend.

00:13:08.720 --> 00:13:10.180
Six, four, six, five.

00:13:10.180 --> 00:13:11.380
And that's where the dip is.

00:13:11.380 --> 00:13:14.760
So people download stuff less on the weekends because there's less.

00:13:14.760 --> 00:13:15.920
Create me a new environment.

00:13:15.920 --> 00:13:16.800
Create me a new project.

00:13:16.800 --> 00:13:17.640
Check it out.

00:13:17.640 --> 00:13:18.340
Set it up.

00:13:18.340 --> 00:13:22.740
All that kind of stuff, which is healthy, but there's still a decent number of downloads going on the weekend there.

00:13:22.740 --> 00:13:29.220
Yeah, I kind of wish that I'd like to see a seven-day moving window, moving average for PyPI.

00:13:29.220 --> 00:13:34.020
Yeah, yeah, like a different window averaging or projecting function.

00:13:34.020 --> 00:13:40.700
Anyway, what we get here is we see that Flask, sorry, FastAPI and Django are super similar,

00:13:40.700 --> 00:13:44.640
like almost tied according to GitHub statistics.

00:13:44.640 --> 00:13:45.460
And these are downloads.

00:13:45.460 --> 00:13:47.380
I don't think you get downloads from GitHub.

00:13:47.380 --> 00:13:50.940
I think this is probably from PyPI or BigQuery or something.

00:13:50.940 --> 00:13:52.520
I'm not sure where those numbers are coming from.

00:13:52.520 --> 00:13:58.740
Because I don't know where those are on these like time series download numbers are on GitHub.

00:13:58.740 --> 00:14:00.800
So they're probably coming from somewhere else.

00:14:00.800 --> 00:14:07.580
But yeah, you can throw different projects in here and say, oh, this one's relatively popular compared to that or whatever.

00:14:07.580 --> 00:14:08.180
What do you think?

00:14:08.180 --> 00:14:10.660
I think it's kind of neat, especially with comparing.

00:14:10.660 --> 00:14:16.360
I mean, I've used to, there's other ways to get the stats, but having, being able to grab a few related ones,

00:14:16.360 --> 00:14:18.280
having suggestions is kind of neat too.

00:14:18.920 --> 00:14:19.360
Yeah.

00:14:19.360 --> 00:14:19.540
Yeah.

00:14:19.540 --> 00:14:20.300
So it looks.

00:14:20.300 --> 00:14:22.160
It also has some more information about the package.

00:14:22.160 --> 00:14:24.580
Like if you go to Flask, it's 12 years old.

00:14:24.580 --> 00:14:26.340
It has 45 versions.

00:14:26.340 --> 00:14:29.120
Its last release was one month ago.

00:14:29.120 --> 00:14:31.000
Its dev status is stable.

00:14:31.000 --> 00:14:32.360
It requires Python 3.7.

00:14:32.360 --> 00:14:34.680
Gives the license and who it's intended for.

00:14:34.680 --> 00:14:40.360
And you can see similarly for FastAPI, for Django and Bottle and so on.

00:14:40.580 --> 00:14:41.080
Oh, cool.

00:14:41.080 --> 00:14:47.240
Also down here in the GitHub stats, you can see like Flask, there's 59,000 stars.

00:14:47.240 --> 00:14:49.860
For Django, there's 64,000 stars.

00:14:49.860 --> 00:14:51.300
Number of open PRs.

00:14:51.300 --> 00:14:54.020
Wow, FastAPI has a lot of open PRs and issues.

00:14:54.020 --> 00:14:55.600
That's crazy.

00:14:55.600 --> 00:14:57.540
When it was last updated and so on.

00:14:57.540 --> 00:15:00.100
So yeah, and it also gives you more comparisons down here.

00:15:00.100 --> 00:15:01.440
Like, well, that was fun.

00:15:01.440 --> 00:15:05.220
What about Flask versus Django versus FastAPI, which is what we did.

00:15:05.220 --> 00:15:07.280
Or NumPy versus Pandas, for example.

00:15:07.280 --> 00:15:08.740
You can see them and so on.

00:15:09.020 --> 00:15:09.620
That's pretty neat.

00:15:09.620 --> 00:15:10.280
I like it.

00:15:10.280 --> 00:15:10.700
Yeah.

00:15:10.700 --> 00:15:11.200
Yeah.

00:15:11.200 --> 00:15:13.760
So piptrends.com, you can check it out.

00:15:13.760 --> 00:15:17.740
So I want to talk about, what do I want to talk about?

00:15:17.740 --> 00:15:19.060
Class, being classy.

00:15:19.060 --> 00:15:22.120
Actually, being callable.

00:15:22.120 --> 00:15:27.580
So Trey Hunter put this blog post out called, is it a class or a function?

00:15:27.580 --> 00:15:28.920
It's a callable.

00:15:28.920 --> 00:15:34.500
And this is actually something that I guess I realized I just sort of got used to with Python.

00:15:34.500 --> 00:15:38.320
It's a lot more, if you call something.

00:15:38.320 --> 00:15:42.960
Like, as if you would call a function, it might not be a function.

00:15:42.960 --> 00:15:44.100
It might be a class.

00:15:44.100 --> 00:15:46.480
It might be an object that's callable.

00:15:46.480 --> 00:15:47.680
It might be a class object.

00:15:47.680 --> 00:15:50.140
All sorts of stuff you could do.

00:15:50.140 --> 00:15:57.100
Like, just to be clear, we were talking about, or he talks about classes are callables.

00:15:57.100 --> 00:16:03.480
So in like JavaScript or C++, you'd have to say new something.

00:16:03.480 --> 00:16:07.000
So you'd have to say like a new date object or something.

00:16:07.000 --> 00:16:12.220
But in Python, you just call date time with some parameters and you get back a date time object.

00:16:12.220 --> 00:16:13.220
That's neat.

00:16:13.960 --> 00:16:21.700
But so it's just, I guess, this is a good article to go through just to realize that you don't really have to care.

00:16:21.700 --> 00:16:25.480
There's a whole bunch of stuff that act like functions.

00:16:25.480 --> 00:16:27.240
And it's okay if they're not functions.

00:16:27.240 --> 00:16:29.280
You just have to know if it's callable.

00:16:29.740 --> 00:16:37.220
And he talks a little bit about using a knit, a dunder a knit, to make something callable.

00:16:37.220 --> 00:16:37.820
That works.

00:16:37.820 --> 00:16:43.380
Properties are like decorators or a thing that are a callable item.

00:16:43.380 --> 00:16:50.240
There's some, it's just a good discussion about all of this.

00:16:50.680 --> 00:16:52.440
I thought this was a fascinating article.

00:16:52.440 --> 00:16:56.540
And I'm not sure I ever really thought about partials before.

00:16:56.540 --> 00:17:03.100
Like a partial function is a, is a, like a function that creates a, almost creates an object.

00:17:03.100 --> 00:17:07.700
And then you call it with some more stuff and then it creates a, the rest of it or creates an, anyway.

00:17:07.700 --> 00:17:08.760
Maybe I got that wrong.

00:17:08.760 --> 00:17:09.920
Yeah.

00:17:09.920 --> 00:17:10.620
From functools.

00:17:10.620 --> 00:17:11.920
I'd never used partial before.

00:17:11.920 --> 00:17:12.620
Okay.

00:17:12.620 --> 00:17:13.080
Yeah.

00:17:13.080 --> 00:17:20.000
And then there's a, there's a call decorator or a call dunder method that you can use that

00:17:20.000 --> 00:17:22.720
is helps out with making partials.

00:17:22.720 --> 00:17:31.280
And, and talks about iterators and decorators and all sorts of stuff like that, that actually

00:17:31.280 --> 00:17:33.820
act like callables, but they're not, they're like objects.

00:17:33.820 --> 00:17:39.660
The thing that I don't know where this is, but the thing, there's a, a statement in here

00:17:39.660 --> 00:17:40.700
that I thought was amazing.

00:17:40.700 --> 00:17:47.560
So there's a, there's a page on the PyPI documentation of the built-in functions within Python.

00:17:47.980 --> 00:17:56.000
And, and Trey points out that of the 69, there's 69 listed built-in functions within Python.

00:17:56.000 --> 00:17:59.260
Only 42 are actually implemented as functions.

00:17:59.260 --> 00:18:02.020
26 of them are, 26 are classes.

00:18:02.020 --> 00:18:06.320
And, and one is a instance of a callable class.

00:18:06.320 --> 00:18:11.240
So like, and some of them have in Python two, there were more.

00:18:11.240 --> 00:18:17.000
And some of the, some of them got converted like a map and filter and range and zip used

00:18:17.000 --> 00:18:17.660
to be functions.

00:18:17.660 --> 00:18:21.100
And now they're objects or classes or something.

00:18:21.100 --> 00:18:24.560
The len function, they use that all the time, right?

00:18:24.560 --> 00:18:25.480
It's not a function.

00:18:25.480 --> 00:18:25.860
Right.

00:18:25.860 --> 00:18:27.360
It's a callable class.

00:18:27.360 --> 00:18:28.740
Okay.

00:18:28.740 --> 00:18:34.200
And zip, the like reversed enumerate range filter use those all the time.

00:18:34.200 --> 00:18:36.380
They're not functions, but they're callable.

00:18:36.380 --> 00:18:42.460
So anyway, I just thought that was an interesting take on Python is different than other languages.

00:18:42.460 --> 00:18:44.060
It's different.

00:18:44.060 --> 00:18:44.340
Yeah.

00:18:44.340 --> 00:18:48.140
A lot of, a lot of languages you would never have that ambiguity, right?

00:18:48.140 --> 00:18:51.940
But it's the kind of ambiguity that you don't need to know or be aware of.

00:18:51.940 --> 00:18:53.260
So yeah.

00:18:53.260 --> 00:18:56.220
So maybe ignore this article, but no, no, no.

00:18:56.220 --> 00:18:57.320
I mean, it's interesting to know.

00:18:57.320 --> 00:19:01.380
I'm just saying like, it's, it's not necessarily a problem that it's not super clear whether it's

00:19:01.380 --> 00:19:04.360
a class or function because you call it and it does the thing you want it to do.

00:19:04.360 --> 00:19:05.220
So you're good to go.

00:19:05.220 --> 00:19:05.760
Yeah.

00:19:05.760 --> 00:19:09.080
Like Sam, Sam Morley pointed out here.

00:19:09.080 --> 00:19:10.980
Partial is useful.

00:19:10.980 --> 00:19:16.180
I think, I think it can be pickled unlike typical closures that can't might be wrong.

00:19:16.180 --> 00:19:21.200
But it just made me think about we, in other languages, they really do talk about closures

00:19:21.200 --> 00:19:22.880
a lot and things like that.

00:19:22.880 --> 00:19:24.340
And we just don't have to care.

00:19:24.340 --> 00:19:25.020
It just works.

00:19:25.020 --> 00:19:25.500
I don't know.

00:19:25.500 --> 00:19:26.180
It just works.

00:19:26.180 --> 00:19:27.140
Yep.

00:19:27.140 --> 00:19:28.120
Very nice.

00:19:28.120 --> 00:19:28.660
Very nice.

00:19:28.660 --> 00:19:30.200
Well, we're at the.

00:19:30.380 --> 00:19:32.060
Brian, we, yeah, we flew through those.

00:19:32.060 --> 00:19:33.380
We did fly through them.

00:19:33.380 --> 00:19:35.780
So, and we forgot to plug our stuff.

00:19:35.780 --> 00:19:37.440
So we did.

00:19:37.440 --> 00:19:41.220
Instead of a sponsor today, we've got work sponsored by us.

00:19:41.220 --> 00:19:45.380
So I want to make sure that everybody that is thinking about trying to learn something new

00:19:45.380 --> 00:19:51.740
in Python first, check out Talk Python Training because Michael has a whole bunch of awesome

00:19:51.740 --> 00:19:56.280
courses and, and you can, I'm sure you can learn something for just a few bucks.

00:19:56.280 --> 00:19:57.900
So good prices.

00:19:58.480 --> 00:20:01.240
And a new book version two edition two.

00:20:01.240 --> 00:20:01.880
Yeah.

00:20:01.880 --> 00:20:03.600
I've had a lot of good, a lot of good feedback.

00:20:03.600 --> 00:20:05.740
I love, one of the things I love is getting pictures.

00:20:05.740 --> 00:20:11.480
I don't know why, but having somebody take a picture either of themselves holding the Python

00:20:11.480 --> 00:20:13.200
testing with pytest second edition.

00:20:13.200 --> 00:20:17.460
Heck, you can do the first edition too, if that's what you got, but either holding it somewhere

00:20:17.460 --> 00:20:22.280
unique, like out in a park or at, you know, near a monument or something.

00:20:22.280 --> 00:20:23.100
That would be so cool.

00:20:23.180 --> 00:20:24.440
I love it when people send me pictures.

00:20:24.440 --> 00:20:26.160
So yeah, that's awesome.

00:20:26.160 --> 00:20:27.540
Got any extras?

00:20:27.540 --> 00:20:28.300
I have some extras.

00:20:28.300 --> 00:20:29.120
Yes.

00:20:29.120 --> 00:20:29.980
You know that I do.

00:20:29.980 --> 00:20:30.600
All right.

00:20:30.600 --> 00:20:33.260
So this first one here, let's, let's check this out.

00:20:33.260 --> 00:20:35.300
So this is interesting.

00:20:35.300 --> 00:20:39.940
This comes by way of Dan Bader and it's the Orion browser.

00:20:40.720 --> 00:20:44.360
Just when you thought there was no more room for new browsers, here's the new browser.

00:20:44.360 --> 00:20:45.600
This one is different.

00:20:45.600 --> 00:20:47.880
So you can see I'm running Vivaldi these days.

00:20:47.880 --> 00:20:48.420
I love that.

00:20:48.420 --> 00:20:51.940
Other people are using Brave, right?

00:20:51.940 --> 00:20:57.800
And so all of those browsers take the Chromium engine, strip off the Google stuff, and then

00:20:57.800 --> 00:21:05.480
put their own shell, many times more private privacy protecting and so on around them.

00:21:05.480 --> 00:21:05.980
Right.

00:21:06.300 --> 00:21:08.500
And we've got Firefox, which is awesome.

00:21:08.500 --> 00:21:09.780
It's got its own engine.

00:21:09.780 --> 00:21:10.580
It doesn't do that.

00:21:10.580 --> 00:21:15.920
But almost every other browser is let's take Chrome and Chromium and wrap it up in our own

00:21:15.920 --> 00:21:19.580
flavor of our thing with our own philosophy on how the web should be.

00:21:19.580 --> 00:21:23.280
So this Orion browser is that, but for Safari.

00:21:23.280 --> 00:21:24.740
Interesting.

00:21:24.740 --> 00:21:29.740
So if you're into Safari, you know, it has things like on your Mac, it has better battery

00:21:29.740 --> 00:21:30.760
life and so on.

00:21:30.880 --> 00:21:35.040
But think of it as like, I think Brave is probably the closest analogy.

00:21:35.040 --> 00:21:40.520
It's like Brave for Safari without the crypto, but it's, you know, got built in ad blocking.

00:21:40.520 --> 00:21:43.860
It's got built in tracker blocking and all that.

00:21:43.860 --> 00:21:51.900
One of the big drawbacks of Safari is you don't get access to the Firefox or the Chrome extensions,

00:21:51.900 --> 00:21:52.480
right?

00:21:52.480 --> 00:21:53.820
You just get the Safari ones.

00:21:54.300 --> 00:21:59.860
But this one has compatibility both for Firefox and Chrome extensions.

00:21:59.860 --> 00:22:00.660
Wow.

00:22:00.660 --> 00:22:00.960
In there.

00:22:00.960 --> 00:22:02.260
So you could, isn't that cool?

00:22:02.260 --> 00:22:09.000
So you can run this privacy protecting anti-tracker Safari with Chrome extensions.

00:22:09.000 --> 00:22:11.760
So it's just out in beta, I believe.

00:22:11.760 --> 00:22:13.340
It's not, yeah, it's out in beta right now.

00:22:13.340 --> 00:22:18.560
So I'm not sure where it is or where it's going to go, but it's a pretty interesting take,

00:22:18.560 --> 00:22:18.880
isn't it?

00:22:18.880 --> 00:22:19.280
Yeah.

00:22:19.280 --> 00:22:20.660
It's certified snappy.

00:22:20.660 --> 00:22:22.260
Certified snappy.

00:22:23.100 --> 00:22:23.800
I like it.

00:22:23.800 --> 00:22:27.740
And it's, I really like its privacy aspect.

00:22:27.740 --> 00:22:35.620
So I think the privacy space, and you brought this up, the privacy space is, there's convenience

00:22:35.620 --> 00:22:41.300
and there's speed, but I think that's a place where people can, we can open up the browser

00:22:41.300 --> 00:22:41.980
wars again.

00:22:41.980 --> 00:22:43.080
Yes.

00:22:43.080 --> 00:22:50.180
Because in a good way to try to limit some of the privacy concerns or minimize them.

00:22:50.180 --> 00:22:51.140
Yeah.

00:22:51.360 --> 00:22:57.680
Nobody at Mozilla asked me, but I'll give it, you know, Firefox is having trouble sort

00:22:57.680 --> 00:22:58.840
of keeping its market share.

00:22:58.840 --> 00:23:04.940
I think if it could triple down as the browser that you cannot be tracked with the browser

00:23:04.940 --> 00:23:09.160
that will absolutely preserve your privacy and then add services around that.

00:23:09.160 --> 00:23:10.260
I think that would be great.

00:23:10.260 --> 00:23:11.560
The big challenges.

00:23:11.760 --> 00:23:17.560
Well, I guess, you know, they're 99, 90% funded by Google, an ad company who doesn't want

00:23:17.560 --> 00:23:18.240
that.

00:23:18.240 --> 00:23:22.660
So there's this, this interesting tension, but I think, you know, that's a path that I think

00:23:22.660 --> 00:23:24.340
Firefox should be taking as well.

00:23:24.340 --> 00:23:30.200
But I guess I forgot about that, that Google was so, such a big stake in Firefox.

00:23:31.080 --> 00:23:31.280
Right.

00:23:31.280 --> 00:23:33.240
I think that limits their, their playbook.

00:23:33.240 --> 00:23:35.540
I think they can't do things like we're going to make it.

00:23:35.540 --> 00:23:36.840
So we're invisible.

00:23:36.840 --> 00:23:42.880
If you use Firefox basically, because their biggest supporter would not totally love that,

00:23:42.880 --> 00:23:43.160
would they?

00:23:43.640 --> 00:23:48.440
So anyway, this is a zero telemetry browser and whatnot.

00:23:48.440 --> 00:23:50.000
And you can go and download it.

00:23:50.000 --> 00:23:57.320
Apparently it works on Apple Silicon and Intel, but obviously being a Safari wrapper, I believe

00:23:57.320 --> 00:24:04.800
it only works on, I think, Mac and iOS things, iOS, iPad and macOS.

00:24:04.800 --> 00:24:07.380
But if you're on those, it's a pretty interesting take.

00:24:07.380 --> 00:24:10.900
And just from the browser wars in general, I think it's pretty interesting to track.

00:24:10.900 --> 00:24:12.020
Yeah, definitely.

00:24:12.020 --> 00:24:12.740
It's cool.

00:24:12.740 --> 00:24:13.300
All right.

00:24:13.460 --> 00:24:15.280
One more quick extra and then off to you.

00:24:15.280 --> 00:24:23.440
So last year we all did the PSF plus JetBrains developer survey, which is supported by and

00:24:23.440 --> 00:24:26.700
analyzed by JetBrains, but is really a PSF survey.

00:24:26.700 --> 00:24:32.020
And we had 23,000 Python developers and enthusiasts participate.

00:24:32.020 --> 00:24:33.500
Well, the results are out.

00:24:33.500 --> 00:24:35.220
So people can go check those out.

00:24:35.220 --> 00:24:41.260
Now I've got a whole lot more analysis that I'd like to do before I talk about it, but they're,

00:24:41.260 --> 00:24:42.180
they're already out.

00:24:42.280 --> 00:24:45.980
So people can start looking around there and I'll give you more details next week.

00:24:45.980 --> 00:24:46.480
Yeah.

00:24:46.480 --> 00:24:46.840
Cool.

00:24:46.840 --> 00:24:47.320
Yeah.

00:24:47.320 --> 00:24:48.600
We should definitely cover it next week.

00:24:48.600 --> 00:24:49.060
That'd be fun.

00:24:49.060 --> 00:24:50.260
Absolutely.

00:24:50.260 --> 00:24:51.020
All right.

00:24:51.020 --> 00:24:51.340
How about you?

00:24:51.340 --> 00:24:52.940
I've got a small thing.

00:24:53.100 --> 00:24:54.920
I'm not sure.

00:24:54.920 --> 00:24:55.240
sure.

00:24:55.240 --> 00:25:01.240
It really needed an entire section, but Ned Batchelder did what's in which Python.

00:25:01.240 --> 00:25:07.900
So it's a page that has basically everything from, what did he have?

00:25:07.900 --> 00:25:10.480
From 2.1 to 3.11.

00:25:10.480 --> 00:25:12.300
3.11.

00:25:12.300 --> 00:25:17.940
Not like everything that's in every version, but some of the big hitters that you might know.

00:25:17.940 --> 00:25:22.900
So like 3.10 has union types and structural pattern matching.

00:25:22.900 --> 00:25:26.200
And what do you get with 3.11?

00:25:26.340 --> 00:25:29.140
Well, we know it's faster, but do we get like how much?

00:25:29.140 --> 00:25:32.480
And it's 10 to 60% faster than 3.10.

00:25:32.480 --> 00:25:33.220
That's amazing.

00:25:33.220 --> 00:25:35.160
And then exactly.

00:25:35.160 --> 00:25:41.020
That's really amazing that after 30 years, they're like, oh, you know, this year we're going to make it 50% faster.

00:25:41.240 --> 00:25:42.580
Like that's, that's incredible.

00:25:42.580 --> 00:25:43.340
I'm glad that's happening.

00:25:43.340 --> 00:25:43.700
Yeah.

00:25:43.700 --> 00:25:46.320
And then a new module Toml lib is coming.

00:25:46.320 --> 00:25:54.200
So like, which is interesting that we've got pyproject.toml and it's, it wasn't part of the standard library yet.

00:25:54.200 --> 00:26:03.500
So, but a whole bunch of things, like if you can't remember, like if for some reason you forgot f-strings came in and what was it?

00:26:03.500 --> 00:26:04.440
3.6.

00:26:04.440 --> 00:26:05.220
Apparently I forgot.

00:26:05.220 --> 00:26:10.460
So they came in in 3.6 because it's on the list unless, unless Ned got it wrong, which probably didn't.

00:26:11.000 --> 00:26:14.900
So now I think 3.6, I think that's the biggest mover for 3.6 there.

00:26:14.900 --> 00:26:15.600
Yeah.

00:26:15.600 --> 00:26:16.220
Yep.

00:26:16.220 --> 00:26:18.680
And data classes in 3.7.

00:26:18.680 --> 00:26:19.300
Yeah.

00:26:19.300 --> 00:26:20.920
So lots of cool stuff.

00:26:20.920 --> 00:26:21.620
Fantastic.

00:26:21.620 --> 00:26:27.920
Marie Schreiner out of the audience says it's the top features from each of the versions since 3.0.

00:26:27.920 --> 00:26:31.740
So not everything, not extensive, but like sort of the big hitters.

00:26:31.740 --> 00:26:32.100
Yeah.

00:26:32.100 --> 00:26:38.920
I wasn't going to say top because, you know, there's a lot of people that worked on a whole bunch of other stuff that are on the list and I appreciate them as well.

00:26:38.920 --> 00:26:40.380
Yeah, absolutely.

00:26:40.760 --> 00:26:43.920
And some of it's just setting the groundwork for the next amazing thing.

00:26:43.920 --> 00:26:44.400
Yeah.

00:26:44.400 --> 00:26:47.380
Well, let's, let's wrap up the show with something funny.

00:26:47.380 --> 00:26:48.620
All right.

00:26:48.620 --> 00:26:49.500
Ready for a joke.

00:26:49.500 --> 00:26:49.900
All right.

00:26:49.900 --> 00:26:54.960
This is a joke by Jen Gentleman, but called to our attention by Luke Morley.

00:26:54.960 --> 00:26:58.360
And it says, Jen says, a programmer had a problem.

00:26:58.360 --> 00:27:00.580
He thought, I know, I'll solve it with async.

00:27:00.580 --> 00:27:02.320
Has problems now, period, too.

00:27:02.320 --> 00:27:02.540
He.

00:27:02.540 --> 00:27:05.880
Because of race conditions, of course.

00:27:05.880 --> 00:27:06.720
Yeah.

00:27:06.720 --> 00:27:08.060
I like it.

00:27:09.160 --> 00:27:09.920
I like it, too.

00:27:09.920 --> 00:27:11.660
Quick and simple, but yeah.

00:27:11.660 --> 00:27:14.380
There's a lot of variations on that joke and they're all good.

00:27:14.380 --> 00:27:14.940
Yeah.

00:27:14.940 --> 00:27:16.040
Most of them are good, I guess.

00:27:16.040 --> 00:27:16.580
Anyway.

00:27:16.580 --> 00:27:19.100
Well, thanks again, Michael, for joining me today.

00:27:19.100 --> 00:27:20.420
And it's a great episode.

00:27:20.420 --> 00:27:21.020
Yeah.

