WEBVTT

00:00:00.001 --> 00:00:02.100
Have you heard that FastAPI is awesome?

00:00:02.100 --> 00:00:06.080
We have Michael Herman back on the show to help us make it even more awesome

00:00:06.080 --> 00:00:08.380
with his FastAPI Awesome list.

00:00:08.380 --> 00:00:13.260
He's categorized many extensions and other libraries working with FastAPI

00:00:13.260 --> 00:00:16.000
to help you be even more efficient with this framework.

00:00:16.000 --> 00:00:22.040
This is Talk Python To Me, episode 315, recorded April 22, 2015.

00:00:22.040 --> 00:00:41.340
Welcome to Talk Python To Me, a weekly podcast on Python, the language, the libraries, the ecosystem, and the personalities.

00:00:41.340 --> 00:00:43.160
This is your host, Michael Kennedy.

00:00:43.160 --> 00:00:49.080
Follow me on Twitter where I'm @mkennedy, and keep up with the show and listen to past episodes at talkpython.fm,

00:00:49.080 --> 00:00:52.220
and follow the show on Twitter via at Talk Python.

00:00:52.220 --> 00:00:55.720
Talk Python To Me is partially supported by our training courses.

00:00:55.720 --> 00:00:59.360
At Talk Python, we run a bunch of web apps and web APIs.

00:00:59.360 --> 00:01:03.780
These power the training courses as well as the mobile apps on iOS and Android.

00:01:03.780 --> 00:01:08.500
If I had to build these from scratch again today, there's no doubt which framework I would use.

00:01:08.500 --> 00:01:09.500
It's FastAPI.

00:01:09.500 --> 00:01:14.100
To me, FastAPI is the embodiment of modern Python and modern APIs.

00:01:14.100 --> 00:01:16.680
You have beautiful usage of type annotations.

00:01:16.960 --> 00:01:19.340
You have model binding and validation with Pydantic.

00:01:19.340 --> 00:01:22.100
And you have first-class async and await support.

00:01:22.100 --> 00:01:27.300
If you're building or rebuilding a web app, you owe it to yourself to check out one of our newest courses,

00:01:27.300 --> 00:01:30.680
Modern APIs with FastAPI, over at Talk Python Training.

00:01:30.680 --> 00:01:34.780
This is the first course in a series of FastAPI courses we're building,

00:01:34.780 --> 00:01:36.420
and you can get it for just $39.

00:01:36.420 --> 00:01:40.240
It'll take you from interested to production with FastAPI.

00:01:40.240 --> 00:01:47.760
To learn more and get started today, just visit talkpython.fm/FastAPI or email us at sales at talkpython.fm.

00:01:47.760 --> 00:01:50.900
Michael, welcome back to Talk Python To Me.

00:01:50.900 --> 00:01:51.520
Thank you.

00:01:51.520 --> 00:01:53.300
Yeah, it's really great to have you back.

00:01:53.300 --> 00:01:59.720
You've been on before, and there's a bunch of stuff that we're going to talk about that you've been up to and we've done.

00:01:59.840 --> 00:02:03.980
So you were back on episode 206 when you talked about running Django in production.

00:02:03.980 --> 00:02:07.820
And you've had a couple of large sites that you've been running.

00:02:07.820 --> 00:02:14.180
And the most recent one is probably testdriven.io where you do some articles, some tutorials, and some courses, right?

00:02:14.180 --> 00:02:14.860
Yeah.

00:02:15.020 --> 00:02:22.200
So life was obviously much different back in when I was on the podcast back in, what was that, February of 2019.

00:02:22.200 --> 00:02:26.180
But so now I'm still working on testdriven.io.

00:02:26.180 --> 00:02:32.380
So that's a, I do training courses for mid to senior level developers that are looking to learn test driven development,

00:02:32.380 --> 00:02:36.060
microservices, and AWS infrastructure and whatnot.

00:02:36.060 --> 00:02:36.680
Nice.

00:02:36.680 --> 00:02:38.680
It's mostly Python and JavaScript stuff.

00:02:38.680 --> 00:02:39.100
Is that right?

00:02:39.100 --> 00:02:39.580
Yeah.

00:02:39.580 --> 00:02:40.020
Yeah.

00:02:40.020 --> 00:02:40.380
Yeah.

00:02:40.380 --> 00:02:40.920
Cool.

00:02:40.920 --> 00:02:42.500
Maybe some at the same time.

00:02:42.500 --> 00:02:43.300
Yeah, a bit.

00:02:43.420 --> 00:02:45.920
I also get a lot into like container orchestration and whatnot.

00:02:45.920 --> 00:02:49.640
A little bit of Kubernetes, a little bit of AWS ECS as well.

00:02:49.640 --> 00:02:50.060
Awesome.

00:02:50.060 --> 00:02:51.320
And so what do you have to do now?

00:02:51.320 --> 00:02:57.340
So yeah, I am running testdriven.io on the side, but my full-time main gig is for Monitor.

00:02:57.340 --> 00:03:02.440
And we, as the banner there says, we're doing machine learning assurance.

00:03:02.440 --> 00:03:07.340
We're really doing probably machine learning governance is probably more like what way to redo the website.

00:03:07.340 --> 00:03:11.020
That's probably what we would establish machine learning governance would be there rather than assurance.

00:03:11.200 --> 00:03:19.160
But basically we're helping to ensure that your AI is doing what it should be doing in production.

00:03:19.160 --> 00:03:26.800
So that your models are basically inferences or predictions that your models are serving up are like within a certain bounds, essentially.

00:03:26.800 --> 00:03:27.500
Right.

00:03:27.580 --> 00:03:34.120
Like if the input data changes and you don't change your models, maybe they're not meant to understand that type of data.

00:03:34.120 --> 00:03:36.740
And there's just, you know, the thing is you're always going to get an answer, right?

00:03:36.740 --> 00:03:37.140
Yeah.

00:03:37.140 --> 00:03:40.460
It just might be the wrong or invalid data, but it looks like a valid answer.

00:03:40.460 --> 00:03:41.340
Like, how do you know, right?

00:03:41.340 --> 00:03:41.720
Yeah.

00:03:41.720 --> 00:03:49.860
It's kind of like an Excel, like whenever you get, you know, whatever it is besides an NA or whatever, you know, you don't know that's like good or bad or not.

00:03:49.920 --> 00:03:51.940
And so, yeah, we're looking for like feature drift.

00:03:51.940 --> 00:03:53.240
We're looking for model drift.

00:03:53.240 --> 00:03:55.260
We're looking for bias, you know, that sort of things.

00:03:55.260 --> 00:03:58.800
We're also, we take all inferences that go through a model.

00:03:58.800 --> 00:04:01.580
We're logging and then we're also versioning the model as well.

00:04:01.580 --> 00:04:05.200
So you can recreate the model, run counterfactual type tests and whatnot.

00:04:05.200 --> 00:04:05.960
Interesting.

00:04:05.960 --> 00:04:06.420
Okay.

00:04:06.420 --> 00:04:08.800
Is that mostly Python stuff over there?

00:04:08.800 --> 00:04:09.660
What's the tech?

00:04:09.660 --> 00:04:10.140
Yeah.

00:04:10.140 --> 00:04:11.540
So it's a Django monolith.

00:04:11.540 --> 00:04:20.400
That's like the backend API using Flask is sort of a middle layer to transform data between the API and the front end.

00:04:20.400 --> 00:04:24.260
The front end is in view and it's primarily AWS.

00:04:24.260 --> 00:04:30.560
And so I'm using Terraform as infrastructure as code to simplify the maintaining of the infrastructure.

00:04:30.560 --> 00:04:31.340
Oh, that's cool.

00:04:31.340 --> 00:04:33.400
I feel like Terraform has definitely taken off.

00:04:33.400 --> 00:04:35.600
I hear a lot of people saying that they're using it these days.

00:04:35.600 --> 00:04:36.740
Yeah, I really.

00:04:36.740 --> 00:04:41.580
Is that like Ansible or Chef or it's like a competitor to that, right?

00:04:41.580 --> 00:04:43.600
Yeah, I think those are a little bit different.

00:04:43.600 --> 00:04:48.000
I would say it's more of a competitor to like CloudFormation templates.

00:04:48.000 --> 00:04:53.660
And CloudFormation, I think there's a new sort of infrastructure as code from AWS called CDK.

00:04:53.660 --> 00:04:57.060
That's a little bit more declarative, sort of how Terraform is.

00:04:57.060 --> 00:05:01.480
And I haven't had a chance to look at that, but I think that's sort of like the new hotness these days.

00:05:01.480 --> 00:05:06.240
And then there's one more called like Bloomy, I believe is the name, but I haven't used that one.

00:05:06.240 --> 00:05:07.020
Yeah, cool.

00:05:07.020 --> 00:05:17.760
People want to learn more about what's going on with Monotar, they can check out episode 261, which is a little newer, April 2020 with one of your co-founders, Andrew Clark.

00:05:17.760 --> 00:05:18.980
Is he still working with you?

00:05:18.980 --> 00:05:19.780
Yeah, definitely.

00:05:19.780 --> 00:05:20.760
Yeah, cool.

00:05:20.760 --> 00:05:23.580
So we dive into all that sort of stuff over there, which is cool.

00:05:23.580 --> 00:05:27.680
So really the main thing that we're going to talk about is FastAPI, right?

00:05:27.780 --> 00:05:29.080
Like that's what we're both here.

00:05:29.080 --> 00:05:31.820
We're both fans of FastAPI on multiple levels.

00:05:31.820 --> 00:05:38.840
And yeah, so we're going to talk about the basically all the extensions in the ecosystem around FastAPI.

00:05:39.280 --> 00:05:43.080
But make the case for us for FastAPI itself.

00:05:43.080 --> 00:05:51.560
Like I feel like there was quite a thousand flowers blooming type of thing going on once async and await came out in Python, right?

00:05:51.560 --> 00:05:55.180
We had the Django, the Flask, old standbys.

00:05:55.180 --> 00:06:02.460
And then when things switched with type annotations and with async and await, those frameworks couldn't move super quick to adapt to those.

00:06:02.460 --> 00:06:09.360
So things like FastAPI and Sanic and Jeprento and Starlette and API Star, all these things just sort of came into existence.

00:06:09.360 --> 00:06:11.960
And, you know, FastAPI is certainly among that crowd, right?

00:06:12.340 --> 00:06:14.340
Yeah, FastAPI definitely leverages Starlet.

00:06:14.340 --> 00:06:18.240
And so, yeah, you get the whole async syntax, async and await syntax.

00:06:18.240 --> 00:06:21.440
I would say that I like FastAPI for other things.

00:06:21.440 --> 00:06:24.260
Like I don't really take advantage of async and await.

00:06:24.260 --> 00:06:30.480
And like the, I have one production app that's running in FastAPI and I could honestly care less about async and await.

00:06:30.480 --> 00:06:33.860
But it's more about like the developer experience that I get.

00:06:33.860 --> 00:06:35.780
And also I really like Pydantic.

00:06:35.780 --> 00:06:45.740
I would say that, yeah, if you're really into Pydantic and that's like what you use for serialization, deserialization, whatnot, then I would definitely check out FastAPI.

00:06:45.740 --> 00:06:46.320
Absolutely.

00:06:46.320 --> 00:06:50.120
Just, you probably don't realize it because it's not very obvious.

00:06:50.120 --> 00:06:52.780
There's like, you scoured the website, you might learn this.

00:06:52.780 --> 00:06:59.140
I just interviewed Samuel Colvin, the creator and maintainer of Pydantic, about Pydantic and all the cool stuff it does.

00:06:59.140 --> 00:07:02.720
So people who are listening to this may have just listened to that episode.

00:07:02.720 --> 00:07:09.160
And FastAPI is a framework that absolutely takes Pydantic and puts it on the boundary, right?

00:07:09.160 --> 00:07:15.500
Like it's, when data is exchanged with FastAPI, the most default way to do that is to somehow involve Pydantic models, right?

00:07:15.500 --> 00:07:15.820
Yeah.

00:07:15.820 --> 00:07:26.760
And I mean, like if you could think back to like Flask, Flask is like just a wrapper on top of Wurzwig and I'm not pronouncing that right, but Wurzwig, Click and a couple others that are escaping me right now.

00:07:26.760 --> 00:07:28.500
But FastAPI is really just a wrapper.

00:07:28.500 --> 00:07:29.300
It's dangerous.

00:07:29.300 --> 00:07:30.640
And like a couple other, yeah.

00:07:30.800 --> 00:07:30.960
Yeah.

00:07:30.960 --> 00:07:36.440
It's just a wrapper on top of Pydantic, OpenAPI, JSON schema, that sort of things.

00:07:36.440 --> 00:07:36.800
Yeah.

00:07:36.800 --> 00:07:39.420
A few more like sort of modern tools like that.

00:07:39.420 --> 00:07:47.940
And so what makes FastAPI cool is that you can, makes it easy to like hook into those two so you can like leverage that and build plugins and whatnot.

00:07:47.940 --> 00:07:48.540
Yeah.

00:07:48.920 --> 00:07:54.020
So you can say things like, here's my API endpoint that I expect somebody to send a JSON document to.

00:07:54.020 --> 00:07:59.780
Oh, and the argument to the document is just a Pydantic model.

00:07:59.780 --> 00:08:00.180
Yeah.

00:08:00.180 --> 00:08:00.640
Right.

00:08:00.700 --> 00:08:08.120
And then FastAPI will either successfully convert that model over or send something like a 400 or 422 back to say bad data.

00:08:08.120 --> 00:08:09.780
We can't convert it to what we're expecting.

00:08:09.780 --> 00:08:17.340
And on top of that, FastAPI then automatically generates the OpenAPI stuff, which you hinted at based on those models, right?

00:08:17.340 --> 00:08:17.900
Yeah.

00:08:17.900 --> 00:08:18.540
Yeah.

00:08:18.540 --> 00:08:21.140
So you can sort of that runtime type checking that you were talking about.

00:08:21.140 --> 00:08:24.580
And so you're really abstracting that out all to Pydantic.

00:08:24.580 --> 00:08:27.540
And so like you don't have to maintain like a test suite around that either.

00:08:27.540 --> 00:08:30.500
And so it handles all of like the error handling around that.

00:08:30.500 --> 00:08:34.920
It sends back a nice human and computer readable response.

00:08:34.920 --> 00:08:35.460
Yeah.

00:08:35.460 --> 00:08:42.980
One of the things I like is if you've got like a nested object, maybe I've got a Pydantic model and has a list of little baby Pydantic models.

00:08:42.980 --> 00:08:44.120
And then there's an error.

00:08:44.120 --> 00:08:48.340
The error would say the third thing in the list is where the problem is.

00:08:48.420 --> 00:08:52.960
Not just there's some invalid data, but on this field, you got a list.

00:08:52.960 --> 00:08:54.300
You've sent me a list of things.

00:08:54.300 --> 00:08:57.480
The third one, that's where that type conversion error is.

00:08:57.480 --> 00:09:01.180
It's like really good about giving you like allowing you to drill on where the data is wrong.

00:09:01.180 --> 00:09:01.500
Yeah.

00:09:01.500 --> 00:09:02.300
Okay, cool.

00:09:02.300 --> 00:09:06.660
So we've got the async and await stuff, which you said you don't use a lot, but if you need it.

00:09:06.660 --> 00:09:07.260
It's there.

00:09:07.260 --> 00:09:08.620
It's nice to have it, right?

00:09:08.620 --> 00:09:09.360
It's really there.

00:09:09.360 --> 00:09:12.140
We're going to talk about some of the places that like plug into that in a moment.

00:09:12.140 --> 00:09:14.020
Pydantic, I think is a big one.

00:09:14.020 --> 00:09:17.260
The OpenAPI stuff is a big one.

00:09:17.560 --> 00:09:19.440
And to me also deployment is just simple, right?

00:09:19.440 --> 00:09:24.460
As long as you've got uvicorn or G-Unicorn plus uvicorn, you're kind of good to go, right?

00:09:24.460 --> 00:09:27.080
There's not a lot of other stuff you got to do on the server.

00:09:27.080 --> 00:09:31.840
Just G-Unicorn, fire this thing up and maybe point Nginx, put Nginx in front of it.

00:09:31.840 --> 00:09:32.180
Yeah.

00:09:32.180 --> 00:09:32.920
Yeah, definitely.

00:09:32.920 --> 00:09:35.800
I like how it doesn't have a development server either.

00:09:35.800 --> 00:09:36.900
So you have to use...

00:09:36.900 --> 00:09:37.380
I do too.

00:09:37.600 --> 00:09:39.220
Yeah, uvicorn and development.

00:09:39.220 --> 00:09:44.880
And I think that helps beginners that are new to sort of web development conceptually understand

00:09:44.880 --> 00:09:47.200
that, hey, this development server is...

00:09:47.200 --> 00:09:51.120
There's a difference here between this development server and this production server.

00:09:51.120 --> 00:09:56.540
Whereas like with Flask and with Django, where they give you like a development WSGI server

00:09:56.540 --> 00:09:57.280
right out of the box.

00:09:57.280 --> 00:09:59.840
I think it's confusing because a lot of people are like, well, why do I need that?

00:09:59.840 --> 00:10:00.500
Why do I need...

00:10:00.500 --> 00:10:02.440
Why can't I use this instead of G-Unicorn?

00:10:02.900 --> 00:10:03.220
Exactly.

00:10:03.220 --> 00:10:04.720
And they always come with this warning.

00:10:04.720 --> 00:10:05.960
This is not a production server.

00:10:05.960 --> 00:10:07.000
Please don't use this.

00:10:07.000 --> 00:10:08.080
And you're like, okay, well...

00:10:08.080 --> 00:10:08.300
Yeah.

00:10:08.300 --> 00:10:10.680
What if I want to test it like for performance?

00:10:10.680 --> 00:10:12.740
Is it kind of like what I would expect?

00:10:12.740 --> 00:10:13.700
Is it really different?

00:10:13.700 --> 00:10:15.020
Like there's all these things.

00:10:15.020 --> 00:10:18.120
Just like, just make it run what you're going to run in production anyway, right?

