WEBVTT

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

00:00:05.260 --> 00:00:12.240
This is episode 123, recorded March 27th, 2019. I'm Michael Kennedy.

00:00:12.240 --> 00:00:13.160
And I'm Brian Okken.

00:00:13.160 --> 00:00:18.080
This episode is brought to you by Datadog. They're a big sponsor of the show and longtime supporter.

00:00:18.080 --> 00:00:22.780
Tell you more about them later. Brian, do you think it's a pretty cool episode number?

00:00:22.780 --> 00:00:27.780
I mean, often people say like episode 100, 500, 1,000. These are big, but 1, 2, 3, that's pretty cool too.

00:00:27.780 --> 00:00:31.660
I was just going to comment on it. 1, 2, 3 is really cool. I like that number.

00:00:31.660 --> 00:00:36.320
So I think we should start, maybe count it down, 3, 2, 1, XKCD, go.

00:00:36.320 --> 00:00:39.000
Yeah, okay, sure.

00:00:39.000 --> 00:00:44.640
And the intent is to say like, oh my God, Python packaging and deployment and version management is a mess.

00:00:44.640 --> 00:00:50.060
Like the subtitle is, my Python environment has become so degraded, my laptop has been declared a super fun site, right?

00:00:50.060 --> 00:00:51.840
So that's kind of the theme of it.

00:00:51.840 --> 00:01:02.700
Yeah, but I mean, it is interesting that it's that title doesn't really say that the environment is terrible, but his particular laptop environment has a whole bunch of stuff on it.

00:01:02.700 --> 00:01:02.800
Yeah.

00:01:02.800 --> 00:01:13.760
And that's kind of where there's also now, Brett Cannon wrote an article called Deconstructing XKCD 1987, where he goes through all of the different pieces.

00:01:13.760 --> 00:01:21.100
So if you're looking at this, a lot of people might, especially if they're new to Python, not even know what some of these things are.

00:01:21.180 --> 00:01:27.740
So if you're not familiar with Anaconda or Homebrew or other things or why this comes in.

00:01:27.740 --> 00:01:32.920
So Brett zooms in on all the pieces and just talks about all the different environments.

00:01:32.920 --> 00:01:43.340
And he's honest to say, yes, some people's laptops kind of looks like this, because if you were trying out different things, you're like, oh, I want to try Homebrew, how to Homebrew install.

00:01:43.920 --> 00:01:52.460
And or this other stuff, you can go down this route and do all these crazy different ways to install Python and have it in your environment.

00:01:52.460 --> 00:01:54.060
But you don't have to.

00:01:54.060 --> 00:01:58.260
Any one of these would be sufficient and you can delete them when you're done.

00:01:58.260 --> 00:02:01.640
The you don't need you shouldn't have just the system Python.

00:02:01.640 --> 00:02:06.300
You should have system Python and the thing that you're using at the very least.

00:02:06.300 --> 00:02:13.760
Yeah, you know, I feel like this is a little bit like saying GUI desktop paradigm suck because like, look at my desktop.

00:02:13.760 --> 00:02:16.860
It's a cluttered, absolute mess of like stuff piled on here.

00:02:16.860 --> 00:02:21.540
And that's not necessarily the problem of your OS.

00:02:21.540 --> 00:02:26.200
It's also one of the benefits is that you can have multiple Python versions.

00:02:26.200 --> 00:02:30.880
There's like you're not going to say I've got like seven versions of Chrome on my desktop.

00:02:30.880 --> 00:02:32.800
No, you can only have one.

00:02:32.800 --> 00:02:35.140
I think you can only have one version installed.

00:02:35.480 --> 00:02:38.380
Python is something you can have multiple different versions installed.

00:02:38.380 --> 00:02:44.840
And it's that's one of the benefits, especially for developers to be able to test against multiple versions on one machine.

00:02:44.840 --> 00:02:46.700
But it does kind of get out of hand.

00:02:46.700 --> 00:02:53.020
He also, you know, so he'll just he describes what homebrew is and and what Anaconda is and all that.

00:02:53.020 --> 00:02:59.880
But the I think actually it's kind of a fun article because it's a little bit of an educational history lesson into all of this stuff.

00:02:59.880 --> 00:03:00.800
It looks super interesting.

00:03:00.800 --> 00:03:01.500
I love it.

00:03:01.500 --> 00:03:02.660
Well, well done, Brett.

00:03:02.660 --> 00:03:03.720
And I'm glad you picked it.

00:03:04.400 --> 00:03:05.640
I'm definitely going to go through it.

00:03:05.640 --> 00:03:08.260
You just I just saw it here on the list last minute.

00:03:08.260 --> 00:03:09.960
So I haven't read it yet, but it looks really good.

00:03:09.960 --> 00:03:10.200
Yeah.

00:03:10.200 --> 00:03:10.560
Nice.

00:03:10.560 --> 00:03:13.800
And so let me take you on a journey with this next one, Brian.

00:03:13.800 --> 00:03:14.020
OK.

00:03:14.100 --> 00:03:16.960
So have I talked about Google lighthouse in the show?

00:03:16.960 --> 00:03:17.660
Yeah, I think so.

00:03:17.660 --> 00:03:18.300
It sounds neat.

00:03:18.300 --> 00:03:18.500
Yeah.

00:03:18.500 --> 00:03:30.820
Like about speeding up perceived page speed and most importantly, what search engines think your page speed is because Google uses your page speed somewhat as a index on like how you rank.

00:03:31.680 --> 00:03:37.060
So going down that path, I did all sorts of work to make our sites much, much faster.

00:03:37.060 --> 00:03:40.100
Python bytes.fm, a training site, all these things.

00:03:40.100 --> 00:03:41.440
So that was great.

00:03:41.660 --> 00:03:55.180
But what I realized is when I restart, like I deploy a new version of the Python app, the very first time you hit a page that hasn't been loaded by that like worker process, it has to parse up the templates and do a little bit of work.

