WEBVTT

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

00:00:05.060 --> 00:00:09.280
This is episode 237, recorded June 9, 2021.

00:00:09.280 --> 00:00:10.740
I'm Brian Okken.

00:00:10.740 --> 00:00:11.720
I'm Michael Kennedy.

00:00:11.720 --> 00:00:12.880
And I'm Mike Groves.

00:00:12.880 --> 00:00:15.840
Hey Mike, thanks for showing up today. Tell us a little bit about yourself.

00:00:15.840 --> 00:00:18.280
Yeah, well thank you guys for having me. This is actually really fun.

00:00:18.280 --> 00:00:23.500
My name is Mike Groves. I am leading the engineering at a company called Assembly AI.

00:00:23.500 --> 00:00:28.020
We are mainly a Python shop, but we do a lot.

00:00:28.240 --> 00:00:33.500
We do speech-to-text for developers. We're an API company.

00:00:33.500 --> 00:00:44.180
So you can really think of us as we are trying to make speech-to-text and all of the ways that you can take that text and do things with it really easy for developers

00:00:44.180 --> 00:00:49.220
so that they can integrate this value into their products and make their customers happier.

00:00:49.220 --> 00:00:50.200
Yeah, that's really cool.

00:00:50.200 --> 00:00:56.480
I had somebody who, you know, I had spoken to you guys at Assembly AI for some Talk Python stuff,

00:00:56.480 --> 00:00:59.060
but someone else that I'm working with reached out to me and said,

00:00:59.060 --> 00:01:04.500
hey, I'm doing this stuff with this Assembly AI API and I don't know how to save the file that well.

00:01:04.500 --> 00:01:07.220
Can you help me? I'm like, oh, this looks really simple. This is really nice.

00:01:07.220 --> 00:01:08.200
So yeah, you guys are doing good work.

00:01:08.200 --> 00:01:09.580
Yeah, we try to make it really simple.

00:01:09.580 --> 00:01:10.080
Yeah.

00:01:10.080 --> 00:01:11.160
Yeah, fantastic.

00:01:11.160 --> 00:01:13.080
Brian, shall we kick it off?

00:01:13.080 --> 00:01:14.400
I think we should.

00:01:14.740 --> 00:01:15.240
With a TUI.

00:01:15.240 --> 00:01:16.140
Oh, yeah.

00:01:16.140 --> 00:01:16.660
We've heard of a GUI.

00:01:16.660 --> 00:01:18.740
A GUI, a graphical user interface.

00:01:18.740 --> 00:01:25.100
And this new trend of taking stuff that happens in the terminal and making it nicer.

00:01:25.100 --> 00:01:27.880
We've covered things like Rich and stuff before, right?

00:01:27.880 --> 00:01:28.760
Yeah, a lot.

00:01:28.760 --> 00:01:29.340
I love Rich.

00:01:29.340 --> 00:01:30.240
Yeah, I do too.

00:01:30.240 --> 00:01:31.800
And I'm a super, super big fan.

00:01:32.040 --> 00:01:36.240
So I want to cover something that's like a derivative of Rich from Will McGann.

00:01:36.240 --> 00:01:40.400
See, here we are messing up names already.

00:01:40.400 --> 00:01:40.880
Sorry, Will.

00:01:41.280 --> 00:01:48.460
And the idea is if I wanted to create like Emacs or a richer UI with something like Rich,

00:01:48.460 --> 00:01:53.360
I can sort of control stuff on the screen and how it prints, but it's not full on curses,

00:01:53.360 --> 00:01:53.660
right?

00:01:53.660 --> 00:01:57.580
It's not, I want to write in this section over here and I want to dock this other bit to the

00:01:57.580 --> 00:02:00.480
right and have Rich automatically put stuff into it and so on.

00:02:00.480 --> 00:02:03.520
So I introduce you to Textual.

00:02:03.520 --> 00:02:10.620
It was called rich.tui, T-U-I, as in text, terminal user interface, but it's now called Textual.

00:02:10.940 --> 00:02:12.860
And the idea is we can have these cool things.

00:02:12.860 --> 00:02:18.040
Like I would like a thing to be a header of my terminal app and the footer of my terminal app.

00:02:18.040 --> 00:02:23.460
And I want to dock a 30 column wide section to the left and then just fill out the rest

00:02:23.460 --> 00:02:25.820
in a little area that just takes the rest of the space.

00:02:25.820 --> 00:02:26.700
How cool is that?

00:02:26.700 --> 00:02:27.980
Yeah, this is great.

00:02:27.980 --> 00:02:28.460
Yeah.

00:02:28.460 --> 00:02:32.520
And then each one of these areas is written to and controlled by Rich.

00:02:32.520 --> 00:02:37.000
So all the nice stuff that we've already talked about with Rich and the really nice

00:02:37.000 --> 00:02:38.320
things you get from there.

00:02:38.480 --> 00:02:45.580
So, you know, if people remember like Rich lets you have spectrums and like centered text

00:02:45.580 --> 00:02:49.720
or right aligned text and tables and just all sorts of good stuff.

00:02:49.720 --> 00:02:51.360
So think of doing that.

00:02:51.360 --> 00:02:55.040
But on top of this, like it's almost like a layout for terminals.

00:02:55.040 --> 00:02:58.540
Yeah, he's kind of rethinking how to do terminal stuff.

00:02:58.540 --> 00:03:03.640
So this, I know you can do all of this stuff with Curses libraries and things like that,

00:03:03.640 --> 00:03:07.000
but Curses isn't always easy on all platforms.

00:03:07.000 --> 00:03:10.200
So he's rethinking all of it.

00:03:10.200 --> 00:03:12.340
And I think it's really kind of fun.

00:03:12.340 --> 00:03:12.740
Yeah.

00:03:12.740 --> 00:03:15.100
I do want to point out something here really quick.

00:03:16.100 --> 00:03:20.240
There's a comment in the readmeant says, this project is currently a work in progress and

00:03:20.240 --> 00:03:22.040
may not be usable for a while.

00:03:22.040 --> 00:03:27.920
So, you know, just kind of maybe watch the repo and get notifications and stuff and see,

00:03:27.920 --> 00:03:29.360
you know, keep your eye out for it.

00:03:29.360 --> 00:03:34.340
On the other hand, this kind of thing with these early stages, a lot of people contact us and

00:03:34.340 --> 00:03:35.900
say, I really want to get into open source.

00:03:35.900 --> 00:03:38.380
I want to contribute to some project.

00:03:38.380 --> 00:03:39.580
What should I work on?

00:03:39.580 --> 00:03:40.360
Should I work on Django?

00:03:40.360 --> 00:03:42.540
It's like, well, that's going to be a little bit complicated.

00:03:42.540 --> 00:03:46.420
It's highly polished and there's a ton of dependencies like projects like this that

00:03:46.420 --> 00:03:50.680
are in the early stages are really good for jumping in and getting involved if it sparks

00:03:50.680 --> 00:03:51.200
your interest.

00:03:51.200 --> 00:03:52.260
So, yeah.

00:03:52.260 --> 00:03:57.320
And there's a lot of room for people to do things like out of the testing, do documentation,

00:03:57.320 --> 00:04:01.980
test on different platforms and really help it so that Will can concentrate on doing more

00:04:01.980 --> 00:04:02.340
features.

00:04:02.340 --> 00:04:03.220
Yeah.

00:04:03.220 --> 00:04:03.960
Yeah, exactly.

00:04:03.960 --> 00:04:06.040
Even documentation, like a little tutorial or whatever.

00:04:06.040 --> 00:04:11.500
And Kim out in the live stream, Kim says, I would argue Curses isn't easy anywhere.

00:04:11.500 --> 00:04:12.020
I agree.

00:04:12.180 --> 00:04:15.420
It always feels like, oh boy, we're going down this path.

00:04:15.420 --> 00:04:16.340
Mike, what do you think?

00:04:16.340 --> 00:04:19.700
Well, it looks like a really cool library.

00:04:19.700 --> 00:04:24.260
And I think for me, I try to think of what would I use it for and certainly a lot of internal

00:04:24.260 --> 00:04:31.860
tooling that we could use this for so that we can make better ways of monitoring our machine

00:04:31.860 --> 00:04:33.460
learning systems and how that all works.

00:04:33.460 --> 00:04:36.280
And so, yeah, I think that would be something I would like to look at.

00:04:37.340 --> 00:04:45.840
And also just a lot of times, too, is just trying something out, even if you have a good day or two to just try it out and hit the bug so you can really communicate that with the community.

00:04:45.840 --> 00:04:48.980
And what is broken and what could be fixed?

00:04:49.420 --> 00:04:50.080
Yeah, absolutely.

00:04:50.080 --> 00:04:51.620
I'm excited to see where this goes.

00:04:52.980 --> 00:04:53.340
Yeah.