00:10:18.120 --> 00:10:18.540
Yeah.

00:10:18.540 --> 00:10:19.400
Yeah, definitely.

00:10:19.400 --> 00:10:19.880
Yeah.

00:10:19.880 --> 00:10:20.440
Pretty cool.

00:10:20.440 --> 00:10:20.660
Okay.

00:10:20.660 --> 00:10:23.820
Well, I think that's a pretty solid case for FastAPI.

00:10:23.820 --> 00:10:29.780
I do think it's probably its biggest parallel competitor type thing is probably Flask.

00:10:29.780 --> 00:10:31.640
You know, a lot of times people are using Django.

00:10:31.800 --> 00:10:35.400
They're trying to do a little bit more than maybe what they're doing with Flask.

00:10:35.400 --> 00:10:37.400
Flask has many, many plugins as well.

00:10:37.400 --> 00:10:38.100
So I don't know.

00:10:38.100 --> 00:10:38.880
What do you think about this?

00:10:38.880 --> 00:10:40.000
Do you see these working together?

00:10:40.000 --> 00:10:42.020
Would you use one instead of the other?

00:10:42.020 --> 00:10:46.100
It's interesting because I think last week, you know, Flask announced their 2.0.

00:10:46.100 --> 00:10:46.940
Yes, they did.

00:10:46.940 --> 00:10:49.680
Another 2.0 is going to have some async and await support.

00:10:49.680 --> 00:10:54.420
That'll be interesting because like the entire Flask, part of the power behind Flask is the ecosystem.

00:10:54.420 --> 00:10:56.900
Like you have just thousands of plugins.

00:10:56.900 --> 00:11:00.740
Some might argue that's like there's too many plugins, but regardless, there's a lot of different

00:11:00.740 --> 00:11:01.480
plugins there.

00:11:01.700 --> 00:11:05.900
And so are they all going to start migrating over and supporting async and await?

00:11:05.900 --> 00:11:06.780
What are they going to do?

00:11:06.780 --> 00:11:08.120
So I think that'll be interesting.

00:11:08.120 --> 00:11:12.740
But I would say there's obviously a lot of comparison type articles between Flask and Fast

00:11:12.740 --> 00:11:13.000
API.

00:11:13.000 --> 00:11:14.200
I don't know.

00:11:14.200 --> 00:11:18.640
Like I try not to get into the either or type thinking and try and think of and in both.

00:11:18.640 --> 00:11:19.580
They're both tools.

00:11:19.580 --> 00:11:20.920
I use all three.

00:11:20.920 --> 00:11:22.660
I like FastAPI for certain things.

00:11:22.660 --> 00:11:25.460
I use Django for other things and I use Flask for other things.

00:11:25.960 --> 00:11:29.720
And so it's just all about like the tool, having the right tool for the job.

00:11:29.720 --> 00:11:29.960
Yeah.

00:11:29.960 --> 00:11:30.360
Yeah.

00:11:30.360 --> 00:11:35.100
I would say that FastAPI is more similar to Flask than obviously is Django.

00:11:35.100 --> 00:11:37.680
And so it's probably going to be compared more to Flask.

00:11:37.680 --> 00:11:41.960
But I still think that there's like certain reasons that I would probably use Flask over

00:11:41.960 --> 00:11:42.620
FastAPI.

00:11:42.620 --> 00:11:43.180
Sure.

00:11:43.180 --> 00:11:47.320
That may well be because one of the plugins that you're talking about exactly nails the use

00:11:47.320 --> 00:11:47.560
case.

00:11:47.560 --> 00:11:47.900
Yeah.

00:11:47.900 --> 00:11:53.240
And I'm also going to have David and Phil on to talk about the Flask 2.0 release pretty

00:11:53.240 --> 00:11:53.460
soon.

00:11:53.460 --> 00:11:58.080
So that's, I think there's been this sort of like leapfrog thing is probably going to put

00:11:58.080 --> 00:12:02.620
Flask back, if not ahead of FastAPI and some of the cool features, it'll bring a lot of those

00:12:02.620 --> 00:12:03.800
features over, I would expect.

00:12:03.800 --> 00:12:08.260
It's also worth pointing out that like in Flask, you can still do cool stuff with say Pydantic,

00:12:08.260 --> 00:12:09.000
right?

00:12:09.000 --> 00:12:10.740
You just need one extra line of code.

00:12:10.740 --> 00:12:16.440
The very first line of your API method could just be model equals Pydantic thing, star,

00:12:16.440 --> 00:12:21.600
star, request, dot, get form or whatever the call is to get the form data that's been posted

00:12:21.600 --> 00:12:25.520
over or get the JSON data that's been posted over and then just run with it the same.

00:12:25.520 --> 00:12:25.800
Yeah.

00:12:25.800 --> 00:12:26.160
Yeah.

00:12:26.160 --> 00:12:28.640
And there's a nice like Flask Pydantic plugin as well.

00:12:28.640 --> 00:12:32.920
So yeah, you can definitely use Pydantic inside of Flask.

00:12:32.920 --> 00:12:37.860
And then there's also like Flask Res X, which will give you nice open API slash Swagger type

00:12:37.860 --> 00:12:38.580
support as well.

00:12:38.580 --> 00:12:39.900
So if you want that out of the box.

00:12:39.900 --> 00:12:40.480
Interesting.

00:12:40.700 --> 00:12:40.900
Okay.

00:12:40.900 --> 00:12:43.000
And a lot of this is awareness, right?

00:12:43.000 --> 00:12:45.600
Like knowing, oh, there's this thing that I can go get, right?

00:12:45.600 --> 00:12:50.020
Knowing that I could get Flask Pydantic or the open API, so on.

00:12:50.020 --> 00:12:52.320
And that brings us to our main topic here.

00:12:52.320 --> 00:12:56.140
How do you discover these things and know that they're out there, right?

00:12:56.140 --> 00:13:02.540
It turns out there's actually a bunch of extension type libraries for FastAPI.

00:13:02.540 --> 00:13:06.840
I don't know there's an official plugin model for FastAPI, but certainly things built to make

00:13:06.840 --> 00:13:09.200
FastAPI better and add functionality to it, right?

00:13:09.560 --> 00:13:13.900
And so I learned about a lot of them from your awesome FastAPI list.

00:13:13.900 --> 00:13:18.700
But maybe just for a minute, for people who are not aware of this whole trend of awesome

00:13:18.700 --> 00:13:22.320
lists, maybe just talk about awesome lists for us a little bit.

00:13:22.320 --> 00:13:23.280
Like what's the story?

00:13:23.280 --> 00:13:24.420
Where do these things come from?

00:13:24.620 --> 00:13:26.980
Yeah, I can't remember exactly when they started popping up.

00:13:26.980 --> 00:13:29.640
I feel like maybe like five years ago, something like that.

00:13:29.640 --> 00:13:33.340
But I mean, awesome lists is, I guess, just literally just a list of awesome things.

00:13:33.340 --> 00:13:36.880
In theory, it's contributed, maintained by the community.

00:13:36.880 --> 00:13:42.100
I mean, oftentimes what really happens is like the main author becomes like sort of a dictator

00:13:42.100 --> 00:13:44.460
around that, which I think is totally fine.

00:13:44.460 --> 00:13:48.760
But I think there's just, there's thousands of different awesome lists out there.

00:13:48.760 --> 00:13:54.840
And so it's just, you're like a meta, meta awesome, awesome list of awesome lists, you know,

00:13:54.840 --> 00:13:55.520
type thing there.

00:13:55.720 --> 00:13:57.660
So it gets a little crazy.

00:13:57.660 --> 00:13:59.620
It does get super, super meta.

00:13:59.620 --> 00:14:01.300
And it gets very specific as well.

00:14:01.300 --> 00:14:07.240
The one that probably people know best in the Python space is awesome-python.com, which is

00:14:07.240 --> 00:14:08.600
really general, right?

00:14:08.600 --> 00:14:10.840
I mean, there's Flask stuff and FastAPI stuff.

00:14:10.840 --> 00:14:13.540
There's zillions of other areas.

00:14:13.540 --> 00:14:17.940
And then there's all these offshoots like yours around FastAPI and Stump for Flask and

00:14:17.940 --> 00:14:18.260
so on.

00:14:18.260 --> 00:14:18.780
Cool.

00:14:18.780 --> 00:14:22.440
So when did you create your awesome FastAPI?

00:14:22.440 --> 00:14:24.260
It can't be more than two years ago, right?

00:14:24.260 --> 00:14:26.120
Yeah, I would say.

00:14:26.120 --> 00:14:27.100
How long FastAPIs?

00:14:27.100 --> 00:14:30.360
It must be like a year old, I would say.

00:14:30.360 --> 00:14:35.440
I can't remember when we launched the FastAPI course on Test Driven, but it was like right

00:14:35.440 --> 00:14:36.340
around the same time.

00:14:36.340 --> 00:14:40.580
I think the list probably actually came out before that because the first blog posts on

00:14:40.580 --> 00:14:43.040
FastAPI came out in January of 2020.

00:14:43.040 --> 00:14:44.880
So it was definitely after that.

00:14:44.880 --> 00:14:46.040
Yeah, really cool.

00:14:46.040 --> 00:14:49.600
Well, and I think, you know, it's FastAPI being around two years old.

00:14:49.600 --> 00:14:53.700
It takes a little while for these extra libraries to build up around it, right?

00:14:53.700 --> 00:14:56.140
And I definitely think it's gaining momentum.

00:14:56.140 --> 00:15:01.160
It was for the first time it showed up on, I think it was the PSF JetBrains survey for

00:15:01.160 --> 00:15:01.720
2020.

00:15:01.720 --> 00:15:05.100
And I went straight to number three as the most popular web framework.

00:15:05.100 --> 00:15:09.800
It was really quite interesting how popular it, how quickly it became popular.

00:15:09.800 --> 00:15:14.840
To me, it's because it brings together these little pieces, each one that is kind of a neat,

00:15:15.080 --> 00:15:21.400
new modern Python idea, like type hints, like Pydantic, like async and await, all those things.

00:15:21.400 --> 00:15:24.580
And you just bring it all together and wanting to go, yeah, this has all the things that I

00:15:24.580 --> 00:15:24.860
care about.

00:15:24.860 --> 00:15:25.340
This is cool.

00:15:25.340 --> 00:15:26.040
All right.

00:15:26.040 --> 00:15:30.880
So your awesome list is broken down into a bunch of different categories, like third-party

00:15:30.880 --> 00:15:36.900
extensions, and then resources, including, say, a podcast episode like this one, and so on,

00:15:36.900 --> 00:15:38.500
hosting, and so on.

00:15:39.020 --> 00:15:42.680
So what I thought it'd be fun to do is let's just maybe go through some of those sections

00:15:42.680 --> 00:15:47.920
and highlight a couple of the tools or extensions or whatever that are really neat.

00:15:47.920 --> 00:15:49.280
Yeah, that sounds great.

00:15:49.280 --> 00:15:51.360
How about the FastAPI admin for the first one?

00:15:51.360 --> 00:15:56.280
One of the reasons why I did create this is mainly for these third-party extensions for

00:15:56.280 --> 00:15:57.040
listing these.

00:15:57.520 --> 00:16:02.580
I think it's kind of Django packages.org really aggregates them really well for, you know,

00:16:02.580 --> 00:16:03.380
obviously for Django.

00:16:03.380 --> 00:16:06.300
I don't think there is one anymore for Flask.

00:16:06.300 --> 00:16:09.460
The main Flask docs used to have a list, but it just got out of control.

00:16:09.460 --> 00:16:10.060
Yeah.

00:16:10.060 --> 00:16:14.680
But I think one of the powerful things is definitely the ecosystem and like these extensions.

00:16:14.680 --> 00:16:17.000
So I thought like someone's got to like start this, so.

00:16:17.000 --> 00:16:18.040
Fantastic.

00:16:18.040 --> 00:16:18.820
All right.

00:16:18.820 --> 00:16:22.440
So the first one I think is pretty interesting is this FastAPI admin.

00:16:22.440 --> 00:16:23.180
Tell us about this.

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

00:16:23.860 --> 00:16:27.760
So, I mean, if you're familiar with Django, like one of the powerful things that you get

00:16:27.760 --> 00:16:33.120
from Django right out of the box is a nice CRUD admin where you can interact with your

00:16:33.120 --> 00:16:37.060
models, your database models in sort of like a CRUD GUI-like fashion.

00:16:37.060 --> 00:16:41.540
And so you can add data, all of sort of the CRUD functionality right out of the box.

00:16:41.540 --> 00:16:43.440
So you don't have to jump into SQL.

00:16:43.440 --> 00:16:46.900
So yeah, this just like mimics sort of that same sort of behavior.

00:16:46.900 --> 00:16:47.640
Very cool.

00:16:47.640 --> 00:16:48.160
Very cool.

00:16:48.160 --> 00:16:48.740
Yeah.

00:16:48.740 --> 00:16:52.260
That's one of the main features of Django that I would see people using it for.

00:16:52.260 --> 00:16:52.740
Yeah.

00:16:52.980 --> 00:16:58.960
So the idea is basically if I want to create users or mess with other tables, like here

00:16:58.960 --> 00:17:03.140
they have products and categories and it's just like a grid type thing to add new ones,

00:17:03.140 --> 00:17:04.180
edit existing ones, right?

00:17:04.180 --> 00:17:04.720
Yeah.

00:17:04.720 --> 00:17:05.040
Yeah.

00:17:05.040 --> 00:17:08.840
It's very straightforward, but yeah, it's not like there's not really too much to say about

00:17:08.840 --> 00:17:08.980
it.

00:17:08.980 --> 00:17:12.980
It's not some super sexy interface or anything like that, but it is like, it just saves a

00:17:12.980 --> 00:17:13.480
lot of time.

00:17:13.480 --> 00:17:13.720
Yeah.

00:17:13.720 --> 00:17:18.320
Like one of the main features of the newer Django 3.2 maybe was that there's now templating

00:17:18.320 --> 00:17:20.980
for its admin stuff to make it look all super cool.

00:17:20.980 --> 00:17:21.420
Yeah.

00:17:21.760 --> 00:17:25.460
But to be honest, I think one of the really important things is to make it easy for people

00:17:25.460 --> 00:17:26.060
to get started.

00:17:26.060 --> 00:17:30.280
And you know, for me, if I had to build a little admin backend thing like this, like, all right,

00:17:30.280 --> 00:17:31.900
well, there's half a day.

00:17:31.900 --> 00:17:33.400
Got to do that to add in.

00:17:33.400 --> 00:17:37.280
But if you're starting new and you're like, okay, I got this page showing, but now I need

00:17:37.280 --> 00:17:37.760
to edit them.

00:17:37.760 --> 00:17:38.340
Oh no.

00:17:38.340 --> 00:17:40.880
Like this is going to be such a pain, right?

00:17:40.880 --> 00:17:43.420
Having something like this, you can just plug in.

00:17:43.420 --> 00:17:48.180
It'd be really helpful to say, oh, actually maybe I will choose FastAPI over a Django

00:17:48.180 --> 00:17:51.580
rest framework, for example, potentially because it might have an admin, right?

00:17:51.580 --> 00:17:52.060
Yeah.

00:17:52.060 --> 00:17:55.960
I think one of the negatives about this, and this is one of the negatives with Django is

00:17:55.960 --> 00:17:59.320
a lot of people use it for stuff that it's not intended to be used for.

00:17:59.400 --> 00:18:03.040
Like they try and create, like, you know, make a consumer facing version of it.

00:18:03.040 --> 00:18:07.720
I think that's partly the impetus for like the templates is to be able to do more stuff

00:18:07.720 --> 00:18:11.180
like that, which I think that is not, then you have to make everyone sort of an admin.

00:18:11.180 --> 00:18:12.420
I think that's a bad practice.

00:18:12.420 --> 00:18:12.740
Yeah.

00:18:12.740 --> 00:18:14.700
It might lead to some problems.

00:18:14.700 --> 00:18:15.640
Yeah.

00:18:15.640 --> 00:18:16.180
Yeah.

00:18:16.180 --> 00:18:17.920
Yeah.

00:18:17.920 --> 00:18:22.220
Joe out there on the live stream says, does this include identity?

00:18:22.220 --> 00:18:26.460
Like, can I get a, I'm guessing a restricted admin backend?

00:18:26.460 --> 00:18:26.960
Yeah.

00:18:26.960 --> 00:18:27.360
I'm not sure.

00:18:27.680 --> 00:18:30.400
We are going to talk about other things that do include identity.

00:18:30.400 --> 00:18:34.860
And I suspect, I don't know, I haven't plugged in, but there's probably some point where you

00:18:34.860 --> 00:18:38.720
write some bit of API endpoint, maybe.

00:18:38.720 --> 00:18:39.240
I don't know.

00:18:39.240 --> 00:18:42.480
There's got to be a way where you restrict access to it.

00:18:42.480 --> 00:18:42.880
Yeah.

00:18:42.880 --> 00:18:44.920
It does have admin secret here.

00:18:44.920 --> 00:18:45.740
Maybe that's it.

00:18:45.740 --> 00:18:48.560
I mean, if it works, I haven't used this particular one.

00:18:48.560 --> 00:18:50.600
I don't use Tortoise in production.

00:18:50.600 --> 00:18:55.040
Last I looked at this, it didn't work with any other ORMs besides Tortoise.

00:18:55.240 --> 00:18:59.160
But I know like the, if it's built similar to the, or designed like the Django ORM, the

00:18:59.160 --> 00:19:01.640
Django ORM doesn't have like a concept of permissions.

00:19:01.640 --> 00:19:04.120
So it's just, it has like a super user.

00:19:04.120 --> 00:19:06.540
And so if you're super user access, you get access to it.

00:19:06.540 --> 00:19:09.960
So there's not really any, I think there's probably maybe some extensions you can use to

00:19:09.960 --> 00:19:10.740
like limit access.

00:19:10.740 --> 00:19:11.500
But yeah.

00:19:11.500 --> 00:19:11.960
Yeah.

00:19:11.960 --> 00:19:13.420
It looks like permission true.