00:03:55.180 --> 00:04:06.080
And so maybe the first time you hit like a landing page that might not get hit that often, maybe it's, I don't know, it takes half a second, 70, 750 milliseconds or something to load.

00:04:06.080 --> 00:04:09.060
After that, it's like 20, 50 milliseconds.

00:04:09.060 --> 00:04:09.780
It's super fast.

00:04:09.780 --> 00:04:11.820
But the first time you hit it, it doesn't.

00:04:11.820 --> 00:04:19.000
So I'm like, all right, well, what if I restart and I've done all this work and then like that's when the search indexing happens and everything like still appears slow.

00:04:19.000 --> 00:04:20.180
So what can I do to make it faster?

00:04:20.180 --> 00:04:25.900
Well, why don't I just request every page and do that in parallel as many worker processes I have?

00:04:25.900 --> 00:04:27.440
So it has to hit all the worker processes.

00:04:27.440 --> 00:04:29.980
It's not, you know, perfect, but it's a decent heuristic, right?

00:04:29.980 --> 00:04:33.640
So it works like you run it one time and every request is kind of slow.

00:04:33.640 --> 00:04:35.440
The next time it's incredibly fast.

00:04:35.440 --> 00:04:42.140
So I wrote this little app and I'm like, well, I don't want to just like type Python, my little script against the thing.

00:04:42.140 --> 00:04:49.860
What you do is you point it at a site map of any site and it'll figure out what the URLs are and it'll like warm them all up basically.

00:04:50.620 --> 00:04:51.220
So I linked to this.

00:04:51.220 --> 00:04:51.620
Yeah.

00:04:51.620 --> 00:04:53.000
So I linked to this little GitHub thing.

00:04:53.000 --> 00:04:57.820
But what I wanted to do is I wanted to type, I called it like warm up or wake up or something like that.

00:04:57.820 --> 00:05:01.300
So I wanted to just go to my website and type wake up pythonbytes.fm.

00:05:01.300 --> 00:05:02.320
And that was it.

00:05:02.320 --> 00:05:06.920
And make that part of my like CI, CD deployment pipeline.

00:05:06.920 --> 00:05:07.240
Yeah.

00:05:07.240 --> 00:05:08.240
And I'm like, well, wait a minute.

00:05:08.240 --> 00:05:16.100
How do I, how do I make a, I know there are things like PServe from Python and cookie cutter and pytest and all these things that I can run.

00:05:16.100 --> 00:05:17.880
But how do I make that in Python?

00:05:17.880 --> 00:05:19.620
I just had never thought about that.

00:05:19.940 --> 00:05:21.700
And I think even you had sent me a message.

00:05:21.700 --> 00:05:31.200
And so the idea is that if you create an entry point in your setup for your package, those will become executable commands on your OS, right?

00:05:31.200 --> 00:05:31.460
Yeah.

00:05:31.460 --> 00:05:32.120
So that's pretty cool.

00:05:32.220 --> 00:05:36.520
So what I'm going to do is I'm going to link to a thing called Python package as a CLI option.

00:05:36.520 --> 00:05:38.740
And this just talks you through all the steps.

00:05:38.740 --> 00:05:42.640
I've set it up so that basically you create a package in the package.

00:05:42.640 --> 00:05:43.700
You set up the entry points.

00:05:43.700 --> 00:05:45.220
It talks about how to structure those.

00:05:45.220 --> 00:05:53.700
And then if you just pip install your package, then, you know, all of a sudden these commands are available to you globally as if they were like full on executables in the OS.

00:05:53.700 --> 00:05:53.960
Yeah.

00:05:53.960 --> 00:05:54.340
Nice.

00:05:54.340 --> 00:06:01.100
That's actually one of those, also one of those things that like, I'm glad you bring it up because it's not obvious how to do it.

00:06:01.360 --> 00:06:06.100
But the once you know how to do it, you're like, oh, yeah, that's how you do it.

00:06:06.100 --> 00:06:07.520
And then you don't think about it anymore.

00:06:07.520 --> 00:06:08.440
Exactly.

00:06:08.440 --> 00:06:09.160
It's super easy.

00:06:09.160 --> 00:06:10.520
Everyone's like, oh, this is what you do.

00:06:10.520 --> 00:06:12.920
I'm like, I've just never even thought about that.

00:06:12.920 --> 00:06:20.320
Yeah, it's not super obvious because, you know, in other environments, the way you do that is you compile it to an executable binary and you put that in your path.

00:06:20.320 --> 00:06:21.460
That's not how it works in Python.

00:06:21.460 --> 00:06:21.740
No.

00:06:21.740 --> 00:06:22.000
Yeah.

00:06:22.000 --> 00:06:25.300
You have to have like this magic entry points thing for setup tools.

00:06:25.300 --> 00:06:29.020
And then the other ones have like different versions.

00:06:29.020 --> 00:06:30.260
Yeah, exactly.

00:06:30.420 --> 00:06:34.440
So anyway, I linked to that little sitemap one thing that drove me down this path.

00:06:34.440 --> 00:06:37.880
And then also to the article that talks about this.

00:06:37.880 --> 00:06:38.880
How do you do this?

00:06:38.880 --> 00:06:42.580
And it's, you know, it's not super new, but I think it's certainly relevant to people out there.

00:06:42.580 --> 00:06:46.560
And I think I was inspired to do this because I wanted to have it as part of pipx.

00:06:46.560 --> 00:06:48.300
So you can pipx install your thing.

00:06:48.300 --> 00:06:51.320
It says, here's the executables that you got when you pipx install this thing.

00:06:51.320 --> 00:06:53.040
I'm like, I want mine to have one of those.

00:06:53.040 --> 00:06:53.400
Come on.

00:06:53.800 --> 00:06:54.020
Yeah.

00:06:54.020 --> 00:06:54.900
Well, I'm glad you were.

00:06:54.900 --> 00:06:59.920
Actually, I'm going to use your app because we've got a new visualization tool that we're using at work.

00:07:00.580 --> 00:07:03.860
And at one of the demos, we demoed it.