00:04:53.340 --> 00:04:56.140
So next up, we want to talk about pip-tools.

00:04:57.420 --> 00:05:03.340
actually, one of the listeners, John Hagen, contacted us a while ago and said, hey, have you covered this?

00:05:03.340 --> 00:05:05.640
And we thought we had, but I don't think we have.

00:05:05.640 --> 00:05:07.860
So I'm going to cover it now.

00:05:07.860 --> 00:05:09.300
pip-tools.

00:05:09.620 --> 00:05:18.280
So we've talked about other things around Pip, like poetry and there's other ways to, you know, some virtual environment controllers and stuff.

00:05:18.280 --> 00:05:19.360
This isn't that.

00:05:19.360 --> 00:05:21.000
This isn't an all-in-one thing.

00:05:21.000 --> 00:05:29.180
But one of the things that, like, for instance, poetry gives you is, and a couple other packaging things, is lock files and stuff.

00:05:30.240 --> 00:05:34.600
And kind of a lock file really isn't, I mean, it isn't really what it does.

00:05:34.600 --> 00:05:37.440
I don't know if it's a lock file or a pinned requirements.

00:05:37.440 --> 00:05:42.060
But the idea around, pip-tools does a whole bunch of stuff.

00:05:42.060 --> 00:05:44.660
But right now, I'm just going to concentrate on the compile part.

00:05:44.660 --> 00:05:49.260
So the problem it solves is, so let's say I've got, like, I'm going to give an example.

00:05:49.260 --> 00:05:51.680
I've got, like, a requirement.

00:05:51.680 --> 00:05:56.700
My dependency is rich and typer is, like, two libraries I'm depending on.

00:05:56.940 --> 00:06:03.500
I could just have a simple requirements.in file that has this, just those two labels in it.

00:06:03.500 --> 00:06:10.100
And then with pip-tools, I can take that and take that requirements.in file and compile it.

00:06:10.100 --> 00:06:11.040
I run pip compile.

00:06:11.040 --> 00:06:15.260
And then I get, like, a pinned list.

00:06:15.260 --> 00:06:18.660
And it actually just goes ahead and writes the requirements.txt file.

00:06:18.660 --> 00:06:26.640
So just from an easy, I require these things, and it'll pop out the actual pinned dependencies.

00:06:27.200 --> 00:06:33.060
And now I can deploy this, and all the other developers and stuff can use it and be okay with it.

00:06:33.060 --> 00:06:39.320
Of course, before you do the deployment, please test this.

00:06:39.320 --> 00:06:46.440
So that's the idea, as you update your requirements and then test it before you deploy it.

00:06:46.440 --> 00:06:53.240
But this little extra step of taking, like, I've got a loose list of requirements, and I want to create a pinned list.

00:06:53.240 --> 00:07:00.660
You can also, there's pip-tools also has a way to just say, let me get the syntax right, upgrade.

00:07:00.660 --> 00:07:03.880
So you say --upgrade, and it updates your requirements.

00:07:03.880 --> 00:07:07.660
One of the things I love about it also is it doesn't just do one file.

00:07:07.660 --> 00:07:19.180
So if you've got a requirements.txt and a dev requirements.txt, for instance, with your testing tools, pytest and such, you can throw that in a different file, and it'll update those too.

00:07:19.180 --> 00:07:24.680
So you can have as many, actually, as many requirements files as you want, and it handles it just fine.

00:07:24.880 --> 00:07:26.500
So this is a really cool thing.

00:07:26.500 --> 00:07:38.480
Jonathan also gave us an example project, this Python blueprint that has example code in it, and it uses this workflow, and it has it in the readme.

00:07:38.480 --> 00:07:41.740
So if you want to check out a project that uses this, go ahead and do that.

00:07:41.740 --> 00:07:47.420
I don't really, actually, to be honest, I don't use pip-tools for anything other than this.

00:07:47.420 --> 00:07:49.380
This is what I use pip-tools for, is just this.

00:07:49.380 --> 00:07:52.260
I know it does other things too, but this is what I use it for.

00:07:52.260 --> 00:07:53.920
I'm psyched about this.

00:07:53.920 --> 00:07:54.720
This looks fantastic.

00:07:55.200 --> 00:08:06.980
I have requirements.txt and a dev requirements-dev.txt, and in there, I've been putting, like, at the top, here's the stuff that I really wanted to install.

00:08:06.980 --> 00:08:19.080
And below it, these are the things I want to pin, not because I actually care about them, or you would actually need to mention them, but I want things like to pin the bot to see that there's a security problem in the dependency I'm using, not the thing itself.

00:08:19.080 --> 00:08:21.420
And so it'll bump the version and fix it, right?

00:08:22.200 --> 00:08:26.020
And that means, I just noticed a couple days ago that there's these other libraries.

00:08:26.020 --> 00:08:27.900
I'm like, where did this come from?

00:08:27.900 --> 00:08:32.780
This is in my virtual environment, and I didn't, it's not in either of those scenarios, right?

00:08:32.780 --> 00:08:36.940
Well, some new dependency was added to the main dependency that I didn't pay attention to.

00:08:37.020 --> 00:08:42.720
So now I'm, like, babysitting the bottom half of my requirements.txt file, which seems like a thing I don't want to do with life.

00:08:42.720 --> 00:08:43.240
Yeah.

00:08:43.240 --> 00:08:44.300
This is beautiful.

00:08:44.300 --> 00:08:45.360
I'm all about this.

00:08:45.360 --> 00:08:49.040
I'm very much thinking that this is going to be something I'm using out there.

00:08:49.040 --> 00:08:50.040
My guys seem to agree.

00:08:50.460 --> 00:08:51.620
Yeah, I absolutely agree.

00:08:51.620 --> 00:08:53.760
And I actually have, we do not use this.

00:08:53.760 --> 00:08:57.560
I do not use this, but I will be looking into this right after this podcast.

00:08:57.560 --> 00:09:00.900
So, you know, like, why am I not doing what?

00:09:00.900 --> 00:09:02.760
This is, this will make my life a lot easier.

00:09:02.760 --> 00:09:04.360
And I'm definitely going to look into it.

00:09:04.360 --> 00:09:04.680
Yeah.

00:09:04.980 --> 00:09:10.500
Now, Juergen brings up, oh, you, the pip-tools is awesome.

00:09:10.500 --> 00:09:12.320
Yes, it is.

00:09:12.320 --> 00:09:16.120
And he also brings up that it's all about the app versus library story.

00:09:16.120 --> 00:09:18.520
So pip-tools is definitely on the app side.

00:09:18.520 --> 00:09:27.260
So you, you wouldn't want completely pinned dependencies in a library because it might conflict with the rest of the application.

00:09:27.260 --> 00:09:28.180
Right.

00:09:28.180 --> 00:09:33.980
Or pin you to say, I have to have the one that has the vulnerability in it rather than the newer one that fixes it, right?

00:09:33.980 --> 00:09:34.580
You don't want that.

00:09:34.840 --> 00:09:35.000
Yeah.

00:09:35.000 --> 00:09:35.380
Right.

00:09:35.380 --> 00:09:35.900
Yeah.

00:09:35.900 --> 00:09:36.460
Awesome.

00:09:36.460 --> 00:09:37.260
Yeah.

00:09:37.260 --> 00:09:38.380
So I think.

00:09:38.380 --> 00:09:39.760
Yeah, I think you're up.

00:09:39.760 --> 00:09:40.180
I think I'm up.

00:09:40.180 --> 00:09:40.540
All right.

00:09:40.540 --> 00:09:40.960
Now you.

00:09:40.960 --> 00:09:41.320
Okay.

00:09:41.320 --> 00:09:45.480
So here, here's a hint on the pronunciation, but you're going to have to give this a shot on your own.

00:09:45.480 --> 00:09:46.100
Yeah.

00:09:46.100 --> 00:09:49.580
So I'm going to say it's, it's penguin, but I guess you could call it penguin.

00:09:49.580 --> 00:09:50.140
I don't know.

00:09:50.140 --> 00:10:00.000
I don't know what the proper pronunciation there is, but so penguin is a library for automating the generation of, of tests.

00:10:00.000 --> 00:10:03.520
So basically what you do is it's CLI.

00:10:03.520 --> 00:10:04.380
You set this up.

00:10:04.700 --> 00:10:06.700
You point it at your code.

00:10:06.700 --> 00:10:09.260
You can sometimes give it hints.

00:10:09.260 --> 00:10:16.600
And then it goes off and it processes the, the, your, your files and produces tests.

00:10:17.160 --> 00:10:18.440
Just disclaimer here.

00:10:18.440 --> 00:10:20.740
They mentioned this several times, and this is very important.

00:10:20.740 --> 00:10:22.220
It will run your code.