00:19:13.420 --> 00:19:15.620
Maybe there is like a concept of permissions here.

00:19:15.620 --> 00:19:19.380
So I'm thinking there's two places where you can put a little bit of protection here.

00:19:19.380 --> 00:19:22.820
One is this, where you say the URL is slash admin.

00:19:22.820 --> 00:19:28.040
The URL could be slash UUID out of some insane length, right?

00:19:28.040 --> 00:19:29.320
So it's not very guessable.

00:19:29.320 --> 00:19:29.800
Yeah.

00:19:30.100 --> 00:19:33.160
And then this app secret, I suspect is like, what is the secret?

00:19:33.160 --> 00:19:35.280
You know, knock, knock, what's the magic word sort of thing.

00:19:35.280 --> 00:19:36.840
And there's just one login for it.

00:19:36.840 --> 00:19:39.780
But for the right type of app, that's probably good enough.

00:19:39.780 --> 00:19:40.160
Yeah.

00:19:40.160 --> 00:19:41.980
You would definitely want to change that URL in production.

00:19:41.980 --> 00:19:43.520
You don't want the forward slash admin.

00:19:43.760 --> 00:19:45.720
People are just always poking for stuff like that.

00:19:45.720 --> 00:19:46.840
Yeah.

00:19:46.840 --> 00:19:49.480
I don't know if you've ever, yeah, I'm sure you've done it.

00:19:49.480 --> 00:19:52.980
And I don't know if people out there in the audience have ever done this, but if you haven't,

00:19:52.980 --> 00:19:54.260
it's shocking.

00:19:54.260 --> 00:19:59.440
If you go and you just tail the log of your site, like the main request log, you'll just

00:19:59.440 --> 00:20:03.380
see like requests for all sorts of like weird, unrelated stuff.

00:20:03.380 --> 00:20:05.400
People just trying to guess to see if it exists.

00:20:05.400 --> 00:20:08.680
Like there's all sorts of requests for like WP admin.

00:20:08.680 --> 00:20:09.300
Yeah.

00:20:09.300 --> 00:20:12.580
Dot PHP on my site.

00:20:12.580 --> 00:20:13.600
And it's written in Python.

00:20:13.600 --> 00:20:15.880
It has no admin thing like that whatsoever.

00:20:15.880 --> 00:20:20.680
But people are just going, is there this type of, can I get and try a default password against

00:20:20.680 --> 00:20:27.000
a PHP admin backend or try that for a Joomla backend and just start jamming on those things.

00:20:27.000 --> 00:20:27.280
Right.

00:20:27.280 --> 00:20:32.520
And so having that URL, something that's just not default, while it's not a big piece of

00:20:32.520 --> 00:20:34.380
security, it dissuades the bots.

00:20:34.380 --> 00:20:35.200
I think.

00:20:35.200 --> 00:20:35.660
Yeah.

00:20:35.660 --> 00:20:36.340
Yeah.

00:20:36.340 --> 00:20:37.600
Keeps the honest people honest.

00:20:37.600 --> 00:20:38.260
Exactly.

00:20:38.260 --> 00:20:39.900
You want to hack, you got to do it for real.

00:20:39.900 --> 00:20:40.640
Okay.

00:20:40.640 --> 00:20:43.260
Let's talk about authentication.

00:20:43.260 --> 00:20:45.680
There's a whole section on different types of things here, right?

00:20:45.680 --> 00:20:46.000
Yeah.

00:20:46.000 --> 00:20:50.440
So the one that I like the best or the one that I've used the most, I guess I'd say is

00:20:50.440 --> 00:20:51.400
FastAPI users.

00:20:51.400 --> 00:20:51.900
Okay.

00:20:51.900 --> 00:20:54.220
And I think that's the most popular one.

00:20:54.220 --> 00:20:54.780
Yeah.

00:20:54.780 --> 00:20:55.200
Yeah.

00:20:55.200 --> 00:20:55.720
This is it.

00:20:55.720 --> 00:21:00.920
So it uses all, like it uses Jot based auth, but you can also sort of like, you can store

00:21:00.920 --> 00:21:01.860
your Jot wherever you want.

00:21:01.860 --> 00:21:06.900
But this also has like a session, you know, capability built into it where you can store

00:21:06.900 --> 00:21:07.800
the Jot in a cookie.

00:21:07.800 --> 00:21:08.280
Okay.

00:21:08.280 --> 00:21:11.960
Because a lot of times, you know, people are storing Jots and local storage, which could

00:21:11.960 --> 00:21:15.920
lead to XSS type attacks or like open you up to like some.

00:21:15.920 --> 00:21:16.240
Yeah.

00:21:16.600 --> 00:21:20.320
XSS or cross-site script or I always get those mixed up.

00:21:20.320 --> 00:21:22.100
But yeah, I thought that was cool.

00:21:22.100 --> 00:21:25.520
You don't see that a lot in like sort of like libraries that are like Jot based.

00:21:25.520 --> 00:21:25.940
Yeah.

00:21:25.940 --> 00:21:26.260
That's cool.

00:21:26.260 --> 00:21:26.420
Yeah.

00:21:26.420 --> 00:21:30.740
It has either a cookie auth or a Jot auth backend, which is cool.

00:21:30.740 --> 00:21:32.360
And it also supports different ORMs.

00:21:32.780 --> 00:21:35.140
So if you'd like SeekwAlchemy, you can do that.

00:21:35.140 --> 00:21:37.420
If you'd like MongoDB, you can do that.

00:21:37.420 --> 00:21:42.320
Cortis or ORMR, which I haven't actually heard of before, but we'll probably talk about it in

00:21:42.320 --> 00:21:42.800
a minute anyway.

00:21:42.800 --> 00:21:44.340
But yeah, quite neat.

00:21:44.340 --> 00:21:46.000
And also OAuth 2.

00:21:46.000 --> 00:21:46.600
Yeah.

00:21:46.600 --> 00:21:48.600
So this is quite neat.

00:21:48.600 --> 00:21:51.900
If you want to plug it in, it looks like a bunch of people have contributed to it.

00:21:51.900 --> 00:21:53.300
So it looks pretty lively.

00:21:53.300 --> 00:21:53.720
Yeah.

00:21:53.720 --> 00:21:54.500
It's very popular.

00:21:54.500 --> 00:21:54.940
Yeah.

00:21:54.940 --> 00:21:59.080
I mean, one thing people might want to check out is the sneak package advisor.

00:21:59.080 --> 00:21:59.880
Have you seen this?

00:21:59.880 --> 00:22:00.580
Mm-hmm.

00:22:00.580 --> 00:22:01.500
Over here.

00:22:01.960 --> 00:22:04.240
And you can put all sorts of different packages in here.

00:22:04.240 --> 00:22:08.740
So if you're like, ah, this one or that one, you could actually pull it up and have it tell

00:22:08.740 --> 00:22:13.720
you, maybe not always that quickly, the health of the community, like how popular is it?

00:22:13.720 --> 00:22:17.080
How healthy is its maintenance and its security and its sustainability and so on?

00:22:17.080 --> 00:22:20.480
So if you're like, oh, I got these two or three extensions that might be doing the same

00:22:20.480 --> 00:22:24.440
thing, it might be worth throwing into this sneak package advisor and get a sense for like,

00:22:24.440 --> 00:22:27.000
ah, this one seems a little stronger in terms of liveliness.

00:22:27.000 --> 00:22:31.700
Is the popularity score, is it based on similar packages or just like kind of global?

00:22:31.700 --> 00:22:32.280
Yeah.

00:22:32.280 --> 00:22:33.060
That's a good question.

00:22:33.060 --> 00:22:38.220
Because I can't imagine that there'd be a more popular off library for FastAPI.

00:22:38.480 --> 00:22:40.480
I think it's global.

00:22:40.480 --> 00:22:45.120
I'm pretty sure it's like a logarithmic global type thing because yeah, right.

00:22:45.120 --> 00:22:46.520
This is probably the most popular one.

00:22:46.520 --> 00:22:47.920
So what's going to beat it, right?

00:22:47.920 --> 00:22:53.460
But it's only 798 stars relative to like Flask users or something like that.

00:22:53.460 --> 00:22:53.660
Right.

00:22:53.660 --> 00:22:54.220
Yeah.

00:22:54.220 --> 00:22:54.760
Yeah.

00:22:54.760 --> 00:22:55.800
I'd have to look and actually see.

00:22:55.800 --> 00:23:00.540
It does like show you similar packages if you can find, sometimes it'll say, here's some

00:23:00.540 --> 00:23:01.560
other stuff that's like it.

00:23:01.560 --> 00:23:05.300
But anyway, I think that might be something to like bring together with just awesome lists

00:23:05.300 --> 00:23:05.760
in general.

00:23:05.760 --> 00:23:06.300
Right.

00:23:06.300 --> 00:23:08.880
And that's, give me a chance to check these out and see how they're doing.

00:23:08.880 --> 00:23:13.940
You've also got Flask, no, FastAPI login based on Flask login.

00:23:13.940 --> 00:23:16.560
They're both two similar and both words in the same place.

00:23:16.560 --> 00:23:17.020
Yeah.

00:23:17.020 --> 00:23:17.420
Yeah.

00:23:17.420 --> 00:23:19.520
Cloud Auth, which is kind of cool.

00:23:19.520 --> 00:23:25.280
So like using Auth0 or AWS Cognito or things like that.

00:23:25.280 --> 00:23:27.060
If you're doing that anyway, that might be nice.

00:23:27.060 --> 00:23:27.640
Yeah.

00:23:27.640 --> 00:23:30.480
Auth0, they just got bought by somebody.

00:23:30.480 --> 00:23:32.540
I feel like Google or something like that.

00:23:32.540 --> 00:23:32.840
Facebook.

00:23:32.840 --> 00:23:33.200
Yeah.

00:23:33.200 --> 00:23:34.280
I think they might've.

00:23:34.280 --> 00:23:34.960
Yeah.

00:23:34.960 --> 00:23:39.360
I feel like they bought something else and then, you know, little fish, big fish, whale.

00:23:39.360 --> 00:23:40.420
Okta.

00:23:40.420 --> 00:23:41.720
I think Okta just bought them.

00:23:41.720 --> 00:23:42.020
Yes.

00:23:42.020 --> 00:23:42.400
That's right.

00:23:42.400 --> 00:23:42.920
It was Okta.

00:23:42.920 --> 00:23:43.360
That's right.

00:23:43.360 --> 00:23:43.620
Yeah.

00:23:43.620 --> 00:23:46.800
Another one I wanted to throw out there while we're in this section that I don't see here

00:23:46.800 --> 00:23:48.700
and I don't see anything that does this.

00:23:48.700 --> 00:23:49.800
Possibly.

00:23:49.800 --> 00:23:51.180
Let's look at FastAPI security.

00:23:51.180 --> 00:23:52.940
Maybe this one does.

00:23:52.940 --> 00:23:55.660
It's not super documented over there.

00:23:55.660 --> 00:24:01.380
I feel like this throws some of the permissions in there that you would really want, but a place

00:24:01.380 --> 00:24:01.700
called.

00:24:01.700 --> 00:24:03.320
Like OpenAPI type stuff?

00:24:03.320 --> 00:24:07.540
More like the general OWASP stuff.

00:24:07.540 --> 00:24:14.140
If you check out secure, just how did they get this as the modern IPI package name?

00:24:14.140 --> 00:24:15.320
Just the word secure.

00:24:16.180 --> 00:24:22.220
But this one, it doesn't say that it plugs in with FastAPI, but it plugs in with Flask

00:24:22.220 --> 00:24:26.360
and Django and Pyramid and Court and Responder and Starlet.

00:24:26.360 --> 00:24:27.520
And Starlette is the foundation.

00:24:27.520 --> 00:24:29.240
So I think that it would actually.

00:24:29.240 --> 00:24:35.440
And what it does is it does things like it sets all the default header behaviors like that

00:24:35.440 --> 00:24:39.780
the frame, you can't embed somebody else's, your site into somebody else's site.

00:24:40.420 --> 00:24:46.420
And that cross-site scripting protection is set and certain types of cache policies and

00:24:46.420 --> 00:24:46.800
whatnot.

00:24:46.800 --> 00:24:52.660
And just by doing like one line of code over on against it, one or two lines, it'll automatically

00:24:52.660 --> 00:24:54.820
just like wrap every request with one of those.

00:24:54.940 --> 00:24:58.380
So that might also be interesting to think about in this regard.

00:24:58.380 --> 00:24:58.760
Yeah.

00:24:58.760 --> 00:25:02.940
Those headers can get confusing, especially if you're using like a single page application.

00:25:02.940 --> 00:25:08.360
You have to, if you're trying to use cookies or some sort of like session based off or whatever

00:25:08.360 --> 00:25:09.200
at the same time.

00:25:09.200 --> 00:25:09.380
Yeah.

00:25:09.380 --> 00:25:12.080
Like it can get pretty complex on those headers.

00:25:12.080 --> 00:25:13.640
So yeah, that seems like a cool package.

00:25:13.640 --> 00:25:14.060
Yeah.

00:25:14.060 --> 00:25:17.360
And if something new comes out that should be added that you don't pay attention to, but

00:25:17.360 --> 00:25:21.860
you happen to upgrade your package, maybe it'll bring like the new best practice along.

00:25:21.860 --> 00:25:22.080
Right?

00:25:22.240 --> 00:25:22.420
Yeah.

00:25:22.420 --> 00:25:22.860
Okay.

00:25:22.860 --> 00:25:23.780
So that's authentication.

00:25:23.780 --> 00:25:24.800
Databases.

00:25:24.800 --> 00:25:30.900
You have it broken down into ORMs, query builders, ODMs, which is for document databases, but it

00:25:30.900 --> 00:25:34.780
looks like a quick scan that document equal equal MongoDB for the moment here.

00:25:34.780 --> 00:25:35.560
Yeah.

00:25:35.560 --> 00:25:39.120
And then there's other, which like JSON exchange and whatnot.

00:25:39.120 --> 00:25:41.480
Let's talk, let's talk ORMs first.

00:25:41.480 --> 00:25:44.400
Big, like you pointed out, big news for SQLAlchemy, right?

00:25:44.400 --> 00:25:44.820
Yeah.

00:25:44.820 --> 00:25:46.300
SQLAlchemy 1.4.

00:25:46.300 --> 00:25:48.420
It was either last week or the week before.

00:25:48.600 --> 00:25:54.400
The change actually broke FastAPI or actually broke the FLAS course because it requires the

00:25:54.400 --> 00:25:58.740
database URI to have PostgresQL as the name rather than just Postgres.

00:25:58.740 --> 00:26:00.980
And so, you know, that broke the course.

00:26:00.980 --> 00:26:02.920
So a little annoying, but you know.

00:26:02.920 --> 00:26:03.100
Yeah.

00:26:03.100 --> 00:26:05.040
And it broke my courses too.

00:26:05.040 --> 00:26:08.360
It broke one of my FastAPI courses because we were using async.

00:26:08.840 --> 00:26:12.600
We were using the new one, the async one, but then they said, well, you're using a driver

00:26:12.600 --> 00:26:13.600
that doesn't support async.

00:26:13.600 --> 00:26:17.060
So we're going to throw an exception instead of just work more slowly.

00:26:17.060 --> 00:26:18.060
And like, ah, so.

00:26:18.060 --> 00:26:18.360
Yeah.

00:26:18.360 --> 00:26:21.960
Again, you had to put like a separate different driver in there and so on.

00:26:21.960 --> 00:26:22.140
So.

00:26:22.140 --> 00:26:22.520
Yeah.

00:26:22.520 --> 00:26:22.920
Yeah.

00:26:22.920 --> 00:26:25.520
So we find out sometimes the hard way about these releases, but.

00:26:25.520 --> 00:26:25.840
Yeah.

00:26:25.840 --> 00:26:27.800
So what's the big deal with SQLAlchemy?

00:26:27.800 --> 00:26:30.160
And then we got the SQLAlchemy plug in here.

00:26:30.160 --> 00:26:30.660
Yeah.

00:26:30.660 --> 00:26:31.200
Let's see.

00:26:31.200 --> 00:26:35.840
So, I mean, I haven't updated this like for specifically for like anything new with

00:26:35.840 --> 00:26:36.400
SQLAlchemy.

00:26:36.400 --> 00:26:38.780
So yeah, there's that FastAPI SQLAlchemy.

00:26:38.780 --> 00:26:42.140
That'd be interesting to take a look at that one to see if like, have there been any updates

00:26:42.140 --> 00:26:44.900
since SQLAlchemy new one has been released?

00:26:44.900 --> 00:26:46.060
It looks like no.

00:26:46.060 --> 00:26:47.280
Looks like it hasn't been touched yet.

00:26:47.280 --> 00:26:48.000
Yeah.

00:26:48.000 --> 00:26:51.100
So maybe if you're looking to contribute, maybe there's something to be done here because

00:26:51.100 --> 00:26:53.580
SQLAlchemy used to not support async.

00:26:53.580 --> 00:26:58.520
The big thing with the SQLAlchemy 1.4, there's stuff with changes in the API to sort of move

00:26:58.520 --> 00:26:59.180
to something new.

00:26:59.300 --> 00:27:05.000
But the big one that's probably relevant here is SQLAlchemy now as of 1.4 supports

00:27:05.000 --> 00:27:05.760
async and await.

00:27:05.760 --> 00:27:11.540
Like async, await, execute this query type of thing and give me the objects back.

00:27:11.540 --> 00:27:13.180
And you might not care at all about that.

00:27:13.180 --> 00:27:18.940
But if you're using async and await view or API endpoints in FastAPI, but you want to use

00:27:18.940 --> 00:27:20.920
SQLAlchemy, well, there goes your async, right?

00:27:20.920 --> 00:27:21.360
It's gone.

00:27:21.360 --> 00:27:24.760
Because one of the most important things to await upon is the database.

00:27:24.760 --> 00:27:27.620
And so now the new SQLAlchemy has that support.

00:27:27.740 --> 00:27:30.420
And I'm guessing this one, it probably doesn't support that, right?