00:07:03.860 --> 00:07:05.860
And like, it was super slow.

00:07:05.860 --> 00:07:08.160
And it's like, oh, my God, what happened?

00:07:08.160 --> 00:07:12.860
Well, it's the intern just edited all the code right before we did the demo.

00:07:12.860 --> 00:07:13.420
Yeah, exactly.

00:07:13.680 --> 00:07:15.580
And this will fix it.

00:07:15.580 --> 00:07:17.700
If you have a site map, it'll just go request every page.

00:07:17.700 --> 00:07:19.040
You tell it how many worker processes.

00:07:19.040 --> 00:07:21.280
It'll do it all in parallel with async and await.

00:07:21.280 --> 00:07:21.940
It's beautiful.

00:07:21.940 --> 00:07:28.260
It's worth mentioning, I guess, that that little thing is not on PyPI, at least not yet, unless people can convince me to do it.

00:07:28.260 --> 00:07:30.520
Because I'm happy to build it for myself and it's on GitHub.

00:07:30.520 --> 00:07:34.320
And you can pip install it from the GitHub link, you know, with the GitHub option.

00:07:34.320 --> 00:07:39.220
But I haven't decided, I haven't committed to owning that puppy as an open source thing.

00:07:39.220 --> 00:07:43.160
So I just, I don't want to put it necessarily on the pip just yet.

00:07:43.200 --> 00:07:43.680
I'm not sure.

00:07:43.680 --> 00:07:45.160
Okay, cool.

00:07:45.160 --> 00:07:51.400
Well, next I want to talk about, we've talked about type checking and the, what do we call this stuff?

00:07:51.400 --> 00:07:52.260
The type hints.

00:07:52.260 --> 00:07:53.180
Type hints, yeah.

00:07:53.180 --> 00:07:53.860
Yeah, yeah.

00:07:53.860 --> 00:07:56.420
We've talked about mypy several times.

00:07:56.420 --> 00:08:04.120
And I actually think, I don't even feel bad for not remembering who specifically, because I think we got this suggestion from lots of people.

00:08:04.120 --> 00:08:08.640
There's another tool called Pyright, P-Y-R-I-G-H-T.

00:08:08.640 --> 00:08:12.220
And it's a Microsoft, it's from the Microsoft repo.

00:08:12.720 --> 00:08:16.160
And it's the Microsoft static type checker for Python.

00:08:16.940 --> 00:08:20.620
And it's got a little bit of an interesting twist on it.

00:08:20.620 --> 00:08:22.240
It's written in TypeScript.

00:08:22.240 --> 00:08:24.580
Is TypeScript a JavaScript thing?

00:08:24.580 --> 00:08:25.540
That's pretty meta.

00:08:25.540 --> 00:08:31.200
So TypeScript is basically like the idea of adding type hints or annotations of Python.

00:08:31.200 --> 00:08:34.160
Like TypeScript is that to JavaScript, but to like the nth degree.

00:08:34.380 --> 00:08:39.400
So like TypeScript adds concrete typing and static typing and whatnot to JavaScript.

00:08:39.400 --> 00:08:41.760
And then it's its own language.

00:08:41.760 --> 00:08:44.980
And then it compiles to native JavaScript, basically.

00:08:44.980 --> 00:08:47.760
So yeah, it's kind of meta that that's the way they did it.

00:08:47.920 --> 00:08:50.880
Okay, so it's written in TypeScript and it runs within Node.

00:08:50.880 --> 00:08:53.180
And they're very open about it.

00:08:53.180 --> 00:08:56.460
It's intended for large code bases.

00:08:56.460 --> 00:09:04.040
So they're hinting at this isn't something for just everybody to just use on your small little project or your small open source project.

00:09:04.140 --> 00:09:05.720
Probably means it's a pain to set up.

00:09:05.720 --> 00:09:07.380
Maybe, maybe.

00:09:07.380 --> 00:09:07.800
I don't know.

00:09:07.800 --> 00:09:08.340
I've never tried it.

00:09:08.340 --> 00:09:13.280
Once you have it set up, it's supposedly five times faster than mypy for a lot of people.

00:09:13.280 --> 00:09:14.740
And it has a watch feature.

00:09:14.740 --> 00:09:17.800
It can watch code bases, large code bases.

00:09:17.800 --> 00:09:22.580
So that's for people with a big code base with a lot of people getting involved in it.

00:09:22.580 --> 00:09:24.180
That might be a really great idea then.

00:09:24.180 --> 00:09:25.520
Yeah, this is like a super idea.

00:09:25.520 --> 00:09:28.940
I think type hints are a good idea if not over applied.

00:09:28.940 --> 00:09:30.800
And this definitely seems useful.

00:09:30.800 --> 00:09:34.000
One of their comments, I just wanted to, they're not slamming mypy.

00:09:34.100 --> 00:09:41.040
But they say Pyright was created to address gaps in the existing Python type checkers like mypy.

00:09:41.040 --> 00:09:41.800
Okay, that's cool.

00:09:41.800 --> 00:09:42.960
Yeah, it looks really great.

00:09:42.960 --> 00:09:44.340
It has a lot of stars on GitHub already.

00:09:44.340 --> 00:09:46.740
So happy to see them putting that out there.

00:09:46.740 --> 00:09:50.000
All right, before we get to the next one, let me tell everyone about Datadog.

00:09:50.000 --> 00:09:53.740
So this episode, as many of them are, is sponsored by Datadog.

00:09:53.740 --> 00:09:56.020
And they're a monitoring and analytics service.

00:09:56.020 --> 00:09:59.840
And they bring all of your metrics and logs and distributed traces together in one place.

00:10:00.640 --> 00:10:08.700
They're client auto instruments, things like AsyncIO for Async and Away and popular frameworks like Django and Tornado to help you visualize performance.

00:10:09.340 --> 00:10:14.120
So you can trace all your requests across service boundaries, identify bottlenecks.