00:10:22.220 --> 00:10:25.520
So, and it, it will try many different inputs.

00:10:25.520 --> 00:10:29.300
So you have to be very careful with what that code is doing.

00:10:29.300 --> 00:10:37.120
So they suggest wrapping it in a Docker container to prevent it from affecting or poisoning your, your file system.

00:10:37.120 --> 00:10:37.560
Yeah.

00:10:37.560 --> 00:10:39.800
Maybe don't give it access to the production database.

00:10:39.800 --> 00:10:40.660
Something like that.

00:10:40.900 --> 00:10:41.700
Yes, exactly.

00:10:41.700 --> 00:10:41.780
Exactly.

00:10:41.780 --> 00:10:42.220
Exactly.

00:10:42.220 --> 00:10:42.220
Exactly.

00:10:42.220 --> 00:10:51.540
So, so yes, this, this, this, I had, I didn't go deep into it, but I know that they're using some interesting search techniques.

00:10:51.540 --> 00:10:55.700
This is actually developed by a college at a university and there's a white paper behind it.

00:10:55.700 --> 00:11:12.020
I don't think it's here, but if you, if you look it up, I'm sure you could find the white paper that's associated, but it's supposed to be a very interesting technique around searching for, you know, the inputs that would be, you know, that would find good edge cases.

00:11:12.020 --> 00:11:19.160
So it does take a while to run, they say, so that you can give it some hints and they talk about that within the documentation.

00:11:19.160 --> 00:11:23.900
But I really think this is something for me, you know, I look at tools, I'm like, well, what would I use it for?

00:11:24.260 --> 00:11:32.720
And, and I think, you know, a lot of times we're busy and we don't get the coverage that we really want to get because, you know, deadlines and, you know, we want to land this customer.

00:11:32.720 --> 00:11:37.100
And, and so we have to get, we have to, you know, work really quick to get this one feature done.

00:11:37.100 --> 00:11:41.300
And we don't, we only get half coverage instead of getting, you know, a 90% or plus.

00:11:41.300 --> 00:11:53.600
So, so I think this tool could help maybe bridge that gap in those cases and maybe give you a jump, a jumpstart to, to getting the coverage that you're looking for on your projects.

00:11:53.600 --> 00:11:55.640
So that's what I'm looking at it for.

00:11:55.640 --> 00:11:58.200
And yeah, I think it's a cool project.

00:11:58.200 --> 00:12:01.340
It looks like one of those systems, a little bit like hypothesis.

00:12:01.340 --> 00:12:02.440
Are you familiar with hypothesis?

00:12:02.440 --> 00:12:04.300
Only by name.

00:12:04.300 --> 00:12:05.640
I haven't actually looked into it.

00:12:05.640 --> 00:12:12.860
Where it kind of tries to determine, oh, what are some edge cases and some, like you give it bounds of data and it'll test different scenarios for you.

00:12:12.860 --> 00:12:14.300
It looks, it looks quite interesting.

00:12:14.300 --> 00:12:15.300
Brian, are you familiar with this?

00:12:15.560 --> 00:12:19.940
I'm not, I am actually often leery of test generators.

00:12:19.940 --> 00:12:23.180
But I don't know if people find it useful.

00:12:23.180 --> 00:12:24.460
Maybe it's worth checking out.

00:12:24.460 --> 00:12:24.880
Yeah.

00:12:24.880 --> 00:12:25.100
Yeah.

00:12:25.100 --> 00:12:25.540
Yeah.

00:12:25.540 --> 00:12:26.000
It looks neat.

00:12:26.000 --> 00:12:26.780
Yeah.

00:12:26.780 --> 00:12:27.340
I'm the same.

00:12:27.340 --> 00:12:28.440
I would say I'm the same, Brian.

00:12:28.440 --> 00:12:33.360
I did, you know, I was a little bit leery, I guess about, about the idea of it.

00:12:34.320 --> 00:12:43.300
For me, as I said, I think it's just really that gap that, you know, if you have a gap in coverage and you're really just trying to get a quick, a quick jumpstart on, on your, your coverage.

00:12:43.300 --> 00:12:45.080
This might be a good tool to start with.

00:12:45.080 --> 00:12:46.280
That's, that's my thought.

00:12:46.280 --> 00:12:46.720
Yeah.

00:12:46.720 --> 00:12:47.180
Yeah.

00:12:47.180 --> 00:12:47.560
Very cool.

00:12:47.560 --> 00:12:48.180
That's good.

00:12:48.180 --> 00:12:51.720
Although, Brian, I don't know if you really want to encourage it too much.

00:12:51.720 --> 00:12:52.460
You're getting out there.

00:12:52.460 --> 00:12:55.840
If I'd known about Penguin earlier, I might not have bought Brian's testing book.

00:12:55.840 --> 00:12:57.600
You didn't need to highlight that.

00:12:57.600 --> 00:13:00.920
Indeed.

00:13:00.920 --> 00:13:01.080
Indeed.

00:13:01.080 --> 00:13:02.060
All right.

00:13:02.060 --> 00:13:02.700
You got the next one?

00:13:03.440 --> 00:13:07.300
Well, I wanted to, I think we're at the sponsor bit.

00:13:07.300 --> 00:13:08.400
I believe we are.

00:13:08.400 --> 00:13:08.980
Yeah.

00:13:08.980 --> 00:13:10.780
So let's, yeah.

00:13:10.780 --> 00:13:12.920
So I don't have our sponsor up.

00:13:12.920 --> 00:13:14.100
I got you.

00:13:14.100 --> 00:13:14.900
There we go.

00:13:14.900 --> 00:13:17.520
This episode of Python Bytes is brought to you by Sentry.

00:13:17.520 --> 00:13:20.340
How would you like to remove a little stress from your life?

00:13:20.340 --> 00:13:26.520
Well, do you worry about users that, do you worry that users may be having difficulties or encountering errors in your app?

00:13:26.520 --> 00:13:30.600
Right now, would you even know until they sent you a support email?

00:13:31.020 --> 00:13:41.540
How much better would it be to have the error and performance details immediately sent to you, including the call stack and values of local variables and the active user recorded in the report?

00:13:41.540 --> 00:13:42.500
That'd be awesome.

00:13:42.500 --> 00:13:44.880
With Sentry, it's not only possible, but simple.

00:13:44.880 --> 00:13:50.100
In fact, Michael uses Sentry on all of his web properties, including Python Bytes here.

00:13:50.480 --> 00:13:56.600
He actually fixed a bug triggered by a user and had the upgrade ready to roll out as he got the support email.

00:13:56.600 --> 00:13:59.800
That's also Sentry, but also because Michael's awesome.

00:13:59.800 --> 00:14:02.980
But anyway, surprise and delight your users today.

00:14:02.980 --> 00:14:06.400
Create your Sentry account at pythonbytes.fm/sentry.

00:14:06.400 --> 00:14:14.420
And please, when signing up, click the got a promo code and redeem and enter pythonbytes, all one word.

00:14:14.420 --> 00:14:22.740
It's good for two free months of Sentry's team plan, which will give you up to 20 times as many monthly events as well as other features.

00:14:22.940 --> 00:14:27.800
That's pythonbytes dash slash Sentry and promo code pythonbytes.

00:14:27.800 --> 00:14:28.320
Yep.

00:14:28.320 --> 00:14:28.820
Thanks, Sentry.

00:14:28.820 --> 00:14:29.520
All right.

00:14:29.520 --> 00:14:30.780
I guess I got the next one.

00:14:30.780 --> 00:14:34.140
This one is sent in by a friend of the show, Brian Skin.

00:14:34.140 --> 00:14:34.880
Thank you, Brian.

00:14:35.200 --> 00:14:45.620
And he let us know that there is something out there for all of us who love these external packages and all of these amazing Lego building blocks that are PyPI.

00:14:45.620 --> 00:14:51.480
And yet that's running other people's code with dependencies on them getting things right.

00:14:51.480 --> 00:14:54.540
And this is under the PyPA.

00:14:54.540 --> 00:15:01.660
So this is sort of pretty neat in terms of being officially the Python Packaging Authority group, right?

00:15:01.660 --> 00:15:02.720
I believe.

00:15:03.140 --> 00:15:05.960
And so it's called the advisory dash DB.

00:15:05.960 --> 00:15:11.000
It's a security advisory database for Python packages published on PyPI.org.

00:15:11.000 --> 00:15:24.340
And the idea is if somebody finds some major problem with the package or maybe even worse, maybe it's like a typo squatting scenario, but more like, you know, that part where they were supposed to check the input in that form.

00:15:24.340 --> 00:15:26.660
And then they did this direct SQL query.

00:15:26.660 --> 00:15:27.700
They didn't do that.

00:15:27.700 --> 00:15:28.380
Now they are.