00:27:30.420 --> 00:27:31.700
Because it just, it didn't exist.

00:27:31.700 --> 00:27:33.020
But yeah, so cool.

00:27:33.020 --> 00:27:33.460
Yeah.

00:27:33.460 --> 00:27:34.400
I'm not exactly sure.

00:27:34.400 --> 00:27:38.400
I'm sure it won't work because the sample right here is exactly the same code I had that

00:27:38.400 --> 00:27:38.700
broke.

00:27:38.700 --> 00:27:40.320
So it's not going to work.

00:27:40.320 --> 00:27:44.420
But it also is very possible to be quickly and easily updatable.

00:27:44.420 --> 00:27:44.860
I don't know.

00:27:44.860 --> 00:27:46.120
But people can check that out.

00:27:46.120 --> 00:27:49.420
I guess another one you've mentioned earlier is Tortoise Aurium.

00:27:49.520 --> 00:27:50.860
I haven't really done anything with Tortoise.

00:27:50.860 --> 00:27:51.480
What's the story?

00:27:51.480 --> 00:27:54.580
Like databases are supposed to be fast and here's the turtle going on.

00:27:54.580 --> 00:27:57.100
Yeah.

00:27:57.100 --> 00:27:58.480
I mean, naming is tough, right?

00:27:58.480 --> 00:28:00.100
Exactly.

00:28:00.100 --> 00:28:05.300
I would say like Tortoise is probably the most popular one or like just the one that I've

00:28:05.300 --> 00:28:09.620
like seen the most use out of in terms of seeing a lot of FastAPI projects.

00:28:09.620 --> 00:28:12.860
And so, yeah, I think Tortoise is one that's like leveraged a lot.

00:28:12.860 --> 00:28:16.100
Honestly, people use SQLAlchemy probably more than anything else.

00:28:16.100 --> 00:28:18.740
And they just like don't deal with async type stuff.

00:28:18.740 --> 00:28:22.940
But if you want async await, then yeah, I mean, Tortoise definitely has quite a bit of

00:28:22.940 --> 00:28:23.440
support there.

00:28:23.440 --> 00:28:23.840
Yeah.

00:28:23.840 --> 00:28:27.300
You've got Honi ORM, Tortoise ORM, PeeWee.

00:28:27.300 --> 00:28:28.920
I know PeeWee has an async version.

00:28:28.920 --> 00:28:34.400
I know the Django people are working on an async ORM story, but it's not there yet.

00:28:34.400 --> 00:28:35.720
SQLAlchemy just got it.

00:28:35.720 --> 00:28:41.660
One of the things I like about this is they put just what seems like a pretty fair graph

00:28:41.660 --> 00:28:44.040
comparing all the different ORMs in terms of performance.

00:28:44.040 --> 00:28:50.860
And Tortoise ORM comes up pretty nice on like single inserts and the whole updates.

00:28:50.860 --> 00:28:53.580
But there's also places where it's slower than other stuff.

00:28:53.580 --> 00:28:55.920
And they're just like, we're going to put it all up there and if you find it useful,

00:28:55.920 --> 00:28:56.520
here's what you get.

00:28:56.520 --> 00:29:01.760
And Tortoise is similar to the Django ORM in the sense that it uses an active record type

00:29:01.760 --> 00:29:03.280
approach, more similar to PeeWee.

00:29:03.620 --> 00:29:07.500
Whereas SQLAlchemy uses the Data Mapper approach, I believe.

00:29:07.500 --> 00:29:07.760
Yeah.

00:29:07.760 --> 00:29:08.980
The unit of work style.

00:29:08.980 --> 00:29:09.220
Yeah.

00:29:09.220 --> 00:29:09.720
Yeah.

00:29:09.720 --> 00:29:10.220
Yeah.

00:29:10.220 --> 00:29:13.400
And that's confusing for people because you've got to create the session, then you do all the

00:29:13.400 --> 00:29:15.920
stuff and then you call commit if you want to make changes.

00:29:15.920 --> 00:29:19.060
And it's not that hard to deal with, but it is one of those things.

00:29:19.060 --> 00:29:19.660
You're just like, why?

00:29:19.660 --> 00:29:21.400
Where do I get a hold of the session?

00:29:21.400 --> 00:29:24.760
If I got a hold of the objects and I want to update it, like I do find the active record

00:29:24.760 --> 00:29:26.860
stuff for simple cases, pretty handy.

00:29:26.860 --> 00:29:27.180
Right.

00:29:27.180 --> 00:29:29.500
And it comes from Django as well in that style.

00:29:29.500 --> 00:29:30.020
Yeah.

00:29:30.260 --> 00:29:31.780
So it'd be real familiar.

00:29:31.780 --> 00:29:32.420
Yeah.

00:29:32.420 --> 00:29:32.920
Yeah.

00:29:32.920 --> 00:29:33.360
Very cool.

00:29:33.360 --> 00:29:37.600
Joe also out there says, what's the most popular database to use with FastAPI?

00:29:37.600 --> 00:29:43.060
Postgres, ExpressJS, Mongo maybe is like another example of a pairing.

00:29:43.060 --> 00:29:43.540
Yeah.

00:29:43.540 --> 00:29:44.360
I would say Postgres.

00:29:44.360 --> 00:29:44.880
Yeah.

00:29:45.080 --> 00:29:49.160
I think generally speaking, you're talking Python, it's Postgres if you're relational,

00:29:49.160 --> 00:29:50.320
MongoDB if you're not.

00:29:50.320 --> 00:29:52.160
That seems to be like the story.

00:29:52.160 --> 00:29:56.140
The important thing here is that you may care about async and await.

00:29:56.140 --> 00:30:00.700
So then that limits the way in which you can talk to the things, but both Postgres and MongoDB

00:30:00.700 --> 00:30:02.500
have really good async stories.

00:30:02.500 --> 00:30:04.980
So I think that still holds for FastAPI.

00:30:04.980 --> 00:30:09.060
Does SQLite have any sort, like, I don't know if you know this offhand, if SQLite has any

00:30:09.060 --> 00:30:10.200
sort of async support?

00:30:10.320 --> 00:30:15.520
It doesn't, I don't think the real way you access it has important behaviors that are

00:30:15.520 --> 00:30:21.300
any different, but there's a new driver that allows it to integrate with an async event

00:30:21.300 --> 00:30:22.440
loop, asyncio event loop.

00:30:22.440 --> 00:30:26.980
So it won't block the loop, but basically it just means there's another thread waiting and

00:30:26.980 --> 00:30:30.640
you won't get like true scalability, but at least like you're waiting on a query here

00:30:30.640 --> 00:30:33.820
and an external API there, they can both happen at the same time.

00:30:33.820 --> 00:30:36.200
But if you have a bunch of database calls, I think it just queues up.

00:30:36.200 --> 00:30:36.820
Yeah.

00:30:36.820 --> 00:30:37.360
Cool.

00:30:37.360 --> 00:30:38.000
All right.

00:30:38.000 --> 00:30:44.460
So Portis Orem, useful because down here somewhere we probably have an await, I'm guessing.

00:30:44.460 --> 00:30:46.400
Oh, here's the, you asked about the SQLite.

00:30:46.400 --> 00:30:47.620
Here's the SQLite library.

00:30:47.620 --> 00:30:51.140
aiosqlite is the one that Mike Bayer was recommending.

00:30:51.140 --> 00:30:51.540
Yeah.

00:30:51.540 --> 00:30:57.740
But down here you can do, you know, await, create object, await, filter, object.first,

00:30:57.740 --> 00:31:01.920
exactly what you want for simple access to those APIs.

00:31:01.920 --> 00:31:02.400
Yeah.

00:31:02.400 --> 00:31:06.000
I mean, if you're just doing like a quick select or delete or whatever it is, you're probably

00:31:06.000 --> 00:31:07.740
not going to get any sort of performance boost.

00:31:07.740 --> 00:31:10.760
But if you're doing for whatever reason, if you're doing a lot of different queries in

00:31:10.760 --> 00:31:14.780
a route handler that are not dependent on each other, or if you're like, you're doing more

00:31:14.780 --> 00:31:17.200
than one query that is very expensive.

00:31:17.200 --> 00:31:17.640
Yeah.

00:31:17.640 --> 00:31:18.980
That's also not dependent on each other.

00:31:18.980 --> 00:31:20.840
Then you might get a performance boost like this.

00:31:20.840 --> 00:31:23.960
Basically the worse your database is, the better.

00:31:23.960 --> 00:31:26.100
Yeah, there you go.

00:31:26.100 --> 00:31:27.780
The more of a benefit you're going to get.

00:31:27.780 --> 00:31:31.440
Because async await is all about scaling, weighting, and latency.

00:31:31.440 --> 00:31:37.240
So the more latency your database has, because you're doing slow queries or it's like cloud

00:31:37.240 --> 00:31:38.860
and far away or whatever, you're going to benefit.

00:31:38.860 --> 00:31:42.060
But if it's a one millisecond response time, who knows?

00:31:42.060 --> 00:31:42.460
All right.

00:31:42.460 --> 00:31:44.980
You also mentioned Gino, G-I-N-O.

00:31:44.980 --> 00:31:47.020
This is like literally the first time I'm seeing it.

00:31:47.020 --> 00:31:47.500
What is this?

00:31:47.500 --> 00:31:47.880
Yeah.

00:31:47.880 --> 00:31:52.480
So Gino is from what I understand, it's more of like a full ecosystem.

00:31:52.760 --> 00:31:53.000
Okay.

00:31:53.000 --> 00:31:57.040
So Gino is not ORM, it's like asynchronous ORM.

00:31:57.040 --> 00:32:02.420
So, but yeah, I mean, it is an ORM, but it also like, I believe there's a generator in

00:32:02.420 --> 00:32:08.600
here where you can build like a scaffold out an entire like FastAPI app, sort of like based

00:32:08.600 --> 00:32:09.600
on your models.

00:32:09.600 --> 00:32:09.880
Yeah.

00:32:09.880 --> 00:32:10.280
Interesting.

00:32:10.280 --> 00:32:13.080
Similar to like how the Rails like skeleton command works.

00:32:13.080 --> 00:32:14.500
I don't know if you're familiar with that at all.

00:32:14.500 --> 00:32:16.520
You can like scaffold out like a quick CRUD app.

00:32:16.520 --> 00:32:17.220
Okay, cool.

00:32:17.220 --> 00:32:19.360
And it's one of these recursive acronyms.

00:32:19.360 --> 00:32:20.300
Yeah, it is.

00:32:20.300 --> 00:32:20.540
Yeah.

00:32:20.620 --> 00:32:23.880
It talks about having an async API on top of SQLAlchemy.

00:32:23.880 --> 00:32:26.880
I wonder how much importance that will have these days.

00:32:26.880 --> 00:32:28.880
But yeah, it sounds like it has other stuff.

00:32:28.880 --> 00:32:30.560
Like you talked about the whole community and stuff.

00:32:30.560 --> 00:32:31.280
So very cool.

00:32:31.280 --> 00:32:34.140
What else is in here that we should talk about?

00:32:34.140 --> 00:32:36.420
There's a couple other ORMs people can look at.

00:32:36.420 --> 00:32:37.280
Query builders.

00:32:37.280 --> 00:32:39.080
I've used databases quite a bit.

00:32:39.080 --> 00:32:39.440
Okay.

00:32:39.440 --> 00:32:42.120
One difficult thing about databases is Googling.

00:32:42.120 --> 00:32:46.640
It is like, if you try and Google any sort of like errors around databases, it's, you

00:32:46.640 --> 00:32:48.340
know, like knows what's going to come up.

00:32:48.340 --> 00:32:50.380
But yeah, I mean, this is like one that's...

00:32:50.380 --> 00:32:53.640
Was this originally done by Kenneth Wright and then handed off?

00:32:53.640 --> 00:32:54.640
Or is this different?

00:32:54.640 --> 00:32:55.540
You know, I'm not sure.

00:32:55.540 --> 00:32:58.860
I think it's by the same team that does Starlet.

00:32:58.860 --> 00:32:59.300
Yeah.

00:32:59.300 --> 00:32:59.640
Yeah.

00:32:59.640 --> 00:32:59.920
Yeah.

00:32:59.920 --> 00:33:00.400
Tom Christie.

00:33:00.400 --> 00:33:01.600
That's escaped me there.

00:33:01.600 --> 00:33:01.800
Yeah.

00:33:01.800 --> 00:33:02.220
Yeah.

00:33:02.220 --> 00:33:02.580
Yeah.

00:33:02.580 --> 00:33:02.940
Definitely.

00:33:02.940 --> 00:33:03.360
Cool.

00:33:03.360 --> 00:33:04.800
He does a lot of stuff.

00:33:04.800 --> 00:33:05.100
Yeah.

00:33:05.100 --> 00:33:05.780
That guy's busy.

00:33:05.780 --> 00:33:06.900
I've had him on the show before.

00:33:06.900 --> 00:33:08.000
He's definitely a busy guy.

00:33:08.000 --> 00:33:08.960
That's awesome.

00:33:08.960 --> 00:33:09.440
Cool.

00:33:09.520 --> 00:33:14.220
So it's like a wrapper around SQLAlchemy core that then will give you back proper queries

00:33:14.220 --> 00:33:14.940
and stuff like that.

00:33:14.940 --> 00:33:15.420
Yeah.

00:33:15.420 --> 00:33:16.100
Nice.

00:33:16.100 --> 00:33:16.760
Okay.

00:33:16.760 --> 00:33:17.580
ODMs.

00:33:17.580 --> 00:33:19.000
Just really quick mentions.

00:33:19.000 --> 00:33:22.780
Since I was recently talking about Beanie on Python Bytes.

00:33:22.780 --> 00:33:23.560
Beanie is kind of cool.

00:33:23.880 --> 00:33:29.460
It's an async way to talk to MongoDB, an ODM, object document mapper, because there's no

00:33:29.460 --> 00:33:30.060
relations.

00:33:30.060 --> 00:33:30.780
Not really.

00:33:30.780 --> 00:33:34.040
But what's interesting about that is it's one, it has an async option.

00:33:34.040 --> 00:33:35.820
And two, it's all about Pydantic.

00:33:35.820 --> 00:33:39.380
So you're normally you'd have like Django models or SQLAlchemy models.

00:33:39.540 --> 00:33:44.600
Like the models are Pydantic models that go to and from the database, which has an interesting

00:33:44.600 --> 00:33:48.520
possibility for integration back into the like return types and stuff that you would

00:33:48.520 --> 00:33:50.880
have, say for a FastAPI.

00:33:50.880 --> 00:33:54.560
So anyway, that's if you're into it, that's potentially worth checking out.

00:33:54.560 --> 00:33:58.220
It's based on Motor, which is the MongoDB official async driver for Python.

00:33:58.220 --> 00:33:58.720
Yeah.

00:33:58.720 --> 00:34:03.240
The PR for that one came out, I think last week and I heard about it maybe the week before.

00:34:03.240 --> 00:34:05.340
So I don't know if that's like a new library, Beanie, but.

00:34:05.340 --> 00:34:06.080
Yeah.

00:34:06.080 --> 00:34:09.240
It's quite new because I was talking to Roman Reyes.

00:34:09.240 --> 00:34:13.220
This is a guy who created this and when he did some stuff on it, I talked about how

00:34:13.220 --> 00:34:17.340
I thought it was really cool to be using Pydantic models and types, but it needs indexes.

00:34:17.340 --> 00:34:22.320
And so he actually went and put a whole mechanism in for doing indexes.

00:34:22.320 --> 00:34:23.360
I got to check them out.

00:34:23.360 --> 00:34:27.600
I guess that's just the example, but whole way in which you can put indexes in your models

00:34:27.600 --> 00:34:28.140
and stuff.

00:34:28.140 --> 00:34:28.540
Yeah.

00:34:28.540 --> 00:34:29.840
MongoDB index is perfect.

00:34:29.840 --> 00:34:32.860
So pretty cool that it has that stuff built in.

00:34:32.860 --> 00:34:35.180
And yeah, it looks like it's coming on strong.

00:34:35.180 --> 00:34:36.100
So maybe that's a good one.

00:34:36.100 --> 00:34:38.940
Mongo engine is actually what I use over at Talk Python, but I don't believe it.

00:34:38.940 --> 00:34:39.700
I don't believe it's async.

00:34:39.700 --> 00:34:41.740
I have suspicions that will never be async.

00:34:41.740 --> 00:34:45.440
It's super, super involved and it doesn't seem to be changing real quickly.

00:34:45.440 --> 00:34:47.540
So I'm guessing that that's kind of where it is.

00:34:47.540 --> 00:34:49.840
Have you checked out this Pydantic SQLAlchemy?

00:34:49.840 --> 00:34:51.420
Pydantic to SQLAlchemy?

00:34:51.420 --> 00:34:52.300
I haven't, no.

00:34:52.300 --> 00:34:55.400
Tools to convert SQLAlchemy models to Pydantic models.

00:34:55.400 --> 00:34:59.580
Like I just talked about the benefits of having your database models be Pydantic so they can

00:34:59.580 --> 00:35:00.620
be on the boundaries, right?

00:35:00.620 --> 00:35:00.980
Yeah.

00:35:01.240 --> 00:35:03.920
And maybe this is just like a way to sort of map those over.

00:35:03.920 --> 00:35:04.480
That's kind of cool.

00:35:04.480 --> 00:35:05.420
Yeah, that is cool.

00:35:05.420 --> 00:35:05.900
I did.

00:35:05.900 --> 00:35:09.780
When I looked at this earlier, one thing I wasn't psyched about, I'd be interested to hear your

00:35:09.780 --> 00:35:10.500
thoughts on this, Michael.

00:35:10.500 --> 00:35:13.420
The way that it does this is at runtime, right?

00:35:13.500 --> 00:35:17.360
So the way you get your SQLAlchemy model, you say, now I'm going to create a Pydantic

00:35:17.360 --> 00:35:22.380
user from my user by passing it to a function that does probably magic metaprogramming and

00:35:22.380 --> 00:35:25.180
boom, out comes this type Pydantic user, right?

00:35:25.180 --> 00:35:25.920
And that's cool.