00:10:14.120 --> 00:10:20.500
You've got a bunch of microservices, like how do you correlate these into one sort of call stack performance statement.

00:10:20.500 --> 00:10:22.140
It'll do that for you.

00:10:22.140 --> 00:10:23.300
So pretty awesome stuff.

00:10:23.300 --> 00:10:26.340
Check them out at pythonbytes.fm/Datadog.

00:10:26.340 --> 00:10:26.740
Nice.

00:10:26.740 --> 00:10:27.660
Thanks, Datadog.

00:10:27.740 --> 00:10:28.320
Thank you, Datadog.

00:10:28.320 --> 00:10:31.860
Now, it wouldn't be a show if we didn't talk about Anthony Shaw, would it?

00:10:31.860 --> 00:10:34.160
Oh, is this an Anthony Shaw article?

00:10:34.160 --> 00:10:36.740
And a real Python thing as well.

00:10:36.740 --> 00:10:40.360
So this next one that I want to talk about is something I'm super passionate about.

00:10:40.360 --> 00:10:42.260
And so I'm glad Anthony wrote about it.

00:10:42.260 --> 00:10:44.540
And Dan Bader had it on real Python.

00:10:44.540 --> 00:10:48.940
Is refactoring, especially for simplicity.

00:10:49.140 --> 00:10:57.520
So he wrote an article that I think people who maybe haven't thought too much about this lately should check out called Refactoring Python Applications for Simplicity.

00:10:57.520 --> 00:10:59.640
So pretty cool.

00:10:59.640 --> 00:11:05.840
A lot of it turns out to be about answering the question of, is my code complex?

00:11:05.840 --> 00:11:07.040
That's interesting.

00:11:07.040 --> 00:11:08.040
Like, I don't know.

00:11:08.040 --> 00:11:08.980
I've been working on it.

00:11:08.980 --> 00:11:09.720
It doesn't seem bad.

00:11:09.720 --> 00:11:10.620
Like, where is it bad?

00:11:10.620 --> 00:11:12.480
That part over there, I don't like to edit.

00:11:12.480 --> 00:11:14.160
I know that breaks a lot if I touch that.

00:11:14.160 --> 00:11:15.660
So we just don't mess with that too much.

00:11:15.660 --> 00:11:17.000
Things like that, right?

00:11:17.000 --> 00:11:18.820
But in general, like, how do you know?

00:11:18.820 --> 00:11:22.440
So he talks about different metrics for complexity.

00:11:22.440 --> 00:11:24.920
So if you haven't thought about that, that's pretty cool.

00:11:24.920 --> 00:11:26.880
So, like, lines of code, super obvious.

00:11:26.880 --> 00:11:28.400
Like, it's 10,000 lines of code.

00:11:28.400 --> 00:11:29.280
I don't know.

00:11:29.280 --> 00:11:30.060
That can mean something.

00:11:30.060 --> 00:11:32.460
Or it could just mean you have a lot of stuff you got to do.

00:11:32.460 --> 00:11:33.520
But then...

00:11:33.520 --> 00:11:34.700
Yeah, but 100 is easier, right?

00:11:34.700 --> 00:11:37.280
Yeah, 100 is definitely easier in general.

00:11:37.280 --> 00:11:42.260
So he talks about cyclomatic complexity, which is pretty awesome.

00:11:42.260 --> 00:11:45.740
And as a tester, I think that's a pretty interesting thing to think about as well.

00:11:45.740 --> 00:11:55.580
It's like, so if I've got, like, foreign loop, and within that foreign loop, I have an if statement, you know, maybe depending on how you've structured it, that might be like three for the cyclomatic complexity.

00:11:55.580 --> 00:11:58.660
Because you could write some code that has an empty list, so you don't iterate over it.

00:11:58.660 --> 00:12:00.880
So that's one branch of execution.

00:12:00.880 --> 00:12:04.260
Another one is maybe you are looping through stuff, but none of them hits that if statement.

00:12:04.360 --> 00:12:05.260
Maybe it does, right?

00:12:05.260 --> 00:12:12.940
So how do you basically execute each path of all the potential conditional logic and, like, going in or not into loops and stuff like that?

00:12:12.940 --> 00:12:13.560
So that's cool.

00:12:13.560 --> 00:12:19.120
Like, if you have a function that has 15 of those things, I don't know what it's doing, but it's wrong.

00:12:19.120 --> 00:12:20.320
Right?

00:12:20.320 --> 00:12:21.480
It should not be doing that.

00:12:21.480 --> 00:12:23.260
It should not be doing that much.

00:12:23.260 --> 00:12:25.600
You shouldn't have smaller functions, probably.

00:12:25.600 --> 00:12:28.660
You know, maybe that's a little bit of a harsh blanket statement.

00:12:28.780 --> 00:12:31.960
But, like, there is a number where, like, I don't know what you're doing, but it's too much.

00:12:31.960 --> 00:12:32.540
You know what I mean?

00:12:32.540 --> 00:12:33.720
Where's lines of code?

00:12:33.720 --> 00:12:35.040
You can't really say that.

00:12:35.040 --> 00:12:44.400
And there's also, like, a couple other metrics that I'm not going to talk about that go into this thing that's, like, global, like, sort of takes more of them into account called a maintainability index.

00:12:44.400 --> 00:12:52.180
And he also talks about Wiley, which I think we've covered on the show, which is a tool he created to compute those numbers for your Python application.

00:12:52.180 --> 00:12:52.560
Yeah.

00:12:52.560 --> 00:12:53.120
That's pretty cool.

00:12:53.120 --> 00:12:55.960
So all of that is to say, is my code complex and where?

00:12:55.960 --> 00:12:58.580
And then he talks about, all right, how do we refactor it?

00:12:58.660 --> 00:12:59.460
What are the tools?

00:12:59.460 --> 00:13:03.340
We can use PyCharm because it has killer refactoring stuff built in.

00:13:03.340 --> 00:13:08.080
There's some plugins for things like Vim and stuff or packages you can get.