00:15:28.380 --> 00:15:33.020
You really, really should change that so that they're using like parameterized queries now.

00:15:33.020 --> 00:15:38.580
And so there's vulnerabilities directory that is just a bunch of YAML files.

00:15:38.580 --> 00:15:43.700
You come over here, like let's take one here that maybe is security conscious bleach.

00:15:43.700 --> 00:15:45.600
I love the name of this package.

00:15:45.600 --> 00:15:50.200
The idea is you take user input and you sanitize it by putting bleach on it, which is fantastic.

00:15:50.200 --> 00:15:52.880
But even the sanitizer is going to have problems, right?

00:15:52.880 --> 00:15:55.420
So we checked this out back apparently in 2020.

00:15:56.300 --> 00:15:59.340
There's a problem with bleach in PyPI.

00:15:59.340 --> 00:16:08.080
It said in Mozilla bleach before 3.12, a mutation XSS cross site scripted in bleach.clean win RC data.

00:16:08.080 --> 00:16:15.420
And either the SVG or math tags are whitelisted and such and such as said like, oh my gosh, but here's all the version of effects.

00:16:15.580 --> 00:16:16.580
And here's the fixed version.

00:16:16.580 --> 00:16:22.560
And then there's some more info about like where that was spoken about, like where the problem was discovered and so on.

00:16:22.560 --> 00:16:23.400
This is really cool.

00:16:23.400 --> 00:16:32.820
So if you depend on these packages and we already spoke at the beginning about how having a tracking your dependencies, not just the things you directly install, let you let you be more aware of this.

00:16:32.820 --> 00:16:32.960
Right.

00:16:33.000 --> 00:16:37.640
You could look at that pip-tools generated requirements.txt file and see this problem.

00:16:37.640 --> 00:16:42.560
And then very likely GitHub through dependent bot would even be proposing a fix.

00:16:42.560 --> 00:16:43.280
What do you guys think?

00:16:43.280 --> 00:16:44.100
Yeah, that's great.

00:16:44.100 --> 00:16:45.600
I think this is cool.

00:16:45.600 --> 00:16:47.300
So how do you use it?

00:16:47.300 --> 00:16:49.380
Do you just look stuff up or?

00:16:49.380 --> 00:16:50.700
You let it help you.

00:16:50.700 --> 00:16:52.740
I mean, you can come over here and obviously look it up.

00:16:52.740 --> 00:16:54.780
It depends on what's going on.

00:16:54.780 --> 00:17:00.220
I think more if you're maintaining a package, you can do a PR to let people know.

00:17:00.380 --> 00:17:04.300
There's a triage service, which goes through the NIST.

00:17:04.300 --> 00:17:07.440
It pulls a lot of data from the NIST, what's that called?

00:17:07.440 --> 00:17:09.960
The National Vulnerability Database Data Feed.

00:17:09.960 --> 00:17:11.140
Say that again.

00:17:11.140 --> 00:17:15.520
So if it gets submitted there, a lot of the data gets pulled back in.

00:17:15.520 --> 00:17:19.440
They have a tool to perform some heuristics to match that back up.

00:17:19.440 --> 00:17:23.540
And then you can do, most importantly, is there's an API that you can use.

00:17:23.540 --> 00:17:30.100
So these vulnerabilities, when submitted to this GitHub repository, are then submitted outwardly to this place

00:17:30.100 --> 00:17:34.440
called the Open Source Vulnerability or the Database for Open Source Vulnerabilities.

00:17:34.440 --> 00:17:39.720
And then this has an API that people can call to learn about these problems.

00:17:39.720 --> 00:17:46.220
So if you ran, I don't know, if you were an API company and you wanted to make sure your API wasn't getting hacked by having a bad dependency,

00:17:46.220 --> 00:17:49.960
maybe you make this part of your CI, CD or something, Mike.

00:17:50.220 --> 00:17:50.680
Yeah, absolutely.

00:17:50.680 --> 00:17:55.640
I'm going to have to tell our DevOps guru, Mitch, to look into this.

00:17:55.640 --> 00:17:57.040
Exactly.

00:17:57.040 --> 00:18:06.980
So, I mean, for the most part, having stuff pinned in GitHub will trigger an immediate security notification to you when GitHub finds out about it,

00:18:06.980 --> 00:18:07.860
when it makes it out.

00:18:07.940 --> 00:18:13.360
But if you want to be a little more proactive or you're a security researcher or something like that, this looks like a good one.

00:18:13.360 --> 00:18:21.300
In the longer term, we're looking, we're working with the PyPI team to build a pipeline to automatically get these vulnerabilities into PyPI.

00:18:21.300 --> 00:18:23.700
So maybe like you could see it or something like that.

00:18:23.700 --> 00:18:26.340
I'm not exactly sure what the story is there.

00:18:26.560 --> 00:18:30.840
But it's a start for basically storing that data and sharing that data.

00:18:30.840 --> 00:18:34.300
And then hopefully like it, it makes its way over to PyPI and such.

00:18:34.300 --> 00:18:35.860
Sam Morley, welcome.

00:18:35.860 --> 00:18:37.160
Glad you made the live show, man.

00:18:37.160 --> 00:18:40.600
Said, is there a tool that can run like a pre-commit hook?

00:18:40.600 --> 00:18:48.960
I feel like maybe with just a tiny bit of wrapper, you could call that API over at the open source vulnerabilities project and get some information back.

00:18:48.960 --> 00:18:49.700
Yeah, that'd be cool.

00:18:49.700 --> 00:18:50.800
Yeah, that would be a cool thing.

00:18:50.800 --> 00:18:51.620
Like, don't check that in.

00:18:51.620 --> 00:18:52.520
It's got a problem.

00:18:52.520 --> 00:18:54.660
Don't push it.

00:18:54.660 --> 00:18:55.780
Yeah, exactly.

00:18:56.220 --> 00:18:56.540
Exactly.

00:18:56.540 --> 00:18:59.000
So anyway, I think this is a pretty cool one.

00:18:59.000 --> 00:19:01.000
Thanks, Brian Skin for sending it in.

00:19:01.000 --> 00:19:01.480
Yeah.

00:19:01.480 --> 00:19:02.860
So I don't know.

00:19:02.860 --> 00:19:06.440
Sorry, but I was going to say, yeah, you're a C++ developer, right?

00:19:06.440 --> 00:19:06.940
Yeah.

00:19:06.940 --> 00:19:10.140
And C++ is all about overriding functions by type.

00:19:10.140 --> 00:19:11.100
Like, oh, it takes an int.

00:19:11.100 --> 00:19:11.720
It takes a float.

00:19:11.720 --> 00:19:13.400
This one takes a string and it's totally different.

00:19:13.400 --> 00:19:14.400
Python doesn't have that.

00:19:14.400 --> 00:19:15.160
Yeah.

00:19:15.160 --> 00:19:17.980
What's funny is I don't actually use it that much in C++.

00:19:17.980 --> 00:19:25.880
I mean, you learn about it a lot, but I don't, I mean, I normally don't write a whole bunch of functions that have the same name, but take different

00:19:25.880 --> 00:19:26.340
parameters.

00:19:26.340 --> 00:19:28.440
But you can do, yes, you can do that.

00:19:28.440 --> 00:19:30.100
Definitely do it in C++ and C.

00:19:30.940 --> 00:19:35.800
And there's probably other languages you can do that in, but those are the two main languages that I work with.

00:19:35.800 --> 00:19:36.120
Yeah.

00:19:36.120 --> 00:19:37.320
C#, for example, does it.

00:19:37.320 --> 00:19:37.600
Okay.

00:19:37.600 --> 00:19:38.420
As well.

00:19:38.920 --> 00:19:39.920
The Python, you can do that.

00:19:39.920 --> 00:19:40.380
The Python, you cannot.

00:19:40.380 --> 00:19:48.820
So Python, if you try to do that, the second one wins and you just have another name that is attached to the function.

00:19:49.340 --> 00:20:05.740
I was, and I never really thought that I had a problem with this, but there are definitely times where it would be simpler to not try to put a switch in place or something and just have several functions that dealt with related things, but in different functions.

00:20:05.800 --> 00:20:11.320
So there's an article called The Correct Way to Overload Functions in Python.

00:20:11.840 --> 00:20:20.120
And maybe it is, but I'm not somebody that likes to use the phrase the correct way because somebody will tell me I'm wrong.

00:20:20.120 --> 00:20:21.880
But anyway, it's an interesting article.

00:20:21.880 --> 00:20:25.140
You might, for example, hear like you shouldn't overload functions in Python.

00:20:25.140 --> 00:20:27.320
You're doing it wrong if you do it at all, for example, right?

00:20:27.320 --> 00:20:28.300
Yeah, exactly.

00:20:28.300 --> 00:20:30.040
Although this is a cool solution.