00:35:25.920 --> 00:35:32.100
But one thing I don't like about that style is the editors can't be very smart about helping

00:35:32.100 --> 00:35:32.580
you, right?

00:35:32.580 --> 00:35:37.900
Like it doesn't know what the heck a Pydantic user can do or can be or autocomplete and

00:35:37.900 --> 00:35:38.880
all that sort of stuff.

00:35:38.880 --> 00:35:43.380
So I feel like a lot of these sort of runtime converter things, I don't know.

00:35:43.440 --> 00:35:46.100
They let the good editors like PyCharm and VS Code down.

00:35:46.100 --> 00:35:46.620
What do you think?

00:35:46.620 --> 00:35:47.100
Yeah.

00:35:47.100 --> 00:35:50.420
I mean, is there a way to look at what it'll convert that down to?

00:35:50.420 --> 00:35:52.900
It'd be great if you could get it to like spit out.

00:35:52.900 --> 00:35:53.460
Yeah.

00:35:53.460 --> 00:35:54.300
The actual model.

00:35:54.300 --> 00:35:55.380
A code file.

00:35:55.380 --> 00:35:57.660
You run this one time and then you're like, we're good.

00:35:57.660 --> 00:35:58.000
Yeah.

00:35:58.000 --> 00:35:58.480
We're good.

00:35:58.480 --> 00:36:03.740
I just want a way to go from 20 SQLAlchemy models to 20 Pydantic models and then I'm

00:36:03.740 --> 00:36:06.160
going to save that code and go with it or something like that would be cool.

00:36:06.160 --> 00:36:07.260
But I didn't know.

00:36:07.260 --> 00:36:09.560
It must be cached sort of at some point.

00:36:09.560 --> 00:36:09.880
So.

00:36:09.880 --> 00:36:10.380
Yeah.

00:36:10.380 --> 00:36:11.040
Yeah.

00:36:11.040 --> 00:36:11.700
That's interesting.

00:36:11.700 --> 00:36:12.240
Yeah.

00:36:12.320 --> 00:36:15.380
I do think it's really powerful though, but it's just like, yeah, it's a little tricky

00:36:15.380 --> 00:36:16.680
to get help with what you're supposed to do.

00:36:16.680 --> 00:36:16.860
Right.

00:36:16.860 --> 00:36:19.340
Because otherwise you have two different like model concepts.

00:36:19.340 --> 00:36:22.100
Like you have your model, like your database model, which is SQLAlchemy.

00:36:22.100 --> 00:36:24.860
And then you have like sort of like your model, which is more of like a schema.

00:36:24.860 --> 00:36:25.240
Yeah.

00:36:25.240 --> 00:36:26.680
But Pydantic calls them models.

00:36:26.680 --> 00:36:30.640
And so like in my FastAPI code, I call them schemas.

00:36:31.020 --> 00:36:32.700
So I have like a schemas.py file.

00:36:32.700 --> 00:36:35.180
And then I have a models.py file, which is the flask.

00:36:35.180 --> 00:36:35.560
Sorry.

00:36:35.560 --> 00:36:36.700
I keep saying flask.

00:36:36.700 --> 00:36:37.500
But the.

00:36:37.500 --> 00:36:38.700
I know.

00:36:38.700 --> 00:36:39.280
I was doing it too.

00:36:39.280 --> 00:36:42.800
It's so hard because they're the same size word and they play a very similar role.

00:36:42.800 --> 00:36:42.940
Yeah.

00:36:42.940 --> 00:36:43.400
Yeah.

00:36:43.400 --> 00:36:43.920
Yeah.

00:36:43.920 --> 00:36:46.900
Are they sponsoring this?

00:36:46.900 --> 00:36:48.620
Yeah.

00:36:48.620 --> 00:36:51.060
Just having them combined together, like would make sense.

00:36:51.060 --> 00:36:54.540
But yeah, I get what you're saying about like, you don't know exactly what that is.

00:36:54.540 --> 00:36:55.880
Like until like at runtime.

00:36:55.880 --> 00:36:56.460
Yeah.

00:36:56.460 --> 00:36:59.760
If I go to one of those and say dot, it's like, it gives me nothing.

00:36:59.760 --> 00:37:00.200
Right.

00:37:00.200 --> 00:37:00.560
Yeah.

00:37:00.560 --> 00:37:01.040
Yeah.

00:37:01.040 --> 00:37:01.320
Cool.

00:37:01.320 --> 00:37:01.740
Yeah.

00:37:01.740 --> 00:37:05.660
So Joe out there in the live stream says, what would you recommend as a DB driver instead

00:37:05.660 --> 00:37:08.920
of psycopg two for Postgres and FastAPI?

00:37:08.920 --> 00:37:10.060
You got a recommendation?

00:37:10.060 --> 00:37:13.800
Well, like if you're using synchronous, you want to go psycopg two, obviously.

00:37:13.800 --> 00:37:15.880
But if you're using the async, then it's going to be asyncpg.

00:37:15.880 --> 00:37:16.460
Yeah.

00:37:16.460 --> 00:37:18.040
So there's a separate async one.

00:37:18.460 --> 00:37:18.740
Very cool.

00:37:18.740 --> 00:37:19.140
All right.

00:37:19.140 --> 00:37:21.340
Let's talk about, did I just bag on code generators?

00:37:21.340 --> 00:37:22.360
Let's talk about code generators.

00:37:22.360 --> 00:37:24.160
Okay.

00:37:24.160 --> 00:37:25.940
Because they are valuable.

00:37:25.940 --> 00:37:30.400
One of the things that's super cool, like here I have a, here's a little site I built for

00:37:30.400 --> 00:37:35.120
a course, weather.talkpython.fm that lets you go and enter a city and it'll tell you literally

00:37:35.120 --> 00:37:36.240
the real weather right now.

00:37:36.240 --> 00:37:40.640
Like for now in Portland, it's broken clouds within like a few moments.

00:37:40.640 --> 00:37:40.880
Right.

00:37:40.880 --> 00:37:41.700
That's cool.

00:37:41.700 --> 00:37:44.460
And one of the things that's really nice though, with all these things is you can go to slash

00:37:44.460 --> 00:37:47.460
docs and you get this cool documentation thing.

00:37:47.620 --> 00:37:52.500
And that's just where like your Pydantic model kicks in for the JSON schema response and

00:37:52.500 --> 00:37:53.320
all those cool things.

00:37:53.320 --> 00:37:53.580
Right.

00:37:53.580 --> 00:37:55.180
So that's just FastAPI.

00:37:55.180 --> 00:37:55.760
That's amazing.

00:37:55.760 --> 00:37:58.920
But the next thing is the FastAPI code generator.

00:37:58.920 --> 00:37:59.260
Right.

00:37:59.500 --> 00:38:04.940
So this takes an open API file and then it'll scaffold out your FastAPI app based on that.

00:38:04.940 --> 00:38:07.420
And so does that do all like the Pydantic models and whatnot?

00:38:07.420 --> 00:38:09.540
I'm not sure if it does.

00:38:09.540 --> 00:38:11.040
Or does it just do the endpoints?

00:38:11.040 --> 00:38:12.180
It seems like it.

00:38:12.180 --> 00:38:13.840
It says the response model is pets.

00:38:13.840 --> 00:38:14.580
I think so.

00:38:14.580 --> 00:38:16.200
From the models import pets.

00:38:16.200 --> 00:38:16.380
Yeah.

00:38:16.460 --> 00:38:16.600
Yeah.

00:38:16.600 --> 00:38:20.380
So you pointed at that documentation, that slash docs that I was just talking about.

00:38:20.380 --> 00:38:23.160
And you say, here's some API specification.

00:38:23.160 --> 00:38:25.980
I want a FastAPI server implementation of that.

00:38:25.980 --> 00:38:26.440
Boom.

00:38:26.440 --> 00:38:27.540
And you get it, right?

00:38:27.540 --> 00:38:30.040
So you can sort of do like the document driven development.

00:38:30.040 --> 00:38:34.220
So then if you want to change your API, you change the open API doc.

00:38:34.540 --> 00:38:34.860
Exactly.

00:38:34.860 --> 00:38:35.140
Yeah.

00:38:35.140 --> 00:38:40.100
You can see right here, it is actually generating the Pydantic models and even the errors that

00:38:40.100 --> 00:38:40.860
it throws and so on.

00:38:40.860 --> 00:38:41.620
This is super cool.

00:38:41.620 --> 00:38:46.580
It even has support for say optional strings and default values versus non-optional strings.

00:38:46.580 --> 00:38:47.300
I like it.

00:38:47.300 --> 00:38:47.720
That's cool.

00:38:47.720 --> 00:38:51.600
I'm not sure I would use it because I don't find myself in a situation where I have that

00:38:51.600 --> 00:38:51.860
a lot.

00:38:51.860 --> 00:38:54.700
But if you wanted to do it, it seems like it would be really cool to have.

00:38:54.700 --> 00:38:55.220
All right.

00:38:55.220 --> 00:38:58.060
Related to that is the other side of the story.

00:38:58.060 --> 00:39:00.740
I want to talk to an existing FastAPI.

00:39:00.740 --> 00:39:04.500
Probably this would work for any open API thing, I would guess.

00:39:04.580 --> 00:39:07.020
But it says it's for FastAPI.

00:39:07.020 --> 00:39:12.800
So generate a mypy and IDE friendly API client from an open API spec.

00:39:12.800 --> 00:39:13.800
This looks cool.

00:39:13.800 --> 00:39:15.260
Let's see some examples down here.

00:39:15.260 --> 00:39:17.960
It both supports async and synchronous clients.

00:39:17.960 --> 00:39:23.240
And I'm guessing it's using the similar example model because we have a pet here as well.

00:39:23.240 --> 00:39:26.980
So it generates the model, the Pydantic model that you're going to exchange with the server

00:39:26.980 --> 00:39:27.800
and all sorts of stuff.

00:39:27.800 --> 00:39:28.420
This is cool.

00:39:28.420 --> 00:39:30.220
So what does this generate exactly?

00:39:30.220 --> 00:39:32.620
It's generating a client library to interact with the API?

00:39:32.620 --> 00:39:33.180
Yeah.

00:39:33.360 --> 00:39:39.120
So instead of using requests to call the API and just putting bare dictionaries, it will

00:39:39.120 --> 00:39:45.460
actually generate the Pydantic models and it'll give you the API endpoints as functions instead

00:39:45.460 --> 00:39:46.920
of just request this URL.

00:39:46.920 --> 00:39:47.520
Nice.

00:39:47.520 --> 00:39:50.520
Does that give you like Sphinx documentation and all that too?

00:39:50.520 --> 00:39:51.660
I have no idea.

00:39:52.760 --> 00:39:53.720
That would be cool.

00:39:53.720 --> 00:39:54.980
Yeah.

00:39:54.980 --> 00:39:55.860
It's super cool though.

00:39:55.860 --> 00:39:58.440
It shows you how to basically take all that stuff and generate those.

00:39:58.440 --> 00:40:01.580
And it does say that it generates IDE friendly ones.

00:40:01.580 --> 00:40:06.440
So it must export those and not do it at runtime, which, you know, those pet, you can see right

00:40:06.440 --> 00:40:08.460
here, like from client.models import pet.

00:40:08.460 --> 00:40:13.520
So it generates the Python files and then you consume them instead of at runtime so that you

00:40:13.520 --> 00:40:16.100
get like autocomplete and type check in and all that.

00:40:16.100 --> 00:40:16.520
That's cool.

00:40:16.520 --> 00:40:16.840
Yeah.

00:40:16.840 --> 00:40:23.220
Teddy out here on the live stream says, what use case would you use FastAPI versus say Django

00:40:23.220 --> 00:40:24.280
REST framework?

00:40:24.280 --> 00:40:25.800
It's kind of hard to compare the two.

00:40:25.800 --> 00:40:29.280
I mean, if you're already using Django, then yeah, obviously go with Django REST framework.

00:40:29.280 --> 00:40:36.000
But yeah, in terms of Django plus Django REST framework versus FastAPI, as always, it depends.

00:40:36.000 --> 00:40:37.660
It just depends on what you're doing.

00:40:37.660 --> 00:40:39.140
It depends on the size of the API.

00:40:39.140 --> 00:40:40.720
It depends on if you need authentication.

00:40:40.720 --> 00:40:44.780
It depends if you want like the CRUD admin, you know, type stuff.

00:40:44.780 --> 00:40:48.140
It depends on what tools you're going to be using to consume the API.

00:40:48.140 --> 00:40:52.000
You know, if you want something that's tried and true and battle tested, I would go with Django

00:40:52.000 --> 00:40:52.980
and Django REST framework.

00:40:52.980 --> 00:40:57.940
If you want to play around with the new hotness and take advantage of, you know, you sync and await

00:40:57.940 --> 00:41:01.720
and all the cool stuff that's coming out, then maybe check out FastAPI.

00:41:01.720 --> 00:41:06.140
Yeah, I would certainly say if you already have Django and you're already using it and

00:41:06.140 --> 00:41:10.040
just want to plug into the same app and just keep rolling, probably just Django REST framework,

00:41:10.040 --> 00:41:10.340
right?

00:41:10.340 --> 00:41:14.540
Unless you really want to commit to having multiple apps that you run separately and I don't

00:41:14.540 --> 00:41:17.880
know, put behind Nginx through URL routing or something like that.

00:41:17.880 --> 00:41:21.820
Also, you know, how much of the FastAPI features are you going to use, right?

00:41:21.820 --> 00:41:25.120
If you don't care about async and await and you don't care about the typing very much and

00:41:25.120 --> 00:41:27.000
you don't care about the documentation, like, well,

00:41:27.440 --> 00:41:28.520
then it kind of comes down.

00:41:28.520 --> 00:41:32.400
But if like all of those things are super important to you, maybe breaking that out matters.

00:41:32.400 --> 00:41:32.780
I don't know.

00:41:32.780 --> 00:41:33.980
That's kind of my thought as well.

00:41:33.980 --> 00:41:34.300
Yeah.

00:41:34.300 --> 00:41:38.680
Also, Galvin Haas asks, best JS front-end framework for FastAPI?

00:41:38.680 --> 00:41:39.980
I mean, it's kind of open, right?

00:41:39.980 --> 00:41:42.600
But is there anything that stands out as better?

00:41:42.600 --> 00:41:43.120
No.

00:41:43.120 --> 00:41:46.340
I mean, it works well with Vue, React, Angular.

00:41:46.340 --> 00:41:48.840
Vue.js because it's Vue.js.

00:41:48.840 --> 00:41:51.040
Cool.

00:41:51.040 --> 00:41:51.360
All right.

00:41:51.360 --> 00:41:55.380
Another one here I want to talk about that's super neat is FastAPI Profiler.

00:41:55.380 --> 00:41:56.400
This looks really cool.

00:41:56.540 --> 00:41:57.840
So it's middleware.

00:41:57.840 --> 00:42:01.740
I mean, Ian, you're the Django expert, certainly for the two of us here.

00:42:01.740 --> 00:42:02.680
Tell me how it works.

00:42:02.680 --> 00:42:06.060
I know in Pyramid, there's a debug toolbar you can turn on.

00:42:06.060 --> 00:42:08.800
And then one of the parts of that is show me the profile.

00:42:08.800 --> 00:42:12.080
Like when I request this page, where was my time spent?

00:42:12.080 --> 00:42:16.100
Show me my SQLAlchemy queries actually interlaced in there and so on, which is super cool.

00:42:16.100 --> 00:42:17.440
Django has something like that, right?

00:42:17.680 --> 00:42:17.820
Yeah.

00:42:17.820 --> 00:42:19.240
Django has Django debug toolbar.

00:42:19.240 --> 00:42:19.640
Yeah.

00:42:19.640 --> 00:42:20.700
You had said it does.

00:42:20.700 --> 00:42:30.540
Basically, that works with your service side templating to figure out with that specific template or with that specific route, how many different queries did it take to load this view?

00:42:30.540 --> 00:42:30.880
Right.

00:42:30.880 --> 00:42:38.660
Find if you got the N plus one problem because you passed this thing and then you're all over touching the lazy loaded properties over and over and over.

00:42:38.660 --> 00:42:39.620
Something like that, right?

00:42:39.680 --> 00:42:43.180
It's not going to detect N plus one issues for you, but you should be able to see them.

00:42:43.180 --> 00:42:43.540
Yeah.

00:42:43.540 --> 00:42:46.960
If you're like, why do I have a hundred queries on this page instead of two?

00:42:46.960 --> 00:42:49.060
Like that should jump out at you, right?

00:42:49.060 --> 00:42:49.520
Yeah.

00:42:49.520 --> 00:42:50.000
Yeah.

00:42:50.000 --> 00:42:52.700
So this is, I'm guessing like that.

00:42:52.700 --> 00:42:53.040
Yeah.

00:42:53.040 --> 00:42:58.680
I wonder where the output prints out at because like with FastAPI, I usually don't have the server side templating with it.

00:42:58.680 --> 00:42:58.980
So.

00:42:58.980 --> 00:42:59.480
Exactly.

00:42:59.480 --> 00:43:00.460
By default, you don't.

00:43:00.460 --> 00:43:02.400
Is this like just print out to the terminal or.

00:43:02.400 --> 00:43:02.760
Yeah.

00:43:02.760 --> 00:43:05.440
It's worth pointing out that FastAPI does support Jinja.

00:43:05.440 --> 00:43:05.860
Yeah.

00:43:05.860 --> 00:43:08.040
But you got to do a little extra work to make it do it.

00:43:08.040 --> 00:43:12.760
So it says, this is really like a leveraging PI instrument from Joe Rick.

00:43:12.760 --> 00:43:17.900
And if you scroll down over on their repo, on his repo, there's a bunch of cool output.

00:43:17.900 --> 00:43:20.360
I think it might even open up.

00:43:20.360 --> 00:43:21.020
I don't know.

00:43:21.020 --> 00:43:22.500
I'm not sure exactly where it goes.

00:43:22.500 --> 00:43:22.780
It might.

00:43:22.780 --> 00:43:24.860
I think it saves it to like a profile file.