00:13:08.080 --> 00:13:09.880
Also, VS Code stuff.

00:13:09.880 --> 00:13:16.820
And then the most, I think the most important part is, like, here are some anti-patterns, like highly nested code, for example.

00:13:16.820 --> 00:13:20.380
And here are ways to refactor your way to better code.

00:13:20.380 --> 00:13:24.540
And I think that's actually the most valuable and actionable part of this article.

00:13:24.540 --> 00:13:26.720
Like, do I do this?

00:13:26.720 --> 00:13:27.580
Yes, I do.

00:13:27.580 --> 00:13:28.300
That's bad.

00:13:28.400 --> 00:13:29.180
Oh, here's the fix.

00:13:29.180 --> 00:13:29.760
Let me do that.

00:13:29.760 --> 00:13:30.640
I think that's great.

00:13:30.640 --> 00:13:30.980
Yeah.

00:13:30.980 --> 00:13:32.400
Actually, this is incredible.

00:13:32.400 --> 00:13:40.840
I think this should be, like, turn into, like, a chapter in, or a couple lessons in all computer science programs.

00:13:40.840 --> 00:13:43.080
Because there's a lot of information in here.

00:13:43.080 --> 00:13:44.340
Yeah, it's super good.

00:13:44.340 --> 00:13:49.040
I mean, the complexity measures is really interesting, as well as the anti-patterns.

00:13:49.760 --> 00:13:51.080
And, yeah, I definitely like it.

00:13:51.080 --> 00:13:55.800
And certainly, I think it probably would resonate with you as well, because it has this testing angle, right?

00:13:55.800 --> 00:13:58.680
Like, how do you know it's safe to refactor your way out of anti-patterns?

00:13:58.680 --> 00:14:00.420
Well, if you have tests, you're good.

00:14:00.420 --> 00:14:00.940
Yeah.

00:14:01.040 --> 00:14:04.040
With some of the things like Wiley and others, you can test for this.

00:14:04.040 --> 00:14:04.460
Yeah.

00:14:04.460 --> 00:14:05.480
Yeah, super cool.

00:14:05.480 --> 00:14:05.880
Cool.

00:14:05.880 --> 00:14:06.400
All right.

00:14:06.400 --> 00:14:12.100
Well, check that one out if you want a refresher or on-route backtrade or you want to see some of the anti-patterns.

00:14:12.160 --> 00:14:18.840
Speaking of, like, things to learn and lessons, we had Colin Sullivan suggested that we cover FastAPI.

00:14:18.840 --> 00:14:19.640
So thanks, Colin.

00:14:19.640 --> 00:14:21.740
Yeah, and I hadn't heard of it, but it looks cool, doesn't it?

00:14:21.740 --> 00:14:22.100
Yeah.

00:14:22.100 --> 00:14:24.180
My first reaction is, okay, I'll check it out.

00:14:24.180 --> 00:14:32.740
But it's yet another API generator stuff so that you can create, like, REST APIs fairly quickly and easily.

00:14:32.740 --> 00:14:35.260
But it is super cool.

00:14:35.260 --> 00:14:37.040
And they're building it as fast.

00:14:37.040 --> 00:14:41.700
So it's FastAPI, high performance, easy to learn, fast to code, ready for production.

00:14:42.440 --> 00:14:45.040
And, yeah, I'm going to drop in their little sales pitch.

00:14:45.040 --> 00:14:49.340
It's fast, fast to code, fewer bugs, supposedly more intuitive.

00:14:49.340 --> 00:14:56.300
And I just, this morning, I just went through their quick tutorial on it, installed it, ran something.

00:14:56.300 --> 00:14:58.500
Because I had one question.

00:14:58.500 --> 00:15:06.780
It has both Swagger and Redock, which are ways to document your APIs, like, live.

00:15:06.780 --> 00:15:11.200
You can just go to the web page and go to the docs and see what it is.

00:15:11.560 --> 00:15:12.820
What your API looks like.

00:15:12.820 --> 00:15:15.860
And I'm like, that's just automatically there.

00:15:15.860 --> 00:15:17.200
And sure enough, yeah.

00:15:17.200 --> 00:15:19.040
Did the demo and it's right there.

00:15:19.040 --> 00:15:22.960
You can walk along with the demo and see the hunt through it.

00:15:22.960 --> 00:15:25.720
And it only took, like, a couple minutes for me to try this out.

00:15:26.020 --> 00:15:35.040
And then it's built on top of Starlet, which I hadn't heard of before, which is a project for web part, some of the web parts of it.

00:15:35.040 --> 00:15:35.220
Yeah.

00:15:35.220 --> 00:15:43.160
The most important part about Starlette is, I think, is that it adds the async and await capabilities and the parallelism as well.

00:15:43.160 --> 00:15:43.360
Yeah.

00:15:43.360 --> 00:15:49.800
And then Pydantic, which is for some of the data, controlling the data structures.

00:15:49.800 --> 00:15:57.460
And then at the bottom of just the front page that only takes a few minutes to go through, it says, oh, yeah, we also have this tutorial.

00:15:58.160 --> 00:16:06.000
And the tutorial looks like it goes through, I think, like, some of the best practice, crash course of API best practices.

00:16:06.780 --> 00:16:08.700
And so I'm totally going to go through that.

00:16:08.700 --> 00:16:13.560
I think I might learn a whole bunch about schemas and a whole bunch of stuff.

00:16:13.560 --> 00:16:13.960
Right.

00:16:13.960 --> 00:16:14.600
Just trying that.

00:16:14.600 --> 00:16:15.960
Which I use this verb.

00:16:15.960 --> 00:16:18.120
And, yeah, it looks, this looks super cool.

00:16:18.120 --> 00:16:23.200
And, you know, one of the things I like about, well, certainly one of the things I like is this async and await capability.

00:16:23.200 --> 00:16:30.060
You know, there's some talk every now and then you hear these things flare up like, oh, we're switching to Go because it's not fast enough.