00:20:30.040 --> 00:20:30.960
I totally like it.

00:20:30.960 --> 00:20:31.580
Definitely.

00:20:31.580 --> 00:20:32.520
It's a cool solution.

00:20:32.520 --> 00:20:37.500
So there's this, there's apparently a built-in way with Functools.

00:20:37.500 --> 00:20:43.820
So there's a, Functools has a decorator called Single Dispatch.

00:20:44.220 --> 00:20:50.620
And what it does is you can decorate a, basically a function signature with a single function.

00:20:50.620 --> 00:20:53.480
You say, I'm going to single dispatch this function.

00:20:53.480 --> 00:21:02.640
And then you register all, you do like the name of the function dot register as decorators around other functions.

00:21:02.640 --> 00:21:07.520
And the example shown in the articles just uses underscore.

00:21:07.520 --> 00:21:10.440
I'm guessing that's just because you don't care what the name is.

00:21:10.440 --> 00:21:12.680
I don't know, but that seems like a good way to do it.

00:21:13.260 --> 00:21:17.220
And then you've got, then after that, you just have, that works.

00:21:17.220 --> 00:21:19.600
It works like you've done function overloading.

00:21:19.600 --> 00:21:20.800
Yeah, that's awesome.

00:21:20.800 --> 00:21:28.120
So in the example it takes, you can call this format function with a string, with a date, with a date time, and a time.

00:21:28.120 --> 00:21:31.460
And you actually get, there's like three different functions that get called.

00:21:31.460 --> 00:21:35.140
One for a string, one for a date, one that just falls back or something, right?

00:21:35.140 --> 00:21:35.700
Yeah.

00:21:35.700 --> 00:21:38.400
I mean, it's a pretty simple example.

00:21:38.400 --> 00:21:40.940
And if you, and it's pretty clean code.

00:21:40.940 --> 00:21:47.320
So I would definitely try to keep all these things together in one, you know, in one module, of course.

00:21:47.320 --> 00:21:49.840
You would be mean to put them in different places.

00:21:49.840 --> 00:21:50.760
That would be so wrong.

00:21:51.220 --> 00:21:54.400
Or even like spread out in the same function would be terrible.

00:21:54.400 --> 00:21:57.860
But keeping them together, this is great.

00:21:59.360 --> 00:22:10.400
One of the things that the article mentions is that this, you can't really, it's called single dispatch because it's based on the type of the first, I think it's based on the type of the first parameter.

00:22:10.820 --> 00:22:18.560
So if you want to do multi-parameter ones, there is a third-party plugin called multiple dispatch.

00:22:18.780 --> 00:22:21.160
You can just pip install.

00:22:21.160 --> 00:22:23.540
And then it kind of works the same.

00:22:23.540 --> 00:22:25.740
Although I kind of like this one better, honestly.

00:22:25.740 --> 00:22:27.500
The syntax is a little different.

00:22:27.500 --> 00:22:31.320
And it probably does single dispatch too, I'm guessing.

00:22:31.320 --> 00:22:33.000
Yeah, just one parameter.

00:22:33.000 --> 00:22:37.600
But in this one, yeah, similar sort of thing.

00:22:37.600 --> 00:22:40.360
It just kind of works on multiple parameters.

00:22:40.900 --> 00:22:44.020
I'm digging the multiple dispatch style where you just say dispatch.

00:22:44.020 --> 00:22:45.860
This is arguments are list stir.

00:22:45.860 --> 00:22:49.920
You know, we're going to maybe get to where Mike is going at the end of the show.

00:22:49.920 --> 00:22:57.460
But it would be even cooler if you could just say at dispatch and then put a type like a colon list, b colon stir.

00:22:57.460 --> 00:23:00.780
So I want to dispatch on types and stuff like that.

00:23:00.780 --> 00:23:07.220
And have the dispatch decorator look at the function that's passed in and look at the type parameters and then just do that.

00:23:07.220 --> 00:23:09.800
So you don't have to say the types more than once.

00:23:10.200 --> 00:23:12.600
Anyway, we come back to that as well.

00:23:12.600 --> 00:23:13.000
Yeah.

00:23:13.000 --> 00:23:17.400
So in a past life, I was a Java engineer.

00:23:17.400 --> 00:23:22.740
So we call it dynamic dispatch in Java.

00:23:22.740 --> 00:23:30.040
And actually, there's a lot of patterns, object-oriented patterns that kind of are derived from that feature.

00:23:30.040 --> 00:23:32.580
From, again, from the C++.

00:23:32.580 --> 00:23:34.240
Well, from the old days.

00:23:35.580 --> 00:23:42.740
And, yeah, no, to me, this actually, you know, when I saw it, I was like, okay, I could definitely use this for a lot of cases.

00:23:42.980 --> 00:23:51.400
I know that, like, when you might want to build, when you have, like, a piece of code that has to work with a variety of different types, but they're very similar types, maybe.

00:23:51.400 --> 00:23:54.960
And you want to do something with that family of types.

00:23:55.560 --> 00:24:01.880
You know, I think that that would be something I would, you know, I would think to look at, to solve with something like this.

00:24:02.380 --> 00:24:02.740
Yeah.

00:24:02.740 --> 00:24:03.400
Yeah.

00:24:03.400 --> 00:24:05.000
I kind of had the same thought.

00:24:05.000 --> 00:24:10.340
And I do not think I would make this any sort of normal workflow use case for my code.

00:24:10.520 --> 00:24:17.740
But there are times where you have some code that says, if, you know, argument is, the type of this is a list, do this thing.

00:24:17.740 --> 00:24:21.120
If it's not a list, then make an empty list, put it in, and then do this other thing.

00:24:21.120 --> 00:24:27.600
You know, like, if you're doing that type switching already, this dispatch thing might actually make it more clear, right?

00:24:27.600 --> 00:24:28.880
It's not common to do it in Python.

00:24:28.880 --> 00:24:33.320
But there are times you're like, I kind of want to be able to take a string or a date time and then just parse the string of it.

00:24:33.320 --> 00:24:34.680
You know, those kinds of things.

00:24:35.280 --> 00:24:40.340
So as an API company, this is actually kind of interesting, fits into what we do as an API company.

00:24:40.340 --> 00:24:45.160
We have to, a lot of times, you know, we're not very, we're not overly strict on our input types.

00:24:45.160 --> 00:24:49.180
We allow like truthy and falsy kind of types to come in for like Booleans.

00:24:49.180 --> 00:24:53.200
And I could see us using this for that, right?

00:24:53.200 --> 00:25:01.940
So that way, instead of using all the helper code we've already written for that, have it more along the lines of, okay, if it's this type of input, you know, then you can convert it this way.

00:25:01.940 --> 00:25:03.660
If it's this type of input, you can convert it that way.

00:25:04.140 --> 00:25:09.080
And I think we could probably write some code to handle our inputs differently using this pattern.

00:25:09.080 --> 00:25:09.600
Yeah.

00:25:09.600 --> 00:25:10.020
Yeah.

00:25:10.020 --> 00:25:11.040
Very neat insight there.

00:25:11.040 --> 00:25:12.760
Brian, you blew up our chat with us.

00:25:12.760 --> 00:25:16.300
Well, you want to pull out some highlights?

00:25:16.300 --> 00:25:16.620
Yeah.

00:25:16.620 --> 00:25:17.080
All right.

00:25:17.080 --> 00:25:24.540
So John Sheehan says, function overloading was one of those things like switch statements that I missed when I first started Python, but then I found I rarely needed it.

00:25:24.540 --> 00:25:24.780
Yeah.

00:25:24.780 --> 00:25:26.180
I'm kind of with you on that.

00:25:26.180 --> 00:25:32.620
Like I said, there's a few cases for me that I'm like, where I'm doing a type check or is instance of that I think is the one time.

00:25:32.700 --> 00:25:34.720
But that's, you know, a couple of times in a whole program.

00:25:34.720 --> 00:25:35.340
What do you think, Brian?

00:25:35.340 --> 00:25:36.220
Yeah.

00:25:36.220 --> 00:25:38.660
I definitely missed it at first.

00:25:38.660 --> 00:25:40.680
And now I just don't even really notice it.

00:25:40.680 --> 00:25:40.940
Yeah.

00:25:42.820 --> 00:25:46.080
Then you've got, you're going to get it says Luciano Romano.

00:25:46.080 --> 00:25:48.860
Romano also explains this in Fluent Python.

00:25:48.860 --> 00:25:51.880
I just read the pre-version of the second edition.

00:25:51.880 --> 00:25:53.440
Getting some polish.

00:25:53.440 --> 00:25:53.640
Yeah.

00:25:53.640 --> 00:25:54.020
Very nice.

00:25:54.020 --> 00:25:55.040
That's a really good book.

00:25:55.040 --> 00:25:56.140
Fluent Python as well.