00:43:24.860 --> 00:43:28.260
So you get this like cool little view of like the profile output here.

00:43:28.260 --> 00:43:33.980
Even there's like a terminal version, which is, I don't know, like a rich colored terminal version.

00:43:33.980 --> 00:43:36.320
But there's a bunch of cool graphs and stuff you can get.

00:43:36.320 --> 00:43:41.340
There's a, I think I saw in here somewhere you can open up some kind of like flame graph as well.

00:43:41.340 --> 00:43:42.160
Oh, that's cool.

00:43:42.160 --> 00:43:42.680
Yeah.

00:43:42.680 --> 00:43:43.840
You can dig into it.

00:43:43.840 --> 00:43:46.080
So basically anything you can do with PI instrument.

00:43:46.080 --> 00:43:53.500
I think this is just a middleware wrapper that generates PI instrument stuff for you, which is, that's pretty cool.

00:43:53.500 --> 00:43:53.860
Yeah.

00:43:53.860 --> 00:43:54.900
A lot of stuff is super powerful.

00:43:54.900 --> 00:44:01.500
Like you could probably take some of that stuff and tie it into your integration type test to ensure that, hey, like I built this route.

00:44:01.500 --> 00:44:03.520
This view takes X amount of time.

00:44:03.520 --> 00:44:06.840
And like, you know, now I want to throw junior developer on my code.

00:44:06.840 --> 00:44:09.580
I want to make sure, hey, there's not like any performance loss.

00:44:09.580 --> 00:44:15.760
And you can like use like some stuff like that to make sure that the number of queries don't all of a sudden triple.

00:44:15.760 --> 00:44:19.160
Like the load time doesn't all of a sudden triple stuff like that.

00:44:19.160 --> 00:44:22.840
So tying like that stuff into your test suite is like super powerful.

00:44:23.100 --> 00:44:26.580
I do that with, there's a library called N plus one that does that very same thing.

00:44:26.580 --> 00:44:27.360
Oh, interesting.

00:44:27.360 --> 00:44:27.820
Yeah.

00:44:27.820 --> 00:44:28.060
Yeah.

00:44:28.060 --> 00:44:28.440
Very cool.

00:44:28.440 --> 00:44:29.080
Nice.

00:44:29.080 --> 00:44:29.800
Heard of it.

00:44:29.800 --> 00:44:30.480
I haven't used it.

00:44:30.480 --> 00:44:34.020
Another one I think that stands out is pretty interesting is FastAPI mail.

00:44:34.020 --> 00:44:37.880
I mean, boring, but sending mail is one of those things that can take forever.

00:44:37.880 --> 00:44:41.400
Like I had one of these admin parts of my site.

00:44:41.400 --> 00:44:44.360
I had a way to like send an email to all the people in this class.

00:44:44.360 --> 00:44:47.900
Go 20 seconds, 30 seconds timed out.

00:44:47.900 --> 00:44:50.320
And it was going to like thousands of people.

00:44:50.320 --> 00:44:55.460
And the problem was it had sent hundreds of emails and then it timed out.

00:44:55.460 --> 00:44:59.540
So how do I resend that without sending a duplicate to the first half?

00:44:59.540 --> 00:45:00.040
Right.

00:45:00.040 --> 00:45:01.420
Maintaining the state there.

00:45:01.420 --> 00:45:01.800
Yeah.

00:45:01.800 --> 00:45:02.400
Yeah.

00:45:02.400 --> 00:45:06.340
And like, I don't really, like, it's really hard to go back to figure out everyone who got it, but not.

00:45:06.340 --> 00:45:07.640
Anyway, it was a huge pain.

00:45:07.640 --> 00:45:09.760
And I'm like, okay, sending a lot of emails kind of sucks.

00:45:09.760 --> 00:45:16.160
And so this one FastAPI mail is cool because email is one of those things that's like dreadfully slow.

00:45:16.160 --> 00:45:20.160
And this allows you to asynchronously send email messages in a super simple way.

00:45:20.560 --> 00:45:23.620
So you're not using like SendGrid or SES or anything to?

00:45:23.620 --> 00:45:26.400
At the time, I was using SES at the time.

00:45:26.400 --> 00:45:26.640
Yeah.

00:45:26.640 --> 00:45:27.040
Okay.

00:45:27.040 --> 00:45:27.420
Okay.

00:45:27.420 --> 00:45:30.000
But I was doing it instead of like doing a bulk send.

00:45:30.000 --> 00:45:30.500
Yeah.

00:45:30.500 --> 00:45:33.020
I said, this is a customized email to that person.

00:45:33.020 --> 00:45:34.280
This is a customized email to that person.

00:45:34.280 --> 00:45:38.980
And like, I mean, it's fine if I even just set the timeout limit longer or whatever.

00:45:38.980 --> 00:45:39.820
It would have been fine.

00:45:39.820 --> 00:45:43.120
What I ended up doing is just putting that in a background queue and just let it go.

00:45:43.220 --> 00:45:44.240
Like that's how it should have been.

00:45:44.240 --> 00:45:48.700
It shouldn't have been as part of the request, but I learned the hard way the first time around.

00:45:48.700 --> 00:45:50.320
I use Celery for that same exact thing.

00:45:50.320 --> 00:45:51.660
I mean, that just goes right to queue.

00:45:51.660 --> 00:45:51.940
Yeah.

00:45:51.940 --> 00:45:52.300
Perfect.

00:45:52.300 --> 00:45:52.600
Yeah.

00:45:52.600 --> 00:45:54.220
So this one has an async.

00:45:54.220 --> 00:45:59.180
This makes, I mean, like you said, doing bulk sending on some kind of background thing is

00:45:59.180 --> 00:46:00.060
exactly what you should do.

00:46:00.120 --> 00:46:05.000
But if you're trying to not block your processing and you want to send an email, just one, like,

00:46:05.000 --> 00:46:06.300
Hey, reset my password, right?

00:46:06.300 --> 00:46:08.080
That could be a thing you could just do right away.

00:46:08.080 --> 00:46:11.700
And so here's a way to await sending emails, which is kind of cool.

00:46:11.700 --> 00:46:12.120
Yeah.

00:46:12.120 --> 00:46:16.080
If you don't really care too much about what happens to the email, like if you're not too

00:46:16.080 --> 00:46:18.700
concerned about, Hey, if this doesn't get delivered, it's not a huge deal.

00:46:18.700 --> 00:46:20.760
I'd say like something like this is fine.

00:46:20.760 --> 00:46:24.780
If it's more like, you know, there's like any sort of like workflow based on what could

00:46:24.780 --> 00:46:27.380
happen there, like success, failure, that sort of thing.

00:46:27.380 --> 00:46:29.000
Like if then this, that type stuff.

00:46:29.000 --> 00:46:29.220
Yeah.

00:46:29.220 --> 00:46:33.140
You want to probably look more like towards salary, I would say, but I still think like,

00:46:33.140 --> 00:46:36.920
if you want to send like just a simple one-off email, maybe it's even to yourself or something

00:46:36.920 --> 00:46:37.380
like that.

00:46:37.380 --> 00:46:39.840
I do this like with FastAPI mails.

00:46:39.840 --> 00:46:44.740
I send myself notifications based on events and like, I don't necessarily need them.

00:46:44.740 --> 00:46:46.480
Like, you know, I'm not curing cancer here.

00:46:46.480 --> 00:46:47.880
So if I don't get it, I don't care.

00:46:47.880 --> 00:46:48.280
Yeah.

00:46:48.280 --> 00:46:49.040
I have the same thing.

00:46:49.040 --> 00:46:52.140
I'll just shoot myself messages like, Oh, here's the thing you should probably know about

00:46:52.140 --> 00:46:52.600
that happened.

00:46:52.600 --> 00:46:53.240
Very cool.

00:46:53.240 --> 00:46:53.760
Yeah.

00:46:53.760 --> 00:46:57.040
I have moved to SendGrid last month or two and really like it.

00:46:57.040 --> 00:46:58.280
I don't think that's so big.

00:46:58.320 --> 00:46:58.720
Yeah.

00:46:58.720 --> 00:47:00.400
Come back to normal size.

00:47:00.400 --> 00:47:02.440
So let's see, what else have we got here?

00:47:02.440 --> 00:47:03.160
That's interesting.

00:47:03.160 --> 00:47:06.020
Then we got the obligatory utils.

00:47:06.020 --> 00:47:07.780
The catch all right.

00:47:07.780 --> 00:47:08.300
Everything.

00:47:08.300 --> 00:47:08.560
Yeah.

00:47:08.560 --> 00:47:10.200
Well named helpers.py.

00:47:10.200 --> 00:47:10.980
Exactly.

00:47:12.200 --> 00:47:15.420
So we got socket IO stuff, plugins, pagination.

00:47:15.420 --> 00:47:20.340
One I do, two that I'll call quick attention to that I think is our Nate in here.

00:47:20.340 --> 00:47:24.160
Not, this is not an endorsement or saying I would use it, but I think I can see a real

00:47:24.160 --> 00:47:24.840
interesting use case.

00:47:24.840 --> 00:47:25.720
First, the cache one.

00:47:25.720 --> 00:47:26.320
Yeah.

00:47:26.320 --> 00:47:27.780
Maybe tell us about this cache one here.

00:47:27.980 --> 00:47:28.160
Yeah.

00:47:28.160 --> 00:47:32.100
So I haven't used this one exactly, but it looks like, yeah, it just is probably going

00:47:32.100 --> 00:47:35.280
to probably cache at the route handler level.

00:47:35.280 --> 00:47:41.540
And it looks like it's caching the response based on the request parameters inside of Redis.

00:47:41.800 --> 00:47:41.940
Yeah.

00:47:41.940 --> 00:47:45.440
You know, it's the one thing that's interesting here that it actually does that I haven't

00:47:45.440 --> 00:47:49.800
seen in any of these examples yet, but it's certainly a FastAPI thing is it uses dependency

00:47:49.800 --> 00:47:51.180
injection for the cache.

00:47:51.180 --> 00:47:51.500
Yeah.

00:47:51.500 --> 00:47:51.860
Right.

00:47:51.860 --> 00:47:56.040
So they've got a view method here or API endpoint, I guess, called hello.

00:47:56.040 --> 00:48:01.660
And then one of the parameters is cache of type Redis cache backend equals the default

00:48:01.660 --> 00:48:03.360
values depends on Redis cache.

00:48:03.360 --> 00:48:06.620
So it goes and finds the one instance of that and hands it off.

00:48:06.620 --> 00:48:10.340
And then it's just like standard Redis value type thing.

00:48:10.660 --> 00:48:12.240
Like a wait, get the thing.

00:48:12.240 --> 00:48:13.240
The thing's not there.

00:48:13.240 --> 00:48:17.060
A wait, set the thing, you know, pretty standard, but it's kind of cool.

00:48:17.060 --> 00:48:18.160
It was just the simple integration.

00:48:18.160 --> 00:48:18.680
Yeah.

00:48:18.680 --> 00:48:23.540
Like dependency injection, I think is a, it's a pretty difficult concept if you look at it

00:48:23.540 --> 00:48:29.380
from a theoretical standpoint, but it's just like this object here is just taking this other

00:48:29.380 --> 00:48:31.140
object at runtime, you know, essentially.

00:48:31.140 --> 00:48:32.640
So it's, yeah, yeah.

00:48:32.640 --> 00:48:36.640
It's just a way to like sort of split apart sort of your dependencies and it makes testing

00:48:36.640 --> 00:48:37.360
a whole lot easier.

00:48:37.360 --> 00:48:39.560
So you don't have to have like mocks all over the place.

00:48:39.560 --> 00:48:43.560
So you can just switch out like the Redis cache for like in memory cache or, you know,

00:48:43.560 --> 00:48:44.280
something like that.

00:48:44.280 --> 00:48:44.580
Yeah.

00:48:44.580 --> 00:48:47.740
If you could pass in anything that has a get and a set, you're good.

00:48:47.740 --> 00:48:48.580
Right?

00:48:48.580 --> 00:48:49.140
Yeah.

00:48:50.200 --> 00:48:55.340
I think because of dependency injection, FastAPI, like you don't necessarily have to leverage

00:48:55.340 --> 00:48:59.060
it, but I think that if you are, it does take a little, like you have to be a little bit

00:48:59.060 --> 00:49:02.540
more of a seasoned developer, I'd say than someone that's just picking up Flask.

00:49:02.540 --> 00:49:03.020
Yeah.

00:49:03.020 --> 00:49:04.160
I totally agree about that.

00:49:04.160 --> 00:49:05.900
Dependency injection is one of those things.

00:49:05.900 --> 00:49:06.800
It's like, Oh, this is really cool.

00:49:06.800 --> 00:49:07.680
And it makes things simpler.

00:49:07.680 --> 00:49:09.220
And why is it so complicated?

00:49:09.220 --> 00:49:10.020
What just happened?

00:49:10.020 --> 00:49:11.140
You know?

00:49:11.140 --> 00:49:12.260
And I'm thinking more of like.

00:49:12.260 --> 00:49:15.060
Although I don't know when you start looking at Flask global objects.

00:49:15.340 --> 00:49:15.620
Yeah.

00:49:15.620 --> 00:49:15.900
Yeah.

00:49:15.900 --> 00:49:16.080
Yeah.

00:49:16.080 --> 00:49:16.360
Yeah.

00:49:16.360 --> 00:49:18.100
That's complex.

00:49:18.100 --> 00:49:18.740
That's true.

00:49:18.740 --> 00:49:22.440
I'm thinking more of like the static languages like Java or C#, where you've got an

00:49:22.440 --> 00:49:26.040
I and I and interface one of these, and then a bunch of those registered.

00:49:26.040 --> 00:49:29.940
And then like, which one did it actually like, what concrete type am I even working with?

00:49:29.940 --> 00:49:31.640
Like, like it can get, I don't know.

00:49:31.640 --> 00:49:33.320
People can over pattern it, I guess.

00:49:33.320 --> 00:49:33.740
All right.

00:49:33.740 --> 00:49:35.840
Speaking of not over pattern it, let's check this out.

00:49:35.840 --> 00:49:40.880
So I was talking at the Python at the San Francisco Python meetup last night.

00:49:40.940 --> 00:49:46.100
Someone asked me, Hey, is there a way in FastAPI to just like, no, this was my office hours

00:49:46.100 --> 00:49:47.200
same day though.

00:49:47.200 --> 00:49:48.760
And also video meeting.

00:49:48.760 --> 00:49:52.540
Anyway, somebody said, can I just take a database and make it like an API?

00:49:52.540 --> 00:49:53.380
Yes.

00:49:53.380 --> 00:49:56.180
This FastAPI dash CRUD router.

00:49:56.180 --> 00:49:57.160
It sounds amazing, right?

00:49:57.160 --> 00:50:04.460
So basically what you do is you tell it your models and the schemas, and then it just creates

00:50:04.460 --> 00:50:09.120
all these API endpoints to do restful things to that table through the model.

00:50:09.220 --> 00:50:14.380
So I have a get slash potato, like potato was the model, get slash potato that'll list

00:50:14.380 --> 00:50:14.740
them all.

00:50:14.740 --> 00:50:21.360
Post a potato to slash potato will create one, delete a potato, we'll get rid of all of them,

00:50:21.360 --> 00:50:24.600
delete potato slash ID will delete that one and so on.

00:50:24.600 --> 00:50:31.120
So it just turns this into basically a series of FastAPI endpoints that are all the restful

00:50:31.120 --> 00:50:33.100
behaviors against your schemas.

00:50:33.100 --> 00:50:33.800
What do you think?

00:50:33.800 --> 00:50:35.580
You don't see it delete all very often.

00:50:35.580 --> 00:50:36.160
Nope.

00:50:36.160 --> 00:50:36.960
A little Bobby table.

00:50:36.960 --> 00:50:40.560
I wonder if this is how Gino might be leveraging something similar to this.

00:50:40.560 --> 00:50:40.880
Yeah.

00:50:40.880 --> 00:50:43.180
To me, this feels overexposed.

00:50:43.180 --> 00:50:48.940
But if it's like something simple, something internal, probably, maybe it makes sense to

00:50:48.940 --> 00:50:50.340
just go like, I just need to do that.

00:50:50.340 --> 00:50:52.900
But from JavaScript, we just turn that on.

00:50:52.900 --> 00:50:55.880
But like I said, I probably would not turn that on because it scares me.

00:50:55.880 --> 00:50:57.500
Let's see rate limiting.

00:50:57.620 --> 00:50:59.880
There's a couple of rate limiting things that are cool here.

00:50:59.880 --> 00:51:01.080
Slow API.

00:51:01.080 --> 00:51:03.080
And then what was the other one?

00:51:03.080 --> 00:51:04.080
FastAPI limiter.

00:51:04.080 --> 00:51:04.940
Those are cool.

00:51:04.940 --> 00:51:08.320
And that's pretty much it for the standard docs, right?

00:51:08.320 --> 00:51:09.660
Or standard extensions.

00:51:09.660 --> 00:51:10.920
And we've got the documentation.

00:51:10.920 --> 00:51:15.320
We've got some external resources, like some of the things that you have over at Test Driven.

00:51:15.720 --> 00:51:20.140
The podcasts that you mentioned are somehow someone linked the Python bytes thing I had

00:51:20.140 --> 00:51:21.540
with Sebastian, I believe.

00:51:21.540 --> 00:51:25.200
I'm starting to get to the point with this awesome list where it's like, I'm going to probably

00:51:25.200 --> 00:51:29.920
have to like curate the tutorials a little bit more because there's so many like new tutorials.

00:51:29.920 --> 00:51:32.380
Like when I started this, there were like three or four tutorials.

00:51:32.380 --> 00:51:37.580
And now, you know, there's like hundreds of them just based on the popularity of the framework.

00:51:37.580 --> 00:51:42.240
So getting a little bit smarter with curating the tutorials, like because you don't need 15

00:51:42.240 --> 00:51:45.400
different tutorials, like showing how to build a CRUD app, you know, that sort of thing.

00:51:45.400 --> 00:51:51.740
I did find this FastAPI for Flask users super helpful because what it does, it says, you want