00:16:30.060 --> 00:16:33.200
Or we're switching to Node.js because I don't know, right?

00:16:33.200 --> 00:16:34.840
You know, because it was hot and amazing.

00:16:35.340 --> 00:16:40.740
And they say we have super fast performance for this, like, on par with Node.js and on par with Go.

00:16:40.740 --> 00:16:44.840
And I think largely they say thanks to Starlette and Pydantic.

00:16:44.840 --> 00:16:53.240
And it's also thanks to this native asyncio and uvicorn and all the ASGI foundations, which is super, super nice.

00:16:53.240 --> 00:16:53.420
Yeah.

00:16:53.420 --> 00:16:57.780
And uvicorn, they have me using that with just the introduction demo.

00:16:57.780 --> 00:16:59.380
That's cool.

00:16:59.380 --> 00:17:04.860
And one of the things you can, they have you doing is to try out the reload flag.

00:17:04.900 --> 00:17:11.940
Which just means, like, while you're, you can just type your code and change it and it just changes on the fly.

00:17:11.940 --> 00:17:14.700
And you don't have to restart your application.

00:17:14.700 --> 00:17:15.180
Right.

00:17:15.180 --> 00:17:19.240
Normally, when you run your web app, you type uvicorn or Microwizzi or whatever.

00:17:19.240 --> 00:17:21.260
And it's going to just load your Python files.

00:17:21.260 --> 00:17:24.300
And until you restart it, it's not going to reload them.

00:17:24.440 --> 00:17:28.040
Like, the uvicorn thing you're talking about is to watch the files.

00:17:28.040 --> 00:17:31.640
And if there's any change, it'll just automatically restart your process.

00:17:31.640 --> 00:17:35.220
So you can just type save request, type save request, and it's all good.

00:17:35.220 --> 00:17:35.600
Yeah.

00:17:35.600 --> 00:17:38.200
I feel smarter already just going through the little intro.

00:17:38.200 --> 00:17:38.900
Yeah.

00:17:38.900 --> 00:17:39.300
That's great.

00:17:39.300 --> 00:17:41.700
I'm glad you pulled that out because that's super cool.

00:17:41.700 --> 00:17:43.540
The API is really nice as well.

00:17:43.540 --> 00:17:44.240
Okay.

00:17:44.740 --> 00:17:47.920
So I talked about at the beginning, like, I don't know if I want that puppy.

00:17:47.920 --> 00:17:51.760
I just, you know, there's a lot of folks out there that have probably open source projects.

00:17:51.760 --> 00:17:55.280
And they're just like, ah, there's somebody angry at me on GitHub again.

00:17:56.120 --> 00:17:58.280
I can't go back here today.

00:17:58.280 --> 00:18:05.740
So there's a project called Bleach, which is a web server foundation type thing or web framework foundation type thing.

00:18:05.740 --> 00:18:12.300
And the reason it's called Bleach is it will take, like, link text and stuff like that and make sure that it is safe for HTML.

00:18:12.300 --> 00:18:19.400
Because if you get it from an untrusted source, there's all sorts of insanity that, like, with, I don't know, Unicode, escape codes,

00:18:19.400 --> 00:18:23.200
and all sorts of bizarre stuff that you can put into links to make bad stuff happen on servers.

00:18:23.200 --> 00:18:29.920
And so the idea of this is, like, it's supposed to apply some bleach to this user input, right, and stop the problem.

00:18:29.920 --> 00:18:33.720
So this guy, Will Congreen, he had been maintaining this project.

00:18:33.720 --> 00:18:34.900
He picked it up from someone else.

00:18:34.900 --> 00:18:38.840
And he decided, you know what, I don't want to work on this anymore.

00:18:38.840 --> 00:18:40.740
I've been working on it for a while, and it doesn't bring me joy.

00:18:40.740 --> 00:18:42.420
So I'm going to step down.

00:18:42.420 --> 00:18:47.900
And I thought I'd just highlight this because I think it tells an interesting story that probably resonates with a lot of folks.

00:18:47.900 --> 00:18:53.700
He said, look, I picked up maintenance of this project because when I was familiar with it, the current maintainer wanted to step down.

00:18:53.700 --> 00:18:56.820
I guess he worked for Mozilla, and Mozilla was using it on a bunch of sites.

00:18:56.820 --> 00:19:00.540
And he felt an obligation to make sure it didn't just drop to, like, nowhere.

00:19:00.540 --> 00:19:02.120
And he knew that he could do it.

00:19:02.120 --> 00:19:08.640
He didn't really like working on it because it's just, you know, really tedious to, like, sort of fight all these weird escape codes and stuff.

00:19:09.320 --> 00:19:10.980
And he did a bunch of work.

00:19:10.980 --> 00:19:15.220
He didn't like using it, but he felt obligated to make sure it kept going.

00:19:15.220 --> 00:19:18.220
So he said, is he getting paid to work on it?

00:19:18.220 --> 00:19:18.500
No.

00:19:18.500 --> 00:19:19.600
Does he like working on it?

00:19:19.600 --> 00:19:19.900
No.

00:19:19.900 --> 00:19:21.180
Seems like he shouldn't be doing it.

00:19:21.180 --> 00:19:23.020
So it's just basically he's stepping down.

00:19:23.020 --> 00:19:28.520
But I thought it was just, like, kind of an interesting journal entry of, like, that side of open source.

00:19:28.520 --> 00:19:29.200
Yeah.

00:19:29.200 --> 00:19:30.700
So, you know, people are out there.

00:19:30.700 --> 00:19:32.180
They can read this, and maybe it'll resonate.

00:19:32.180 --> 00:19:34.060
Maybe it'll help them stay on the project.

00:19:34.060 --> 00:19:35.400
No, no, actually, I don't feel like this.

00:19:35.400 --> 00:19:37.960
You know, actually, I am getting joy from this or whatever.

00:19:38.060 --> 00:19:38.880
Or maybe they are.

00:19:38.880 --> 00:19:40.880
Is there somebody else taking it over?