00:25:56.140 --> 00:25:59.420
Came out there says, that's the kind of thing I was thinking of.

00:25:59.420 --> 00:25:59.780
Yeah.

00:26:00.380 --> 00:26:01.240
Oh, sorry.

00:26:01.240 --> 00:26:02.160
That's a different comment.

00:26:02.160 --> 00:26:02.960
We'll come back to that in a minute.

00:26:02.960 --> 00:26:05.180
And then Sam Morley.

00:26:05.180 --> 00:26:08.260
I don't tend to find this kind of dispatching that useful.

00:26:08.260 --> 00:26:13.480
I generally just write a master function that takes star args, star kwrgs and dispatch to other functions.

00:26:13.480 --> 00:26:13.920
Yeah.

00:26:13.920 --> 00:26:14.400
Yep.

00:26:14.400 --> 00:26:17.920
But if you're switching on his instance, it could be, it could be a time.

00:26:17.920 --> 00:26:18.380
Yeah.

00:26:18.380 --> 00:26:20.580
And then stepping back one quick topic.

00:26:20.580 --> 00:26:26.760
Kim Vanewick says, would be handy if some pip tooling could automatically check the PyPA advisory before downloading a package.

00:26:26.760 --> 00:26:27.720
That would be slick.

00:26:27.720 --> 00:26:28.120
Yeah.

00:26:28.120 --> 00:26:32.800
I just did a typo squatting and PyPI security episode over on Talk Python.

00:26:32.800 --> 00:26:36.680
And we had a lot of interesting ideas, like almost like a, have I been pwned?

00:26:36.680 --> 00:26:38.160
Like, remember what I installed?

00:26:38.160 --> 00:26:40.120
And if you ever see, I installed something out of vulnerability.

00:26:40.120 --> 00:26:41.100
Quick, shoot me a note.

00:26:41.100 --> 00:26:41.680
Let me know.

00:26:41.680 --> 00:26:43.620
Hey, a few weeks ago, you installed this thing.

00:26:43.820 --> 00:26:45.100
You might want to get rid of it now.

00:26:45.100 --> 00:26:45.880
Stuff like that.

00:26:45.880 --> 00:26:48.160
But I think this is another interesting thing along those lines.

00:26:48.160 --> 00:26:48.640
All right.

00:26:48.640 --> 00:26:53.020
Like kind of cache that data and then just say, you know, I know you want to install it.

00:26:53.020 --> 00:26:56.540
And maybe this is what they're talking about with integrating that into pypi.org itself.

00:26:56.540 --> 00:26:57.080
Who knows?

00:26:57.080 --> 00:26:57.780
Very cool.

00:26:57.780 --> 00:26:59.660
All right, Mike, you got the last one.

00:26:59.660 --> 00:27:00.220
Yeah.

00:27:00.220 --> 00:27:05.640
So, AIO SQL is a, as it says, simple SQL in Python.

00:27:05.640 --> 00:27:13.240
it's a SQL templating framework or, or library, that really you, what you do is you give it some

00:27:13.240 --> 00:27:17.720
SQL files with some, it has some conventions around how you define queries.

00:27:17.720 --> 00:27:22.140
And then the essentially gives you a query mapping, that you can then use in your code.

00:27:22.140 --> 00:27:27.060
and this is kind of a, it's a minimalistic way of, of access to your, of accessing your database.

00:27:27.580 --> 00:27:32.660
it is, you know, with the A in front of it, it's, it's, natively asynchronous.

00:27:32.660 --> 00:27:35.700
it works really well with asyncpg.

00:27:35.700 --> 00:27:38.040
I know that, we use, Postgres.

00:27:38.040 --> 00:27:43.520
So, you know, that, that was a good, that was a highlight for us to, to look at it.

00:27:43.780 --> 00:27:47.040
and, you know, I think we all have worked with ORMs.

00:27:47.040 --> 00:27:50.260
you know, I've come back and forth on ORMs over the years.

00:27:50.260 --> 00:27:56.340
you know, I think this is a nice fit for when you have, when you, when you don't have to do,

00:27:56.340 --> 00:28:00.020
uh, a lot of touch, a lot of different tables or do a lot of joins.

00:28:00.260 --> 00:28:06.220
Maybe you're, have a small microservice that just needs to do a couple, you know, reads and writes updates.

00:28:06.220 --> 00:28:12.320
and, and also I think this really helps because ORMs, especially when you're dealing at scale,

00:28:12.320 --> 00:28:16.160
you have to really know the ORM at a very deep level to understand what it's doing.

00:28:16.160 --> 00:28:20.420
And this kind of exposes all of, you know, it really just brings you down to the SQL level.

00:28:20.420 --> 00:28:24.940
So now, you know, exactly what you're doing and you, you can be a little bit more direct on what you want to,

00:28:24.940 --> 00:28:26.460
what you want to do with your data.

00:28:26.460 --> 00:28:26.980
Yeah.

00:28:26.980 --> 00:28:27.220
Yeah.

00:28:27.220 --> 00:28:32.740
Sometimes you're like, well, I want to do the join and then the filter, not the filter, then the, I don't know.

00:28:32.740 --> 00:28:37.780
Like if you're really good at SQL, you can, you can put these little tricks and like, oh, it's actually

00:28:37.780 --> 00:28:40.100
likes it better if we do it this way rather than that way.

00:28:40.100 --> 00:28:42.120
And, oh, I'm probably not going to let you do that.

00:28:42.120 --> 00:28:46.500
So let me just describe this to people out there because it's breaking some paradigms for me.

00:28:46.500 --> 00:28:51.880
So this is a library that allows you to write queries against a database,

00:28:51.880 --> 00:28:57.660
but you do it almost with data access, data access layer style of things.

00:28:57.660 --> 00:29:01.760
So you would, you don't do a quote, select star from such and such.

00:29:01.760 --> 00:29:06.820
You, you would say like query dot get all greetings or get user by username.

00:29:06.820 --> 00:29:12.280
And you pass a like username equals such and such in an asynchronous way, which is pretty interesting.

00:29:12.400 --> 00:29:18.700
But the way that that has meaning is you create a dot SQL file that has like a doc string like thing.

00:29:18.700 --> 00:29:24.340
And you write a bunch of SQL, almost like stored procedures, but just in a text file, this thing parses it.

00:29:24.340 --> 00:29:27.700
And then it becomes like a smart query data access layer.

00:29:27.700 --> 00:29:28.300
Correct.

00:29:28.300 --> 00:29:28.740
Yeah.

00:29:28.800 --> 00:29:33.520
So it basically builds out other data access layer or data access object kind of for you,

00:29:33.520 --> 00:29:37.920
where you can basically map in these, these, these queries.

00:29:37.920 --> 00:29:39.420
And it's not just queries.

00:29:39.420 --> 00:29:42.540
You can do mutations and you can do, you can do a DDL and all of that.

00:29:42.540 --> 00:29:43.080
So, yeah.

00:29:43.080 --> 00:29:44.200
Yeah.

00:29:44.200 --> 00:29:44.880
It gives you a lot.

00:29:44.880 --> 00:29:45.880
Create tables or whatever.

00:29:45.880 --> 00:29:46.420
Yeah.

00:29:46.420 --> 00:29:47.140
It could be a function you call.

00:29:47.140 --> 00:29:47.340
Yeah.

00:29:47.340 --> 00:29:48.000
Absolutely.

00:29:48.000 --> 00:29:48.380
So.

00:29:48.380 --> 00:29:49.360
Brian, what do you think?

00:29:49.360 --> 00:29:50.780
Do you touch SQL much these days?

00:29:50.780 --> 00:29:53.160
I'm touching it more and more.

00:29:53.160 --> 00:29:55.240
And I love this actually.

00:29:56.080 --> 00:29:59.320
Cause I always assume if there's a bug, it's probably in my SQL statement.

00:29:59.320 --> 00:30:01.300
But this looks pretty cool.

00:30:01.300 --> 00:30:06.720
So get, get your, get your selects and stuff figured out what kind of queries you want to do ahead of time.

00:30:06.720 --> 00:30:09.180
And, and then use them in your code.

00:30:09.180 --> 00:30:10.060
This is cool.

00:30:10.060 --> 00:30:10.540
Yeah.

00:30:10.540 --> 00:30:10.980
Yeah.

00:30:10.980 --> 00:30:15.900
I mean, I'm very repelled by writing raw SQL statements in my code.

00:30:15.900 --> 00:30:18.240
Very much like Kim Van Wijk.

00:30:18.240 --> 00:30:23.400
Others like this looks exactly what I like, like not writing SQL, but not using an ORM.

00:30:23.480 --> 00:30:26.420
No, it's no secret to the world out there that I'm a MongoDB fan.