00:51:51.740 --> 00:51:52.580
to do this in Flask.

00:51:52.580 --> 00:51:54.020
Here's the FastAPI version.

00:51:54.020 --> 00:51:55.200
You want to do this in Flask.

00:51:55.200 --> 00:51:56.680
Here's the FastAPI version.

00:51:56.680 --> 00:51:58.200
And it just does like simple stuff.

00:51:58.200 --> 00:52:00.680
Like I want to, let me see if I can find some examples.

00:52:00.880 --> 00:52:03.120
I want to create a method that does post.

00:52:03.120 --> 00:52:04.240
Here's what it looks like there.

00:52:04.240 --> 00:52:09.600
Here's what it looks like in FastAPI and just side by side sort of a cookbook type of thing.

00:52:09.600 --> 00:52:10.620
I like that a lot.

00:52:10.620 --> 00:52:11.880
So yeah, that's a good one.

00:52:11.880 --> 00:52:12.540
All right.

00:52:12.540 --> 00:52:14.440
We're just out a few moments left.

00:52:14.440 --> 00:52:16.240
I don't think we have time to go through all the tutorials.

00:52:16.240 --> 00:52:18.480
And honestly, I haven't researched them enough to talk about it.

00:52:18.480 --> 00:52:20.400
A couple of talks, which is cool.

00:52:20.400 --> 00:52:21.760
A couple of videos.

00:52:21.760 --> 00:52:25.840
Well, I'm sure there's probably some more out there on the internet that could overwhelm your

00:52:25.840 --> 00:52:26.520
list at this point.

00:52:26.520 --> 00:52:28.740
Courses, you and I, we've got to lock on it.

00:52:28.740 --> 00:52:30.860
Yeah, I recognize a few of those names, right?

00:52:31.420 --> 00:52:32.560
Tell us about the courses.

00:52:32.560 --> 00:52:34.380
Exactly, man.

00:52:34.380 --> 00:52:35.700
There's three courses.

00:52:35.700 --> 00:52:37.300
And now let's talk about yours first.

00:52:37.300 --> 00:52:37.700
Yeah.

00:52:37.700 --> 00:52:41.760
So my course focuses on building just a RESTful API.

00:52:41.760 --> 00:52:45.360
It also focuses on heavily, obviously, on test-driven development.

00:52:45.360 --> 00:52:51.740
I also focus on code formatting type tools like Black and Playgate and stuff like that.

00:52:52.200 --> 00:52:55.480
And so I also go into CI, you know, CD with GitHub Actions.

00:52:55.480 --> 00:52:57.080
And then everything is Dockerized.

00:52:57.080 --> 00:52:58.980
And then you also deploy it to Heroku.

00:52:58.980 --> 00:53:00.080
Yeah, super cool.

00:53:00.080 --> 00:53:05.120
And I saw that both you and I are also sponsors of the FastAPI project in GitHub, which is

00:53:05.120 --> 00:53:05.500
pretty cool.

00:53:05.500 --> 00:53:06.400
Yeah, you're gold.

00:53:06.400 --> 00:53:06.900
I'm silver.

00:53:06.900 --> 00:53:09.560
I assume you donate a few more bucks a month then.

00:53:09.560 --> 00:53:10.980
I guess so.

00:53:10.980 --> 00:53:11.480
I guess so.

00:53:11.480 --> 00:53:12.600
But yeah, how does that work?

00:53:12.600 --> 00:53:13.120
Here's the thing.

00:53:13.120 --> 00:53:15.420
I don't call it out to like say, oh, look how cool we are.

00:53:15.420 --> 00:53:17.720
I mean, I do see it on the screen here, which sort of brought it to mind.

00:53:17.780 --> 00:53:22.640
But there's so many companies out there who are building major parts of their businesses

00:53:22.640 --> 00:53:25.120
on top of FastAPI and other projects.

00:53:25.120 --> 00:53:29.600
Like GitHub has such a simple way to go press the sponsor button, support those things and

00:53:29.600 --> 00:53:34.140
make sure they have a nice, vibrant ecosystem, people backing them.

00:53:34.140 --> 00:53:35.820
You know, if we can do it, surely.

00:53:35.820 --> 00:53:40.940
Bank of America, Chase, Microsoft, Google, get in there.

00:53:40.940 --> 00:53:43.020
Anyway, that was more my pitch there.

00:53:43.020 --> 00:53:47.720
Yeah, I think more companies need to like sort of call that just the cost of doing business.

00:53:48.040 --> 00:53:50.780
It's like we're resting on the shoulders of all these giants.

00:53:50.780 --> 00:53:54.380
Like we have this other remote team over here that we know nothing about.

00:53:54.380 --> 00:53:56.320
And yet we're leveraging, you know, this team.

00:53:56.320 --> 00:54:00.820
And not all projects are like curated or maintained by Google and Facebook either.

00:54:00.820 --> 00:54:04.700
And so, yeah, I think it's I'm not trying to like push this in people's face.

00:54:04.700 --> 00:54:05.760
Like, hey, I'm better than you.

00:54:05.760 --> 00:54:10.420
I'm just trying to say, hey, if I can do this, then yeah, I think a lot of companies should

00:54:10.420 --> 00:54:12.980
be thinking more and more about doing stuff like this.

00:54:12.980 --> 00:54:14.080
I totally agree.

00:54:14.080 --> 00:54:15.560
I think they should definitely see.

00:54:16.160 --> 00:54:18.320
We critically depend upon these technologies.

00:54:18.320 --> 00:54:20.680
Let's make sure that we do a little bit to support them.

00:54:20.680 --> 00:54:21.100
Yeah.

00:54:21.100 --> 00:54:24.160
Because a little bit for a lot of these companies would dramatically change it, right?

00:54:24.160 --> 00:54:29.880
If if Flask got two million dollars a year, that would fundamentally change that organization.

00:54:29.880 --> 00:54:33.500
And yet, given how many people use it, it would be nothing to the companies.

00:54:33.500 --> 00:54:35.320
And like it wouldn't even show up almost.

00:54:35.320 --> 00:54:35.620
Right.

00:54:35.620 --> 00:54:40.340
So I know there's a lot of complexity about how companies justify money and where it goes on

00:54:40.340 --> 00:54:41.160
the balance sheet and all that.

00:54:41.200 --> 00:54:43.980
But still, people encourage your companies to do stuff like that.

00:54:43.980 --> 00:54:44.400
All right.

00:54:44.400 --> 00:54:45.660
So this is a really cool course.

00:54:45.660 --> 00:54:48.240
I love the Docker angle of it as well.

00:54:48.240 --> 00:54:49.240
So nice.

00:54:49.240 --> 00:54:49.800
Test driven.

00:54:49.800 --> 00:54:50.520
How's that work?

00:54:50.520 --> 00:54:52.100
What's the story with that part?

00:54:52.100 --> 00:54:53.000
Test driven development?

00:54:53.000 --> 00:54:54.200
Like we're like the site?

00:54:54.200 --> 00:54:57.220
No, I mean, just like, like, how's that plug in with like FastAPI?

00:54:57.220 --> 00:54:59.740
Like, are you doing like this dependency injection type stuff?

00:54:59.980 --> 00:55:03.200
I show I show like I show both like sort of ways how to do tests.

00:55:03.200 --> 00:55:05.100
Like I show like how to mock everything.

00:55:05.100 --> 00:55:08.580
So if you want to like speed like your tests up, but I don't actually go into like all the

00:55:08.580 --> 00:55:11.420
dependency injection type stuff with the ORM.

00:55:11.420 --> 00:55:15.440
It's a little bit too complex, I would say, especially with how Tortoise is set up.

00:55:15.440 --> 00:55:18.860
But yeah, I showed basically two different types of tests.

00:55:18.860 --> 00:55:23.000
Like you can test it sort of like integration, you know, style where it's actually hitting the

00:55:23.000 --> 00:55:27.960
database or like you're using monkey patch to sort of mock out sort of the actual the

00:55:27.960 --> 00:55:28.560
database layer.

00:55:28.560 --> 00:55:30.720
Yeah, that sounds super cool and useful.

00:55:30.720 --> 00:55:35.100
It's also like what differs like between our two courses is like minor text based and yours

00:55:35.100 --> 00:55:36.700
are all video based.

00:55:36.700 --> 00:55:37.720
Yeah, all video based.

00:55:37.720 --> 00:55:38.000
Yes.

00:55:38.000 --> 00:55:38.480
Yeah.

00:55:38.480 --> 00:55:41.500
I mean, there's source code on GitHub that's text, but not really.

00:55:41.500 --> 00:55:43.040
So yours are both then.

00:55:43.040 --> 00:55:43.800
Damn.

00:55:43.800 --> 00:55:45.180
No, no, no, no, no, no.

00:55:45.180 --> 00:55:45.660
Not really.

00:55:45.660 --> 00:55:46.880
It's all video based.

00:55:46.880 --> 00:55:48.740
So I didn't plan this ahead.

00:55:48.740 --> 00:55:51.000
I looked down like, wow, you have my two courses, which is super cool.

00:55:51.000 --> 00:55:54.660
So I have two courses on here, modern APIs with FastAPI.

00:55:54.660 --> 00:56:00.420
And the idea is just like, let's build an API that uses Pydantic, that uses async and await,

00:56:00.420 --> 00:56:02.960
that has real live data, stuff like that.

00:56:02.960 --> 00:56:05.880
And sort of the fundamentals of the FastAPI world.

00:56:06.000 --> 00:56:08.880
And then the other one is full web apps with FastAPI.

00:56:08.880 --> 00:56:14.700
So if you had already a flask app or something like that, and you're like, I'd like to add

00:56:14.700 --> 00:56:15.960
some additional features to it.

00:56:15.960 --> 00:56:20.780
You could just plug in some API type thing to it, some RESTful API extension.

00:56:20.780 --> 00:56:21.660
And it goes.

00:56:21.780 --> 00:56:25.120
But if you're starting from scratch, you might create an API with FastAPI.

00:56:25.120 --> 00:56:27.840
Then you're like, well, I also wanted some HTML stuff.

00:56:27.840 --> 00:56:33.760
Could I actually add like a server side HTML story around this as well?

00:56:33.760 --> 00:56:39.160
So it shows you how to like create users, submit forms, validate data, use templates, all that

00:56:39.160 --> 00:56:39.540
kind of stuff.

00:56:39.540 --> 00:56:43.480
So kind of like you need a little bit more on the server side, a little more on the website,

00:56:43.480 --> 00:56:46.560
not just pure API, then like that would tell you how to do that.

00:56:46.560 --> 00:56:48.540
So you're using server side templating for that?

00:56:48.760 --> 00:56:52.180
Yeah, either Jinja2 or Chameleon, pick your pick.

00:56:52.180 --> 00:56:52.700
Yeah.

00:56:52.700 --> 00:56:55.760
Basically, we recreate IPI.org and FastAPI.

00:56:55.760 --> 00:57:00.660
So you're not doing a single page app and with you and React and Dockerizing and both?

00:57:00.660 --> 00:57:01.520
No, exactly.

00:57:01.520 --> 00:57:02.240
Well, why not?

00:57:02.240 --> 00:57:04.160
I know, I know.

00:57:04.160 --> 00:57:05.080
You're not doing it right.

00:57:05.080 --> 00:57:06.760
I'm totally doing it wrong, though.

00:57:06.760 --> 00:57:08.800
I definitely would not be cool in the JavaScript world.

00:57:08.800 --> 00:57:12.240
You know, it's not that I'm super against that, but I think that there's still a lot of

00:57:12.240 --> 00:57:14.720
value to having some of the stuff on server side.

00:57:14.720 --> 00:57:17.520
And then I don't think everything has to be a spa, right?

00:57:17.520 --> 00:57:18.180
Single page app.

00:57:18.320 --> 00:57:20.580
Yeah, I was being sarcastic because that's definitely like...

00:57:20.580 --> 00:57:20.980
I know you are.

00:57:20.980 --> 00:57:21.500
I know you are.

00:57:21.500 --> 00:57:21.700
Yeah.

00:57:21.700 --> 00:57:25.660
So we were talking right before this.

00:57:25.660 --> 00:57:29.500
We realized we have our three classes here, our courses here, that we wanted to do some

00:57:29.500 --> 00:57:33.560
kind of special for people and a way also to give back to FastAPI.

00:57:33.560 --> 00:57:35.060
I want to tell people what we came up with.

00:57:35.060 --> 00:57:37.840
Like this was not pre-planned until we were like, oh, wait, why don't we, you know, we're

00:57:37.840 --> 00:57:38.680
looking at these three things here.

00:57:38.680 --> 00:57:39.420
Let's do something.

00:57:40.180 --> 00:57:45.080
We decided that we're going to sell these three classes as a bundle, not one off.

00:57:45.080 --> 00:57:49.560
But if you want to take all three of these classes, we'll give you 50% off the price and

00:57:49.560 --> 00:57:56.320
50% of that 50%, 50% of what you pay us will go to support FastAPI directly.

00:57:56.320 --> 00:58:01.440
So we're going to try to do a little fundraiser for FastAPI and do a little awareness for our

00:58:01.440 --> 00:58:01.740
courses.

00:58:01.740 --> 00:58:02.020
Yeah.

00:58:02.020 --> 00:58:03.940
And the courses kind of build into each other too.

00:58:03.940 --> 00:58:06.540
Like your core, your modern API is a FastAPI.

00:58:06.540 --> 00:58:08.020
I would recommend taking that first.

00:58:08.020 --> 00:58:10.840
And then sort of my course takes that to the next level.

00:58:10.840 --> 00:58:15.140
And then if you want to learn how to like, hey, I want to buy routes to have like server

00:58:15.140 --> 00:58:19.440
side templating so I can like serve up something to interact with the API and add the full web

00:58:19.440 --> 00:58:20.920
app course on top of that.

00:58:20.920 --> 00:58:21.960
Yeah, I think so.

00:58:21.960 --> 00:58:26.340
So we don't have, because it's your course and my courses, different platforms, all that,

00:58:26.340 --> 00:58:28.120
we don't have an official way to make this happen.

00:58:28.120 --> 00:58:29.460
So they just send you an email.

00:58:29.460 --> 00:58:30.040
Yeah.

00:58:30.260 --> 00:58:32.720
And say, hey, I'd like to do this bundle thing.

00:58:32.720 --> 00:58:34.820
And we'll just make it happen behind the scenes, right?

00:58:34.820 --> 00:58:35.220
Yeah.

00:58:35.220 --> 00:58:38.000
Just shoot me a quick email, michael.testroom.io.

00:58:38.000 --> 00:58:43.060
And I'll do all the hard work and link all that together and send and put down, probably

00:58:43.060 --> 00:58:44.000
just use Stripe for that.

00:58:44.000 --> 00:58:47.180
Just send out a quick Stripe invoice and then we'll make it work behind the scenes.

00:58:47.180 --> 00:58:50.960
And then Sebastian, the FastAPI creator, 50% of that.

00:58:50.960 --> 00:58:52.880
So help support FastAPI.

00:58:52.880 --> 00:58:53.460
Yeah.

00:58:53.460 --> 00:58:53.920
Fantastic.

00:58:53.920 --> 00:58:54.800
Super cool.

00:58:54.800 --> 00:58:55.100
Yeah.

00:58:55.100 --> 00:58:56.400
Thanks for doing that together, Michael.

00:58:56.400 --> 00:58:56.840
That'd be fun.

00:58:56.840 --> 00:58:57.180
All right.

00:58:57.180 --> 00:59:00.080
Now there's a couple of questions in live chat before we wrap this up.

00:59:00.140 --> 00:59:02.560
I guess let's go with this question from Joe real quick.

00:59:02.560 --> 00:59:04.020
Because I'm really happy with Flask.

00:59:04.020 --> 00:59:05.860
Is there any reason for me to switch to FastAPI?

00:59:05.860 --> 00:59:07.560
I mean, we've covered some of the reasons.

00:59:07.560 --> 00:59:11.180
I would point out before anyone out there listening makes that decision.

00:59:11.180 --> 00:59:15.280
If Flask 2.0 is coming out in a week, wait until that happens.

00:59:15.280 --> 00:59:17.620
And then look at what the modern Flask looks like.

00:59:17.620 --> 00:59:20.900
A lot of major stuff's coming like async and await support and so on.

00:59:20.900 --> 00:59:22.040
And then compare those.

00:59:22.040 --> 00:59:22.440
Yeah.

00:59:22.440 --> 00:59:23.900
I would say that's a hard no.

00:59:23.900 --> 00:59:25.340
Don't switch right away.

00:59:25.340 --> 00:59:27.040
Like spin up an app.

00:59:27.300 --> 00:59:28.120
Like see if you like it.

00:59:28.120 --> 00:59:32.120
See if you enjoy it before like moving your application over to SAPI.

00:59:32.120 --> 00:59:32.660
Yeah.

00:59:32.660 --> 00:59:34.480
And then Teddy has another interesting question.

00:59:34.480 --> 00:59:39.980
Like, are we aware of any CMS like projects building on top of FastAPI similar to say Wagtail

00:59:39.980 --> 00:59:40.400
with Django?

00:59:40.400 --> 00:59:41.620
I don't know of any.

00:59:41.620 --> 00:59:42.100
Yeah.

00:59:42.100 --> 00:59:42.660
I don't know either.

00:59:42.920 --> 00:59:47.440
The closest that I would say is like that thing I described with full web apps with Fast

00:59:47.440 --> 00:59:51.200
API, which you can get the code from the open public GitHub repo.

00:59:51.200 --> 00:59:52.620
You don't have to take the course to check it out.

00:59:52.620 --> 00:59:56.800
That does put like HTML views and stuff on top of it, but you're still there.

00:59:56.800 --> 01:00:01.460
It's more like what Flask does from scratch, not what Wagtail does from like, here's your

01:00:01.460 --> 01:00:01.740
CMS.

01:00:01.740 --> 01:00:04.640
So that's a very long ways from what you're asking, but it's as close as I know of.

01:00:04.640 --> 01:00:04.940
Yeah.

01:00:04.940 --> 01:00:07.860
Wagtail is like in between WordPress and sort of Django.