00:19:40.880 --> 00:19:46.860
There's somebody else who's working on it, I think, who may be taking it over.

00:19:46.860 --> 00:19:52.180
Last line of the article said something to the effect of what happens to bleach.

00:19:52.180 --> 00:19:54.840
I'm stepping down without working on what comes next.

00:19:54.840 --> 00:19:56.580
I think Greg is going to figure that out.

00:19:56.580 --> 00:19:59.440
I'm afraid I don't know who Greg is, but he's one of the people working on it.

00:19:59.440 --> 00:20:03.380
So it's kind of like someone else is going to have good luck, Greg.

00:20:03.380 --> 00:20:04.960
Yeah, yeah.

00:20:04.960 --> 00:20:05.280
Good luck.

00:20:05.340 --> 00:20:09.260
So anyway, not a super positive story, but also I just thought it would be, like, kind

00:20:09.260 --> 00:20:15.320
of interesting to share because it's an interesting look into, like, the sort of life cycle of maintainers

00:20:15.320 --> 00:20:16.320
of open source projects.

00:20:16.320 --> 00:20:16.700
Yeah.

00:20:16.700 --> 00:20:17.320
Interesting.

00:20:17.320 --> 00:20:17.620
Nice.

00:20:17.620 --> 00:20:18.200
Yeah.

00:20:18.500 --> 00:20:20.660
Brian, you got any extras for us this week?

00:20:20.660 --> 00:20:21.800
Things you wanted to start real quick?

00:20:21.800 --> 00:20:28.120
So something that came up that I thought was funny, Tim Hopper sent this out, and it's called

00:20:28.120 --> 00:20:28.820
SleepSort.

00:20:29.420 --> 00:20:34.920
And he found another implementation of SleepSort, and then he implemented it as his and Python.

00:20:34.920 --> 00:20:37.060
But I think it's just hilarious.

00:20:37.060 --> 00:20:45.400
So the idea is, can you make a sort algorithm by just sleeping for the period of time what the number is,

00:20:45.400 --> 00:20:47.680
and then printing out the number when you're done?

00:20:47.680 --> 00:20:49.200
So if you're on it, just sort numbers.

00:20:49.200 --> 00:20:50.180
Oh, that's awesome.

00:20:50.520 --> 00:20:57.400
So if I have, like, 1, 7, and 3, and I want to print 1, 3, 7, I just go to all of them and sleep as long as they are and then print them out?

00:20:57.400 --> 00:20:57.580
Yeah.

00:20:57.580 --> 00:21:06.260
With Async, you can just, like, line them all up and sleep for the amount of time that it says, and then they'll all be sorted because that's time sorting.

00:21:06.260 --> 00:21:07.320
Time sorts for you.

00:21:07.320 --> 00:21:07.860
How interesting.

00:21:07.860 --> 00:21:09.020
Yeah, I guess it does.

00:21:10.100 --> 00:21:13.500
I don't think it's useful, but it's interesting.

00:21:13.500 --> 00:21:14.100
Anyway.

00:21:14.100 --> 00:21:15.440
It's an interesting thought experiment.

00:21:15.440 --> 00:21:20.840
And, you know, if you're in college and you're in one of these algorithm courses and they want to talk about QuickSort, BubbleSort, like,

00:21:20.840 --> 00:21:25.180
here's a little interesting one that people might not see coming.

00:21:25.180 --> 00:21:26.540
Yeah.

00:21:26.540 --> 00:21:28.220
I have a couple I want to throw out there really quick.

00:21:28.220 --> 00:21:32.440
First of all, Python 3.7.3 is out now.

00:21:32.440 --> 00:21:34.260
So that's pretty cool.

00:21:34.260 --> 00:21:37.500
There's a decent number of changes to it, I would say.

00:21:38.200 --> 00:21:40.300
There's some decent number of changes.

00:21:40.300 --> 00:21:49.160
It's really hard sometimes to find on the, like, change logs for Python to see what the point release changes are versus just the major one.

00:21:49.160 --> 00:21:54.960
So, like, you go to where they say what the changes are for Py3.7 and it says, well, these are the new pips in 3.7.

00:21:54.960 --> 00:21:57.600
Okay, well, what about this particular one?

00:21:57.600 --> 00:21:57.920
You know what I mean?

00:21:57.920 --> 00:22:04.060
Anyway, so probably people can point me in a better place in the release logs, but that seems like it should include those.

00:22:04.240 --> 00:22:13.940
Anyway, so if you want to stay in the latest visual release of Python 3.7, you can go install Python 3.7.3 or however you do that, right?

00:22:13.940 --> 00:22:16.240
Don't end up like the XKCD at the beginning.

00:22:16.240 --> 00:22:17.580
Pick one and go with it.

00:22:17.580 --> 00:22:19.240
Yeah.

00:22:19.340 --> 00:22:34.760
Another one, this one I didn't really think is worth covering the whole episode, but Alexander Lurie, who is a medical doctor who's learning Python, a guy I know from the podcast and also from courses and stuff, really, really great guy, sent us this thing called Stack RoboFlow.

00:22:35.080 --> 00:22:36.880
So, we all know Stack Overflow.

00:22:36.880 --> 00:22:40.000
So, Brian, click on Stack RoboFlow and see what you get.

00:22:40.000 --> 00:22:41.360
It looks like Stack Overflow.

00:22:41.360 --> 00:22:44.240
So, here, let me just read, like, real quick, summarize what I get.

00:22:44.240 --> 00:22:47.160
So, it looks like Stack Overflow, sort of, but there's obvious disclaimers.

00:22:47.160 --> 00:22:50.100
And it says, subversion branches related to local directory.

00:22:50.380 --> 00:22:54.460
Sometimes, I need to rename a local file on my SVN repository.

00:22:54.460 --> 00:22:58.020
And in remote desktop, I do this, svn-l.

00:22:58.020 --> 00:22:59.460
It goes in and talks about it.

00:22:59.460 --> 00:23:01.760
This is written by an AI.