00:30:26.420 --> 00:30:31.300
So I, I'm not, I don't have like direct use for this a lot, but I do find this super valuable,

00:30:31.300 --> 00:30:39.880
especially if people on the team are really good at SQL and they're like, oh, this, this library is inhibiting me from like using my superpower on the database.

00:30:39.880 --> 00:30:40.600
Right, Mike?

00:30:40.600 --> 00:30:40.940
Exactly.

00:30:40.940 --> 00:30:41.960
Yeah, that's exactly.

00:30:41.960 --> 00:30:51.120
And I was just about to say that, you know, if, if you have a DBA or you have someone who is, you know, basically they are focused or concentrated on the database and, and optimizing those queries.

00:30:51.120 --> 00:30:59.320
You know, I think what, what this allows you to do, then you can go define your queries and you can write them yourself, how they are as developer.

00:30:59.320 --> 00:31:05.020
And then maybe you can take that to your, to the experts and have him refine them for you without actually changing the abstraction.

00:31:05.020 --> 00:31:05.520
Right.

00:31:05.520 --> 00:31:07.100
Like without, you still get that.

00:31:07.100 --> 00:31:07.500
Yeah.

00:31:07.500 --> 00:31:07.960
Yeah.

00:31:07.960 --> 00:31:12.580
There's also times where like, let's say I've got a internal tool that I'm going to put together and it needs a database.

00:31:12.580 --> 00:31:18.520
And it's really not that big of a deal to tell like your, your IT department and your supervisor and stuff.

00:31:18.520 --> 00:31:23.420
They're going to throw up a MySQL database and, or something and, and interact with it or Postgres.

00:31:23.420 --> 00:31:26.820
But to say, hey, I'm going to throw Mongo in there.

00:31:26.820 --> 00:31:31.000
That might bring up a, just a, just a discussion that you're just not ready to have.

00:31:31.000 --> 00:31:31.500
So.

00:31:31.500 --> 00:31:32.960
Yeah, for sure.

00:31:32.960 --> 00:31:38.920
Let me suggest a pairing, you know, kind of like as you pair wines, a pairing with this library.

00:31:38.920 --> 00:31:41.880
I think Pydantic might go fantastic with this, right?

00:31:41.880 --> 00:31:53.880
So you get these results back as tuples and then you could just, you know, star args that into your Pydantic models and you get your validation and all sorts of like stuff.

00:31:53.880 --> 00:31:58.580
And then you get a list of Pydantic, like you're one list comprehension away from something beautiful here.

00:31:58.580 --> 00:31:58.940
Yeah.

00:31:58.940 --> 00:32:00.440
This is, that's exactly what we're doing.

00:32:00.440 --> 00:32:08.860
You know, we're using, you know, I think right now we're building out a new stack and it's basically, it's, it's, it's FastAPI, Pydantic, you know, AIO SQL.

00:32:08.860 --> 00:32:09.800
Oh, interesting.

00:32:09.800 --> 00:32:11.180
And you're finding it works well.

00:32:11.180 --> 00:32:12.360
Oh, it's, yeah.

00:32:12.360 --> 00:32:13.540
And it's very performant.

00:32:13.540 --> 00:32:15.880
So it's, you know, because it's asynchronous, right?

00:32:15.880 --> 00:32:18.400
We're using asyncpg all the way down to the database too.

00:32:18.400 --> 00:32:20.740
So it's pretty much asynchronous from end to end.

00:32:20.740 --> 00:32:21.620
Fantastic.

00:32:21.620 --> 00:32:23.180
This is a really good recommendation.

00:32:23.180 --> 00:32:23.800
Yeah.

00:32:23.800 --> 00:32:24.840
You'd like it too, right, Brian?

00:32:24.840 --> 00:32:25.320
It's pretty sweet.

00:32:25.320 --> 00:32:26.100
Yeah, this is great.

00:32:26.100 --> 00:32:27.420
Yeah, I do.

00:32:27.420 --> 00:32:34.100
I really like the separation of concerns of the SQL statements and the Python code, but the flexibility of having both.

00:32:34.100 --> 00:32:34.700
It's pretty cool.

00:32:34.700 --> 00:32:35.220
Awesome.

00:32:35.220 --> 00:32:36.340
Brian, is that it for us?

00:32:36.900 --> 00:32:37.300
Yeah.

00:32:37.300 --> 00:32:40.820
Anybody have any other topics they want to bring up?

00:32:41.140 --> 00:32:42.380
Oh, you know, I do.

00:32:42.380 --> 00:32:44.020
Kind of, kind of crazy.

00:32:44.020 --> 00:32:46.820
So it's not quite an extra, extra, extra, extra here all about it.

00:32:46.860 --> 00:32:49.980
But a couple of things sent in from some listeners.

00:32:49.980 --> 00:32:52.880
So let me make sure I credit these.

00:32:52.880 --> 00:33:04.500
So Daniel Mulkey sent this one in and said there is now, has been for a little while from Science Direct, there's a journal for academics called SoftwareX.

00:33:04.500 --> 00:33:06.820
And this library is pretty cool.

00:33:06.820 --> 00:33:11.100
So it aims to acknowledge the impact of software in today's research.

00:33:11.340 --> 00:33:16.200
So if you're in academics, one of the big challenges is that whole publish or perish sort of thing.

00:33:16.200 --> 00:33:22.280
And it would be great to take this cool library and make it a thing that's out on PyPI or Conda that people can use.

00:33:22.280 --> 00:33:24.380
Oh, but that's going to take a week and a half.

00:33:24.380 --> 00:33:30.160
And you really only get credit for your citations in articles, not in code, right?

00:33:30.200 --> 00:33:35.480
So this kind of addresses that to try to give people a place to publish their projects in a meaningful way.

00:33:35.480 --> 00:33:44.920
And I just want to point out that there's a special issue on the software that contributed to the LIGO experiment, the gravitational wave discovery, which I'm pretty sure got the Nobel Prize.

00:33:44.920 --> 00:33:46.360
I don't totally remember.

00:33:46.360 --> 00:33:54.160
But if you just start poking around here, you know, you might find the word Python periodically in this thing here.

00:33:54.160 --> 00:33:57.040
So over this one, we got some Python.

00:33:57.040 --> 00:34:00.000
I'm just randomly clicking articles and they're all coming up Python.

00:34:00.000 --> 00:34:01.800
So I think that that's pretty sweet.

00:34:01.800 --> 00:34:06.640
If people are in science and they do this computational side of things, check this out.

00:34:06.640 --> 00:34:07.020
Very cool.

00:34:07.020 --> 00:34:08.380
Yeah, that's number one.

00:34:08.380 --> 00:34:11.140
Number two, HiCon has been finished for a little while.

00:34:11.140 --> 00:34:17.220
And we were able to go through some like meeting platform type thing where we could watch the replays.

00:34:17.220 --> 00:34:20.740
But it's a little bit wonky in the way that the playback worked.

00:34:20.740 --> 00:34:24.220
Like I had to do some weird stuff to actually get logged back in after a while.

00:34:24.220 --> 00:34:27.220
Anyway, it was fine for live stuff, but it was weird for playback.

00:34:27.220 --> 00:34:28.960
YouTube is pretty awesome for playback.

00:34:29.160 --> 00:34:35.980
And here's the I put in the show notes, the playlist for all of HiCon 2021 US.

00:34:35.980 --> 00:34:36.860
So that's pretty cool.

00:34:36.860 --> 00:34:38.060
I don't know how many videos are in here.

00:34:38.060 --> 00:34:39.200
It looks like 86 videos.

00:34:39.200 --> 00:34:42.240
So if you want to catch up on the HiCon talks, there's a really good way.

00:34:42.240 --> 00:34:42.800
Nice.

00:34:42.800 --> 00:34:46.980
It looks like Juergen had a lightning talk there.

00:34:46.980 --> 00:34:47.840
Yeah.

00:34:47.840 --> 00:34:48.260
It's cool.

00:34:48.260 --> 00:34:48.680
Yeah.

00:34:48.680 --> 00:34:49.000
Very cool.

00:34:49.000 --> 00:34:49.580
Well done.

00:34:49.580 --> 00:34:54.440
And also want to make sure I get the credit for this one right.

00:34:54.440 --> 00:35:00.880
Madison Swain Bowden, who we both met, I believe, at PyCascades, shared this with us.

00:35:00.880 --> 00:35:12.260
That AICS, ImageIO, which is used all over biological imaging and microscopy and that kind of stuff from the Allen Institute.

00:35:12.260 --> 00:35:13.780
Allen Brain Institute, I'm guessing.

00:35:15.080 --> 00:35:15.940
It was just released.

00:35:15.940 --> 00:35:21.320
So if you're doing anything with graphics and pictures and file formats and stuff for that, check that out.

00:35:21.320 --> 00:35:23.240
And yeah, that's it for me.