01:00:07.860 --> 01:00:10.500
So it adds a lot on top of Django.

01:00:10.700 --> 01:00:14.780
So yeah, if you're looking for that sort of functionality, FastAPI is not going to do

01:00:14.780 --> 01:00:14.960
that.

01:00:14.960 --> 01:00:16.960
I wouldn't even look for an extension out there for that.

01:00:16.960 --> 01:00:17.840
It's not the right tool.

01:00:17.840 --> 01:00:18.660
Yeah, probably not.

01:00:18.660 --> 01:00:22.000
Dominus, what's the best platform to deploy FastAPI?

01:00:22.000 --> 01:00:22.500
Yeah.

01:00:22.500 --> 01:00:24.280
So you can deploy it really sort of anywhere.

01:00:24.280 --> 01:00:26.240
It kind of gets into the hosting section there.

01:00:26.240 --> 01:00:27.460
So if you want to scroll down there.

01:00:27.460 --> 01:00:27.840
Yeah.

01:00:27.840 --> 01:00:28.100
Yeah.

01:00:28.100 --> 01:00:31.160
It's kind of, we were like on the cusp of it, but we don't really have time to go too

01:00:31.160 --> 01:00:31.700
deep into it.

01:00:31.700 --> 01:00:32.040
Yeah.

01:00:32.040 --> 01:00:32.520
Yeah.

01:00:32.520 --> 01:00:37.140
I mean, if you containerize it, you can obviously deploy it wherever I deploy like to Heroku.

01:00:37.140 --> 01:00:39.840
It's very simple to deploy containerize apps there.

01:00:40.260 --> 01:00:42.640
EC2, DigitalOcean as an app platform.

01:00:42.640 --> 01:00:44.900
That's where a platform is a service.

01:00:44.900 --> 01:00:46.500
It's similar to Heroku now.

01:00:46.500 --> 01:00:50.540
So yeah, I mean, really wherever you like to do your deployments, you know, FastAPI,

01:00:50.540 --> 01:00:51.920
totally fine to deploy it there.

01:00:51.920 --> 01:00:52.800
It goes pretty easily.

01:00:52.800 --> 01:00:53.020
Yeah.

01:00:53.020 --> 01:00:56.300
There's even some serverless stuff that you point out in your list there, right?

01:00:56.300 --> 01:00:56.940
Further down.

01:00:56.940 --> 01:01:05.200
Certainly on the infrastructure to service, Nginx, G Unicorn, particularly running uvicorn

01:01:05.200 --> 01:01:06.200
workers.

01:01:06.200 --> 01:01:10.060
So you get the async support, which is like a special flag you can pass to G Unicorn.

01:01:10.060 --> 01:01:13.360
And then let's encrypt for SSL and you're golden.

01:01:13.360 --> 01:01:13.720
Yeah.

01:01:13.720 --> 01:01:17.020
And I run an awesome Flask, you know, repo as well.

01:01:17.020 --> 01:01:19.980
And I literally copied and pasted this from Flask.

01:01:19.980 --> 01:01:21.960
So it's like, I mean, all of this is just agnostic.

01:01:21.960 --> 01:01:22.360
Yeah.

01:01:22.360 --> 01:01:23.000
Yeah.

01:01:23.000 --> 01:01:23.440
Very cool.

01:01:23.440 --> 01:01:27.960
And Joe actually gave a call out to that earlier saying, I just starred your live and realized

01:01:27.960 --> 01:01:29.780
you're the same guy that does the awesome Flask list.

01:01:29.780 --> 01:01:31.040
Awesome.

01:01:31.040 --> 01:01:31.520
Yeah.

01:01:31.580 --> 01:01:32.020
There we go.

01:01:32.020 --> 01:01:32.740
Fantastic.

01:01:32.740 --> 01:01:33.400
All right.

01:01:33.400 --> 01:01:39.180
Well, I think we're quite out of time here, Michael, but super fun, super fun stuff to

01:01:39.180 --> 01:01:39.700
talk about.

01:01:39.700 --> 01:01:40.460
Really helpful.

01:01:40.460 --> 01:01:44.720
I just love these awesome lists because not only do you learn about all these cool things

01:01:44.720 --> 01:01:50.220
like some of the plugins, like FastAPI, SQLAlchemy, but then also things that those are using.

01:01:50.220 --> 01:01:54.220
It's just such a cool exploration of all these different libraries and things that are out

01:01:54.220 --> 01:01:54.860
there, right?

01:01:54.860 --> 01:01:56.340
Like Beanie, for example.

01:01:56.340 --> 01:01:59.660
I didn't know about Beanie, but now I discovered it, even though I wasn't looking for that in

01:01:59.660 --> 01:02:00.020
particular.

01:02:00.440 --> 01:02:00.540
Yeah.

01:02:00.540 --> 01:02:04.080
I don't know how many times I see on Reddit, like people asking, well, hey, what should

01:02:04.080 --> 01:02:04.920
I use for auth?

01:02:04.920 --> 01:02:06.420
What should I use for this?

01:02:06.420 --> 01:02:09.280
And it's like, well, I mean, yeah, I mean, here's a list.

01:02:09.280 --> 01:02:11.520
Here's a concise list of all the different things out there.

01:02:11.520 --> 01:02:15.740
It might not cover everything because there's obviously other things out there, but it's

01:02:15.740 --> 01:02:19.900
definitely nice to like come to something like this versus like, you know, searching PyPI

01:02:19.900 --> 01:02:21.900
with FastAPI dash, basically.

01:02:21.900 --> 01:02:22.480
Exactly.

01:02:22.480 --> 01:02:23.640
Exactly.

01:02:23.640 --> 01:02:27.660
One of the big challenges we have in the Python space, which is kind of the opposite

01:02:27.660 --> 01:02:32.340
of some places like say the Microsoft world where they're like, here's your ORM, here's

01:02:32.340 --> 01:02:32.960
your web framework.

01:02:32.960 --> 01:02:33.820
You go build with that.

01:02:33.820 --> 01:02:34.400
Have a good time.

01:02:34.400 --> 01:02:40.060
Is we have the exact opposite of there's a thousand flowers blooming in each level of the

01:02:40.060 --> 01:02:40.480
stack.

01:02:40.700 --> 01:02:42.160
And it's a paradox of choice.

01:02:42.160 --> 01:02:46.080
Did you notice as a newcomer, I don't think it feels like amazing.

01:02:46.080 --> 01:02:46.940
Look at all these choices.

01:02:46.940 --> 01:02:48.160
It feels like overwhelming.

01:02:48.160 --> 01:02:49.320
I had, what do I do?

01:02:49.320 --> 01:02:49.720
Yeah.

01:02:49.720 --> 01:02:50.240
Right.

01:02:50.240 --> 01:02:54.420
I think awesome lists like the one you created are helpful to really narrow it down to a couple,

01:02:54.420 --> 01:02:56.220
go make a pick and just run with it.

01:02:56.220 --> 01:02:59.380
A lot of the Ruby and Rails folks, when they come over to the Python space, they're like,

01:02:59.380 --> 01:03:00.300
well, there's more than one.

01:03:00.300 --> 01:03:01.620
There's more than one ORM.

01:03:01.620 --> 01:03:03.660
Well, which one do I use?

01:03:03.660 --> 01:03:05.000
Well, I don't know.

01:03:05.000 --> 01:03:06.000
Ask DHH, I guess.

01:03:06.000 --> 01:03:07.100
Yeah, exactly.

01:03:07.100 --> 01:03:07.640
What are you doing?

01:03:07.640 --> 01:03:08.200
What are you doing?

01:03:08.200 --> 01:03:08.900
Yeah.

01:03:08.900 --> 01:03:09.480
Very cool.

01:03:09.480 --> 01:03:09.880
All right.

01:03:09.880 --> 01:03:13.440
Well, I guess we're down to the final two questions before I let you out of here.

01:03:13.440 --> 01:03:15.740
I'll see if this has changed since last time.

01:03:15.740 --> 01:03:19.020
So if you're going to write some code, what editor do you use?

01:03:19.020 --> 01:03:20.220
Python code, I suspect.

01:03:20.220 --> 01:03:25.080
So I approached this question a little different because you asked me favorite editor and I said

01:03:25.080 --> 01:03:29.920
idle because I don't use idle, you know, obviously, but it has a special place in my

01:03:29.920 --> 01:03:31.940
heart because that's where I learned Python was idle.

01:03:31.940 --> 01:03:38.020
And Thani is like sort of like in between like VS Code or a PyCharm and idle sort of like

01:03:38.020 --> 01:03:38.540
Interesting.

01:03:38.540 --> 01:03:40.840
You're going to learn like idle like today.

01:03:40.840 --> 01:03:41.660
Check out Thani.

01:03:41.660 --> 01:03:46.220
It like adds like some debugging like type tools and it's like a lot prettier to look at.

01:03:46.220 --> 01:03:46.520
Yeah.

01:03:46.520 --> 01:03:47.300
Super interesting.

01:03:47.300 --> 01:03:53.420
It's like sort of like a notebook, sort of like a proper like autocomplete editor.

01:03:53.420 --> 01:03:55.420
And it looks a little bit like idle.

01:03:55.420 --> 01:03:55.700
Yeah.

01:03:55.700 --> 01:03:56.340
How interesting.

01:03:56.340 --> 01:03:57.000
Yeah.

01:03:57.000 --> 01:03:57.380
Cool.

01:03:57.380 --> 01:03:57.680
Okay.

01:03:57.680 --> 01:03:57.880
Yeah.

01:03:57.880 --> 01:03:59.120
I haven't thought about that one for a while.

01:03:59.120 --> 01:03:59.480
That's cool.

01:03:59.480 --> 01:03:59.900
And then.

01:03:59.900 --> 01:04:00.340
Yeah.

01:04:00.700 --> 01:04:02.460
Don't use this on a daily basis though.

01:04:02.460 --> 01:04:06.340
So I definitely use VS Code on a daily basis.

01:04:06.340 --> 01:04:08.640
So I'm not coding in the idle.

01:04:08.640 --> 01:04:10.040
Like what does idle stand for?

01:04:10.040 --> 01:04:11.860
Integrated development and learning environment.

01:04:11.860 --> 01:04:12.080
Yeah.

01:04:12.080 --> 01:04:13.720
Don't use that on a daily basis.

01:04:13.720 --> 01:04:14.640
Exactly.

01:04:15.120 --> 01:04:17.640
I use Scratch for my architecture design diagrams.

01:04:17.640 --> 01:04:17.920
Yeah.

01:04:17.920 --> 01:04:18.360
There you go.

01:04:18.360 --> 01:04:19.020
Yeah.

01:04:19.020 --> 01:04:20.680
And then notable PyPI package.

01:04:20.680 --> 01:04:22.240
So I've been using for doc strings.

01:04:22.240 --> 01:04:25.280
I've been using Flake 8 doc strings just to lint my doc strings.

01:04:25.280 --> 01:04:26.540
And that has helped me.

01:04:26.540 --> 01:04:30.600
You know, I use like the sort of the Google flavor of doc strings.

01:04:30.660 --> 01:04:32.800
And that has helped me adhere to that a little bit better.

01:04:32.800 --> 01:04:33.300
Yeah.

01:04:33.300 --> 01:04:36.320
Also, I want to give a shout out to Hotwire Django.

01:04:36.320 --> 01:04:40.960
So Hotwire comes from sort of the Rails sort of world.

01:04:40.960 --> 01:04:44.940
But this is essentially HTML served over WebSockets.

01:04:44.940 --> 01:04:50.120
So instead of like, you know, doing, you know, all this stuff with Vue or React, what you do

01:04:50.120 --> 01:04:53.320
is you serve up basically templates and the templates are pre-rendered.

01:04:53.320 --> 01:04:53.680
Yeah.

01:04:53.680 --> 01:04:54.240
Hey.com.

01:04:54.240 --> 01:04:55.780
That's where Hotwire comes from.

01:04:55.780 --> 01:05:00.160
But instead of serving up your JSON and having two forms of state, one on the client,

01:05:00.240 --> 01:05:02.520
one on the server, you just like, you simplify it all.

01:05:02.520 --> 01:05:05.800
I mean, it does add complexity with WebSockets and you have to deal with that.

01:05:05.800 --> 01:05:11.260
But yeah, I like sort of that paradigm and it feels like a little bit more like 2005-ish

01:05:11.260 --> 01:05:13.420
than 2020-ish.

01:05:13.420 --> 01:05:17.700
But yeah, I mean, it's definitely been working for the Rails folks and Basecamp.

01:05:17.700 --> 01:05:18.080
Yeah.

01:05:18.080 --> 01:05:19.120
That place is interesting.

01:05:19.120 --> 01:05:20.720
All the frameworks that they kick out.

01:05:20.720 --> 01:05:21.040
Yeah.

01:05:21.040 --> 01:05:21.360
Cool.

01:05:21.360 --> 01:05:21.640
All right.

01:05:21.640 --> 01:05:24.960
So if you want to, if you want to be like, hey, and DHH, you can go do that.

01:05:24.960 --> 01:05:25.600
That's really cool.

01:05:25.600 --> 01:05:26.000
Yeah.

01:05:26.000 --> 01:05:26.840
I've heard good things about it.

01:05:26.840 --> 01:05:27.460
Awesome.

01:05:27.460 --> 01:05:29.780
Well, Michael, it's been really fun to talk about.

01:05:29.820 --> 01:05:30.640
Your Awesome List.

01:05:30.640 --> 01:05:33.540
And I think all the stuff we touched on is going to be super helpful.

01:05:33.540 --> 01:05:34.580
Final call to action.

01:05:34.580 --> 01:05:37.620
People want to get started with FastAPI and pick some libraries.

01:05:37.620 --> 01:05:38.080
What do they do?

01:05:38.080 --> 01:05:42.080
You know, obviously, I would definitely say start with the FastAPI documentation.

01:05:42.080 --> 01:05:42.960
It is great.

01:05:42.960 --> 01:05:48.040
Out of all of like the documentation out there in terms of Flask and Django and whatnot, that

01:05:48.040 --> 01:05:49.740
one is by far the best.

01:05:49.740 --> 01:05:50.940
Definitely start off there.

01:05:50.940 --> 01:05:55.900
After you've built like just a basic app, check out the awesome like FastAPI list to see how

01:05:55.900 --> 01:05:56.560
to extend it.

01:05:56.560 --> 01:06:01.520
And then if you're looking to like learn more in the testing and Docker type realm, check

01:06:01.520 --> 01:06:04.520
out my course and check out, you know, Michael's courses as well.

01:06:04.520 --> 01:06:04.980
Yeah.

01:06:04.980 --> 01:06:06.480
And you can do that bundle thing.

01:06:06.480 --> 01:06:10.080
I'll include the email so they can send it over and help them out.

01:06:10.080 --> 01:06:10.680
Very cool.

01:06:10.680 --> 01:06:10.980
Awesome.

01:06:10.980 --> 01:06:11.280
Yeah.

01:06:11.280 --> 01:06:11.640
Yeah.

01:06:11.640 --> 01:06:12.140
Awesome.

01:06:12.140 --> 01:06:12.320
Yeah.

01:06:12.320 --> 01:06:13.600
So thank you so much for being here.

01:06:13.600 --> 01:06:14.680
Really appreciate it.

01:06:14.680 --> 01:06:18.440
And it's been super fun to talk FastAPI and all the stuff around it.

01:06:18.440 --> 01:06:19.600
It's really growing, isn't it?

01:06:19.600 --> 01:06:19.980
Yeah.

01:06:19.980 --> 01:06:20.440
It's exciting.

01:06:20.440 --> 01:06:24.480
It's exciting to see just how much it's grown just in like past like six months.

01:06:24.480 --> 01:06:25.600
Yeah, absolutely.

01:06:25.600 --> 01:06:26.340
All right.

01:06:26.340 --> 01:06:26.820
See you later.

01:06:26.820 --> 01:06:27.260
Yeah.

01:06:27.260 --> 01:06:28.000
Well, cheers.

01:06:28.000 --> 01:06:28.700
Thanks for having me.

01:06:28.700 --> 01:06:29.200
Appreciate it.

01:06:29.200 --> 01:06:29.540
Yep.

01:06:29.540 --> 01:06:30.000
Cheers.

01:06:30.000 --> 01:06:33.680
This has been another episode of Talk Python To Me.

01:06:33.680 --> 01:06:38.520
Our guest in this episode was Michael Herman, and it's been brought to you by us over at

01:06:38.520 --> 01:06:39.280
Talk Python Training.

01:06:39.280 --> 01:06:41.280
Want to level up your Python?

01:06:41.280 --> 01:06:45.320
We have one of the largest catalogs of Python video courses over at Talk Python.

01:06:45.760 --> 01:06:50.500
Our content ranges from true beginners to deeply advanced topics like memory and async.

01:06:50.500 --> 01:06:53.180
And best of all, there's not a subscription in sight.

01:06:53.180 --> 01:06:56.080
Check it out for yourself at training.talkpython.fm.

01:06:56.080 --> 01:07:00.760
Be sure to subscribe to the show, open your favorite podcast app, and search for Python.

01:07:00.760 --> 01:07:02.060
We should be right at the top.

01:07:02.060 --> 01:07:07.220
You can also find the iTunes feed at /itunes, the Google Play feed at /play,

01:07:07.220 --> 01:07:11.440
and the direct RSS feed at /rss on talkpython.fm.

01:07:11.440 --> 01:07:14.860
We're live streaming most of our recordings these days.

01:07:15.000 --> 01:07:18.280
If you want to be part of the show and have your comments featured on the air,

01:07:18.280 --> 01:07:22.700
be sure to subscribe to our YouTube channel at talkpython.fm/youtube.

01:07:22.700 --> 01:07:24.540
This is your host, Michael Kennedy.

01:07:24.540 --> 01:07:25.840
Thanks so much for listening.

01:07:25.840 --> 01:07:27.000
I really appreciate it.

01:07:27.000 --> 01:07:28.900
Now get out there and write some Python code.

01:07:44.240 --> 01:07:49.560
I'll see you next time.