00:23:01.760 --> 00:23:02.500
Oh, interesting.

00:23:02.500 --> 00:23:05.640
So, it's like an AI that's, like, been trained on Stack Overflow.

00:23:05.640 --> 00:23:10.680
And it knows how to ask questions and answer questions as if it were a Stack Overflow-like movie.

00:23:10.680 --> 00:23:11.320
Oh, funny.

00:23:11.320 --> 00:23:12.160
Yeah, and they have the code.

00:23:12.160 --> 00:23:15.620
So, if you're into machine learning and stuff, you want to check that out.

00:23:15.700 --> 00:23:16.560
It's pretty amusing.

00:23:16.560 --> 00:23:22.860
Or if you just want to laugh to see, like, you know, how close can an AI get to just, like, random Stack Overflow.

00:23:22.860 --> 00:23:26.040
But I really also like the logo.

00:23:26.040 --> 00:23:26.460
Yeah.

00:23:26.460 --> 00:23:26.860
It's funny.

00:23:26.860 --> 00:23:27.400
Yeah, it's cute.

00:23:27.400 --> 00:23:28.520
All right, last one, really quick.

00:23:28.520 --> 00:23:30.380
I thought this one just might be useful.

00:23:30.380 --> 00:23:32.220
I can't remember where I ran across this.

00:23:32.220 --> 00:23:34.980
I don't think it's written in Python, but it doesn't actually matter.

00:23:34.980 --> 00:23:37.280
It could be useful for teams writing Python.

00:23:37.280 --> 00:23:38.360
Called Passbolt.

00:23:38.360 --> 00:23:39.480
Have you heard of Passbolt?

00:23:39.480 --> 00:23:39.840
No.

00:23:39.840 --> 00:23:46.420
So, Passbolt is a password manager, like, one password or LastPass, something like that.

00:23:46.420 --> 00:23:49.740
But it's for teams, like, for software teams and stuff.

00:23:49.740 --> 00:23:51.360
And it's free, open source.

00:23:51.360 --> 00:23:52.540
It's self-hosted.

00:23:52.540 --> 00:23:54.900
It's based on OpenPGB and stuff like that.

00:23:54.900 --> 00:23:59.140
So, it's, like, your own private, personal hosted stuff for things like server passwords.

00:23:59.140 --> 00:24:02.780
And, you know, how do I get into this GitHub?

00:24:02.780 --> 00:24:05.620
And, like, whose password goes to the mail server?

00:24:05.620 --> 00:24:07.900
And, like, all that kind of stuff meant for teams.

00:24:08.060 --> 00:24:11.060
So, it looks pretty cool for software teams to, like, keep track of that stuff.

00:24:11.060 --> 00:24:12.720
That's actually pretty cool.

00:24:12.720 --> 00:24:13.820
Yeah, it's pretty awesome.

00:24:13.820 --> 00:24:19.740
So, maybe some folks out there can not put that on Sticky Notes or Excel or wherever it's right now.

00:24:19.740 --> 00:24:21.260
Yeah, or in a wiki or something.

00:24:21.260 --> 00:24:22.480
Yeah, or a wiki, exactly.

00:24:22.480 --> 00:24:25.860
Okay, so that wraps it up for our serious topics.

00:24:25.860 --> 00:24:27.560
How about something not serious?

00:24:27.560 --> 00:24:29.000
You got a joke for us?

00:24:29.000 --> 00:24:30.340
You got a pie joke for us?

00:24:30.340 --> 00:24:32.120
Yeah, pie joke.

00:24:32.120 --> 00:24:33.000
Thanks, pie joke.

00:24:33.000 --> 00:24:35.980
How many programmers does it take to kill a cockroach?

00:24:35.980 --> 00:24:36.860
I don't know.

00:24:36.860 --> 00:24:37.100
Two.

00:24:37.220 --> 00:24:39.880
One to hold it and the other to install Windows on it.

00:24:39.880 --> 00:24:43.220
It's pretty bad.

00:24:43.220 --> 00:24:44.560
All right, I got one for you as well.

00:24:44.560 --> 00:24:45.520
Thanks, pie joke.

00:24:45.520 --> 00:24:47.460
Eight bytes walk into a bar.

00:24:47.460 --> 00:24:49.260
The bartender asks, can I get you anything?

00:24:49.260 --> 00:24:50.780
He said, yeah, replies to the bytes.

00:24:50.780 --> 00:24:51.460
Make us a double.

00:24:51.460 --> 00:24:56.840
This is not really a joke, but it's just, like, serious advice from pie joke.

00:24:56.840 --> 00:24:58.940
Friends don't let friends use Python 2.7.

00:24:58.940 --> 00:25:00.560
So, maybe we'll just leave it at that.

00:25:00.560 --> 00:25:02.360
Yeah, definitely.

00:25:02.660 --> 00:25:02.920
All right.

00:25:02.920 --> 00:25:06.340
Well, Brian, thanks for being here and finding all these things and sharing them with everyone.

00:25:06.340 --> 00:25:06.800
Thank you.

00:25:06.800 --> 00:25:07.080
You bet.

00:25:07.080 --> 00:25:07.360
Bye.

00:25:07.360 --> 00:25:09.160
Thank you for listening to Python Bytes.

00:25:09.160 --> 00:25:11.700
Follow the show on Twitter via at Python Bytes.

00:25:11.700 --> 00:25:14.540
That's Python Bytes as in B-Y-T-E-S.

00:25:14.540 --> 00:25:17.780
And get the full show notes at pythonbytes.fm.

00:25:17.780 --> 00:25:22.000
If you have a news item you want featured, just visit pythonbytes.fm and send it our way.

00:25:22.000 --> 00:25:24.720
We're always on the lookout for sharing something cool.

00:25:25.080 --> 00:25:27.820
On behalf of myself and Brian Okken, this is Michael Kennedy.

00:25:27.820 --> 00:25:31.240
Thank you for listening and sharing this podcast with your friends and colleagues.