00:35:23.240 --> 00:35:24.880
I think, Mike, you got one as well, right?

00:35:24.880 --> 00:35:25.200
Elise?

00:35:26.160 --> 00:35:26.560
Yeah.

00:35:26.560 --> 00:35:26.720
Yeah.

00:35:26.720 --> 00:35:34.960
So yeah, PEP563 was, I think it's a postponed evaluation of annotations.

00:35:34.960 --> 00:35:43.640
And basically, there was some, as I think I mentioned before, I'm a big fan of FastAPI and Pydantic.

00:35:43.640 --> 00:35:53.560
And there was some worry a couple months ago that this change would effectively break these projects in 3.10 if it was introduced.

00:35:53.560 --> 00:36:08.960
And so I just wanted to give a shout out to the community for jumping on this and just being really open-minded about this and basically postponing this a little further so that better decisions can be made on how to navigate this change.

00:36:08.960 --> 00:36:19.020
So I don't want to go too deep into it, but I read some of the threads on this and it was just really positive exchange within the community.

00:36:19.020 --> 00:36:20.360
And I think it turned out really well.

00:36:20.360 --> 00:36:23.200
There was like a unanimous decision, I believe, to postpone it.

00:36:23.200 --> 00:36:27.120
And it saved these projects from having to, well, basically.

00:36:27.120 --> 00:36:28.340
At a minimum scramble.

00:36:28.340 --> 00:36:28.960
Yeah.

00:36:28.960 --> 00:36:31.240
Worst case, not work.

00:36:31.240 --> 00:36:31.740
Yeah.

00:36:31.740 --> 00:36:32.260
Yeah.

00:36:32.260 --> 00:36:33.680
Let me see if I can give the elevator pitch.

00:36:33.680 --> 00:36:37.640
There was a proposal in Python 3.10, I guess, 5.3.8.

00:36:37.640 --> 00:36:38.500
I know, sorry.

00:36:38.500 --> 00:36:40.240
5.6.3.

00:36:40.240 --> 00:36:41.620
I don't know where that came from.

00:36:41.620 --> 00:36:42.260
5.6.3.

00:36:42.260 --> 00:36:43.020
PEP563.

00:36:43.020 --> 00:36:47.900
There was a possibility where there's an attempt to simplify and speed up type annotations.

00:36:47.900 --> 00:36:53.260
And by, because right now, if you want to do a type annotation, if I'm going to say I've created a Pydantic model, it's called user.

00:36:53.260 --> 00:36:54.620
And I'm going to say this thing returns a user.

00:36:54.620 --> 00:36:56.560
I have to import user at the top.

00:36:56.560 --> 00:37:03.600
And it was like, well, you're not going to get those evaluated or really dealt with unless you're doing type annotation analysis.

00:37:03.860 --> 00:37:06.580
So we're going to treat those as strings, basically.

00:37:06.580 --> 00:37:07.120
Yeah.

00:37:07.120 --> 00:37:07.640
Right.

00:37:07.640 --> 00:37:18.020
And things like FastAPI and Pydantic and others were going, they would actually get the type information, standard Python style, and then use that to modify behavior.

00:37:18.020 --> 00:37:18.600
Right.

00:37:18.600 --> 00:37:20.600
Like to do, oh, it says it's a list of ends.

00:37:20.600 --> 00:37:23.560
So we're going to convert from this list of those, or maybe a list of user.

00:37:23.560 --> 00:37:26.220
We're going to convert these JSON things to users.

00:37:26.220 --> 00:37:28.660
But with this change, it would have said, well, it's a string.

00:37:28.660 --> 00:37:29.880
And what does user mean?

00:37:29.880 --> 00:37:30.240
Right.

00:37:30.240 --> 00:37:33.580
If you don't know the actual type where it's coming from, there could be multiple users.

00:37:33.580 --> 00:37:34.420
It could be a user.

00:37:34.420 --> 00:37:35.920
It couldn't track down.

00:37:35.920 --> 00:37:36.940
Has it been imported yet?

00:37:36.940 --> 00:37:38.880
All sorts of weirdness around it.

00:37:38.880 --> 00:37:48.380
So the runtime behavior of these type annotated things like Typer, Pydantic, FastAPI, we're not sure how they were going to keep working with this being adopted.

00:37:48.380 --> 00:37:51.060
And it sounds like it's postponed at least until 3.11.

00:37:51.060 --> 00:37:51.540
Yeah.

00:37:51.540 --> 00:37:52.020
Exactly.

00:37:52.020 --> 00:37:52.940
Yeah.

00:37:52.940 --> 00:37:53.720
Thanks for bringing this up.

00:37:53.720 --> 00:37:54.180
That's a good one.

00:37:54.180 --> 00:37:54.500
Yeah.

00:37:54.500 --> 00:37:55.160
All right.

00:37:55.160 --> 00:37:57.200
Well, kind of end of the show.

00:37:57.200 --> 00:37:58.320
Do we have any jokes?

00:37:58.320 --> 00:38:00.680
I got something for you.

00:38:00.680 --> 00:38:02.440
I'll tell you.

00:38:02.440 --> 00:38:03.300
You're loving of it.

00:38:03.300 --> 00:38:06.600
So this is from Zach, RMRF on Twitter.

00:38:06.600 --> 00:38:10.840
It says, did you hear about the four Pythonistas that robbed a bank?

00:38:10.840 --> 00:38:11.940
Three got caught.

00:38:11.940 --> 00:38:15.820
And when questioned, they all stated that the fourth would never be caught.

00:38:15.820 --> 00:38:20.160
Couldn't be caught because he knew RegEx and was something of an escape artist.

00:38:20.160 --> 00:38:23.900
That's funny.

00:38:23.900 --> 00:38:24.380
Yeah.

00:38:24.380 --> 00:38:25.000
I think that's pretty good.

00:38:25.000 --> 00:38:25.920
Well done, Zach.

00:38:25.920 --> 00:38:26.700
Thanks for sending that in.

00:38:26.700 --> 00:38:28.040
Brian, you got anything as well?

00:38:28.440 --> 00:38:28.700
Yeah.

00:38:28.700 --> 00:38:30.340
Let me pull it up.

00:38:30.340 --> 00:38:41.120
So Rich, not Rich, Will McGugan asked about Rich and said, hey, if I wrote a book about

00:38:41.120 --> 00:38:44.560
Rich, how much money would you pay for it?

00:38:44.560 --> 00:38:46.260
But also what should be in the book?

00:38:46.260 --> 00:38:50.920
Of course, I said it should cover how fast it is to install it.

00:38:51.040 --> 00:38:52.900
Kind of a get rich quick guide.

00:38:52.900 --> 00:38:58.440
Love it.

00:38:58.440 --> 00:38:59.140
Love it.

00:38:59.140 --> 00:39:01.260
And I believe the response was something like, get out.

00:39:01.260 --> 00:39:01.960
Get out.

00:39:01.960 --> 00:39:02.300
Yeah.

00:39:02.300 --> 00:39:03.500
Definitely.

00:39:03.780 --> 00:39:04.240
Oh, nice.

00:39:04.240 --> 00:39:06.340
Will's getting a lot of coverage this week.

00:39:06.340 --> 00:39:06.860
That's beautiful.

00:39:06.860 --> 00:39:07.760
He's doing good work.

00:39:07.760 --> 00:39:08.760
All right.

00:39:08.760 --> 00:39:09.380
Speed of coverage.

00:39:09.380 --> 00:39:09.640
Yeah.

00:39:09.640 --> 00:39:10.420
Thanks for being here, Mike.

00:39:10.420 --> 00:39:11.600
Well, thank you guys for having me.

00:39:11.600 --> 00:39:12.200
This was really fun.

00:39:12.200 --> 00:39:12.700
Yeah.

00:39:12.700 --> 00:39:13.300
Thank you.

00:39:13.300 --> 00:39:15.780
Thanks for everybody for joining on the live stream as well.

00:39:15.780 --> 00:39:16.280
Wow.

00:39:16.280 --> 00:39:18.240
Thank you for listening to Python Bytes.

00:39:18.240 --> 00:39:20.800
Follow the show on Twitter via at Python Bytes.

00:39:20.800 --> 00:39:23.680
That's Python Bytes as in B-Y-T-E-S.

00:39:23.680 --> 00:39:27.040
And get the full show notes at Pythonbytes.fm.

00:39:27.040 --> 00:39:31.360
If you have a news item you want featured, just visit Pythonbytes.fm and send it our way.

00:39:31.500 --> 00:39:34.060
We're always on the lookout for sharing something cool.

00:39:34.060 --> 00:39:37.240
On behalf of myself and Brian Okken, this is Michael Kennedy.

00:39:37.240 --> 00:39:40.740
Thank you for listening and sharing this podcast with your friends and colleagues.