Moving Fast with FastAPI
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Number of Parts | 115 | |
Author | ||
Contributors | ||
License | CC Attribution - NonCommercial - ShareAlike 4.0 International: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this | |
Identifiers | 10.5446/58758 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
00:00
GoogolTime zone2 (number)Multiplication signState of matterCodeCartesian coordinate systemLibrary (computing)Projective planeFunctional (mathematics)Web pageWeb 2.0Software testingModule (mathematics)Socket-SchnittstelleOrbitComputer fileTwitterReal numberQuery languageOrder (biology)WebsiteRoutingDatabaseMathematicsProduct (business)Mobile appCone penetration testContext awarenessSoftware developerLogicBitWeb serviceFront and back endsSoftware frameworkServer (computing)FlagLatent heatInformationNetwork socketClient (computing)PlanningMatching (graph theory)Object (grammar)Musical ensemblePattern languageSocial classAuthenticationoutputString (computer science)Dependent and independent variablesSubject indexingElectric generatorDevice driverIntegrated development environmentLine (geometry)File viewerForm (programming)Event horizonVolumenvisualisierungUniform resource locatorComputer programmingTemplate (C++)System callRepresentational state transferWeb applicationPasswordCASE <Informatik>Limit (category theory)WordType theoryEndliche ModelltheorieIntegerData managementArtificial lifeArray data structureSuite (music)Point (geometry)AdditionFunction (mathematics)Content (media)NumberInstance (computer science)Roundness (object)Message passingValidity (statistics)Telephone number mappingAsynchronous Transfer ModeSoftware bugSynchronizationException handlingMoment (mathematics)Mixed realityDataflowRight angleInjektivitätLevel (video gaming)Parameter (computer programming)Flow separationCodeMiniDiscGoodness of fitDampingMedical imagingGraph coloringView (database)Connected spaceControl flowMaizeRevision controlConfiguration spaceNumbering schemeEmailDifferent (Kate Ryan album)File formatProxy serverArmPersonal digital assistantMeeting/Interview
00:32
Goodness of fitMultiplication signRight angleMeeting/Interview
01:01
Witt algebraGEDCOMGamma functionGraphic designACIDDew pointDuality (mathematics)Keilförmige AnordnungPredictabilitySoftware development kitStatisticsWindowLatent class modelMaxima and minimaLemma (mathematics)File formatTwitterMobile appDampingDatabaseArithmetic meanSoftware frameworkComputer fileEvent horizonProduct (business)Moment (mathematics)Web applicationPattern languageProjective planeData storage deviceProcess (computing)Electric generatorDependent and independent variablesTemplate (C++)Cartesian coordinate systemElectronic visual displayAdditionInstance (computer science)Function (mathematics)Server (computing)WordMathematicsWeb 2.0Endliche ModelltheorieSource code
07:47
World Wide Web ConsortiumGEDCOMComputer wormGame theoryKeilförmige AnordnungVarianceElectronic data interchangeMaxima and minimaMoving averageGamma functionMenu (computing)Information managementGeometryColor managementKey (cryptography)Ring (mathematics)Discrete element methodAutomorphismFood energyMassMetropolitan area networkGraphic designEmailLemma (mathematics)System callSoftware developerWeb pageTwitterQuery languageType theoryCodeRight angleContent (media)Open setMobile appUniform resource locatorComputer fileUniqueness quantificationObject (grammar)InjektivitätParameter (computer programming)Event horizonDatabaseNumberCartesian coordinate systemoutputComputer clusterSubject indexingSocial classEndliche ModelltheorieSource code
14:33
TwitterNumbering schemeDependent and independent variablesComputer animation
15:06
Gamma functionMaxima and minimaGEDCOMKeilförmige AnordnungGame theoryMach's principleColor managementFirmwareCodeFiber (mathematics)World Wide Web ConsortiumDynamic random-access memoryComa BerenicesCodeCartesian coordinate systemWeb 2.0Exception handlingGraph coloringEmailSoftware testingServer (computing)Client (computing)Functional (mathematics)AuthenticationFunction (mathematics)View (database)Data managementQuery languageRight anglePlanningMultiplication signSoftware bugMathematicsPattern languageoutputDifferent (Kate Ryan album)Latent heatTelephone number mappingIntegrated development environmentUniform resource locatorSoftware developerWeb applicationDependent and independent variablesMessage passingError messageCodeSource code
23:33
Gamma functionColor managementProjective planeMultiplication signWebsiteBitLecture/ConferenceSource codeMeeting/Interview
24:31
Gamma functionMassWorld Wide Web ConsortiumEmailInformation managementEmbedded systemAugmented realityGame theoryWeightDemo (music)Electronic meeting systemVacuumMenu (computing)Common Language InfrastructureComputer iconKeilförmige AnordnungDean numberCodeCartesian coordinate systemModule (mathematics)TwitterOrder (biology)DatabaseDevice driverMedical imagingConfiguration spacePoint (geometry)Functional (mathematics)Social classNetwork socketServer (computing)AbstractionConnected spacePlanningProduct (business)LogicState of matterIntegrated development environmentSource code
29:37
Roundness (object)Control flowMeeting/Interview
Transcript: English(auto-generated)
00:06
Good morning, and welcome to the second day of conference talks. And I'm really happy that you got up this early in the morning, or that you're maybe in a time zone where it's not that early in the morning. But anyway, we have a great speaker with a fast topic to get us running
00:24
and to get us all pumped up. So I will not waste much of your time and just say let's welcome Dave Bordenik. Hello, good morning. Hey, good morning. Where are you located this morning? In Israel. Oh, so what's the time in Israel this morning?
00:42
9 a.m. Oh, this is much nicer. Okay, so you work for NVIDIA? Right. And I saw the topic, you're doing something very fast today. I'll do my best. I will let you have the stage. Okay, thank you very much.
01:01
Okay, so what we're doing today, we're developing a web application that serves the funniest tech tweets that can be found. And we want the entire works. We want schema validation, we want API documentation,
01:21
we want it to run fast, and we want to develop fast. So that's why we chose fast API framework created by Sebastian Ramirez not too long ago, I think, a year and a half. So without further ado, let's get started. First, I'm initializing the app instance.
01:48
Okay, and as we can see now, we initialize the first API. Everything is live coding here. The only thing that is prepared in advance is the tweets database and some files with comments that will guide it through.
02:05
So right now, I'm going to write something that will display those comments during the session. I'm going to use a feature called event handler and then I'm going to use the start process. So let's see how it goes. I'm annotating the app and I'm saying on event
02:23
and the event that I'm providing is the startup event. And right now, I'm going to open the comments file. Sorry about that.
02:43
Okay, and I'm using Calcite to display it. Format the JSON a bit.
03:00
Okay. So now we're going to run the app. Fast API is a web framework and it uses an ASGI web server called UVCon. So right now, we're going to run it. We also use a dash dash reload flag, which reloads the app while we're making changes,
03:25
which is great for development, but make sure it doesn't go into production. Okay. So without further ado, let's implement our first HTTP handler. We'll start with the HTTP method get
03:42
and we're going to display all the tech tweets that we have. Okay, and now I'm opening my database, which is a JSON file.
04:01
I'm not saying that this should be a production database, but I'm not saying it's not. It's not the problem that we're trying to solve at the moment. Okay. So the app got reloaded. And okay, so we have a first web application.
04:22
And how can we consume it? I like to consume it with a command line application called CRL. It's everywhere. It has all the features that you want and you're in your ID store. So that's great.
04:43
Okay, and we can see that we're getting a response back, which is great. This is exactly what we're hoping for. I like to combine it with an additional command line application called JQ, and it predifies JSON output. So it's much more pleasant on the eye.
05:01
Okay. Didn't see the comments properly because I had the typo here. We can see it better right now. And another great thing about fast API is that it takes all the handlers, all the HTTP handlers that you are writing, and it auto-creates a documentation out of it.
05:22
So I'll show you how it looks like.
05:47
Okay, it doesn't let me show it to you. That's a shame. No. I don't know what to do. Okay, never mind. I'll show it in the chat later.
06:03
But it gives the documentation. Trust my word for it. And moving on. We're going to do a CRUD here. Basically, I'm going to take the IO that is here, and I'm going to move it to another model.
06:23
We did it at the first attempt with Firefox, so right now I'm just going to call it.
06:41
We'll fix the import. You can see the app got reloaded, and we can see that it's still working. What I did here with the IO, it's a similar pattern. The fast API has an amazing project generation template. And in that project generation template, you can see everything. Development, deployment, front-end, back-end,
07:02
tests, everything. So the way I like to explore new technologies is either take this template that is ready as possible and use it and then do minor changes to put my business knowledge here, or I can start from scratch and only put in the stuff that I want.
07:21
This is the pattern that we're going to use now. Okay, so this was about fraud. Moving on to our next example. Okay, you can use fast API as both synchronous and asynchronous. You can also use them together, meaning that here we abstracted the IO,
07:41
but if this IO is non-blocking IO, we can make the HTTP under async, and our application can still work, and we can also do mix and match. Moving on, we're going to talk about query params.
08:03
Fast API has an interesting approach here. It uses a dependency injection pattern, meaning that those parameters are not available during development time, but at runtime, they magically appear. So let's start with query params. As our tech tweets, database gets larger,
08:21
this call gets slower, and we want to limit what's being returned here. If we have a UI, we might also want to page it, so there are many use cases for it. So I'm saying that it has a query param named size, and its type is an integer. Right now, I'm going to slice the array
08:41
that is being returned. The app is being reloaded, and let's see that it's working. I'm adding a query param named size, and you can see we have less stuff coming back. Moving on, we have URL params.
09:01
So let's implement an event handler that is very similar to the previous one but with a URL param. Let's say that every tech tweet that we have is uniquely identified by its array index, so we'll call it a tech tweet ID. The way to define it is very similar to f-strings,
09:21
just without the f, and I'm injecting the tech tweet ID as a dependency. Right now, I'm saying that our CRUD returns get at tech tweet ID index.
09:41
Let's see if we implemented it. We implemented it, so the app gets reloaded, and instead of giving it a query param, I'm giving it a URL param, and you can see we have a unique tech ID, a tech tweet that is being returned
10:02
for certain index. Moving on. Okay, and when we're talking about RESTful applications, usually for get HTTP method, you get data, and for post HTTP, those are the requests that are important,
10:22
and when we want to create new data, we usually do a post request, so let's see how it goes, and for a post request, you provide the data as an HTTP body and not as a URL param or a query param, so let's do a post request for tech tweets.
10:48
We'll create tweets. We want to add something. Okay, and what we dependency inject here is a Pydantic class, which gives us the ability to define strictly
11:03
the input schema, so it sounds very complicated, but it's actually pretty simple, so let's have a look. We're saying it's getting a tweet, and the tweet is of type tweet, and let's create this class tweet, and it's supposed to inherit by dumping base model.
11:27
Okay, we're importing it, and we're only saying that it has one key called content, and the content is a string, and so what we're doing at the moment,
11:41
okay, we are saying, okay, let's use the crowd to save this tweet, and save this with content, and what we're going to do, this is custom for post request that's creating data.
12:02
We're going to return 101 status code. We can also say that instead of returning the status code here, we can say that the user status code here is 101. It's the same, so right now we are going to the crowd, and we're going to implement the save method,
12:25
so what we're going to do now, we're going to append it to our database, and we're going to save it, so it will be persisted between reloads.
12:48
Open the file for writing, and instead of loading, we'll just get the object,
13:03
and then it gets fucked. Okay, so the object reloaded right now. Okay, so this is for CRL. We're saying that this is a JSON
13:21
that we're sending data as JSON, and we're sending it to take tweets, and the data that we send is content of a new tweet, okay, and we can see that we've got 201 created, so let's see if it's saved. I think it's number four.
13:41
Yeah, okay, and we implemented a post request with a body, so let's say that you don't know the schema in advance, or you want to do some exploration, so instead of defining the type, you can say that it gets a dict,
14:03
and then you can send whatever you want with JSON, and it's not strict, and it's not validated, but allow you to do some exploration. Let's try again. I'll try again to share with you how it looks like on the schema.
14:23
You didn't let me to do it earlier. Let's see if it will behave right now. Yeah, okay, everything is here, so we can see all the HTTP methods that we implemented.
14:42
It has auto-generated documentation. You can see here the tech tweet ID is a URL param. We can see it is an integer, and we can see that it is required. We can try it out, provide it with a number. We get the response here, the status code, and we can also get the CRL command,
15:02
and for the post, if we use a strict schema, we can also see the scheme. Okay, so let's get back. Okay, moving on to our next example. Okay, CRL is really great.
15:21
Combining it with JQ is even greater, but I like to use a Python command line application called HTTP, which gives, in my opinion, a much nicer command line interface, so as you can see, we don't need to use JQ, and it returns a code output,
15:41
and it returns the headers in different colors. I prefer to use command line applications like CRL and HTTP instead of using external applications like Postman, because everything is in my IDE view.
16:00
I don't need to go out. I'm inside the development scope, and this is my preference. I hope you like it as well. Okay, right now, we're going to talk about testing. Okay, let's say that, okay, we have an application. We already see that in, I don't know, 15 or 20 minutes.
16:23
We already implemented three HTTP handlers. If you develop this application for months, you can have hundreds of thousands of HTTP handlers, and they might be simple, they might be complicated, but every time you make a change before we deliver it to the customers,
16:41
you want to make sure that everything is working. So you're going to look at an application, and you're trying each route, hopefully, so I know I'll incorporate everything in the test suite. This will be much more maintainable, okay? So the recommended way to test fast API applications
17:03
is with Pytest. So it provides a test client. The test client gets the application as input,
17:21
and you write a function that start with test underscore, and it will be picked up by Pytest, and then I can say response is client get. By the way, the syntax here is request syntax,
17:40
so if you know request, you know how to use the test clients. Give it the param, okay, and let's assert something. The status code is 200.
18:02
I run it through Pycharm. It can be run through command line as well, but I prefer to do Pycharm, and we can see here that the test runs. So HTTP has a lot of status codes. REST API has a lot of status codes, and sometimes, you know, you have to use a bunch of them,
18:21
and you go to other projects, and you get back, and you have new team members that are not necessarily familiar with web application, so do yourself and everyone a favor and just be explicit. Instead of saying 200 or something else, like we had 201 earlier, say use a built-in enum called HTTP status and say,
18:44
okay, it's much more explicit. If you have a large test here, you can understand what is supposed to happen in the entire flow, so be explicit about it. It will be easier to maintain your application like this.
19:01
So using a test client like this is nice and everything, but it has some limitation. It doesn't allow you to override dependencies, and it doesn't let you to... It doesn't perform the startup and shutdown event, so much more, let's call it robust way
19:22
of using the test client is with a fixture, with a pipest fixture. Okay, we'll call it client, and what it does with the complex manager,
19:42
yield the client, and now we pass it this input here. Okay, let's see if everything still passes. Yeah, and this way, let's say, and we add authentication, and we don't want authentication for test,
20:01
but, you know, it won't pass, so we can do stuff like override the, let's say, get current user, and set it as me, and this way, we don't need a authentication for application.
20:21
This is usage that can only be executed in test if you're using it as a fixture and with a complex manager. So let's see that everything still passes. Okay, cool. Another feature that I like to use, I use it in PyCharm.
20:41
It's called Toggle Autotest, but it's also, there are several tools in, with PyTest that allows you to do this. I think Python Xdist or Tersmon or something like this, or even both. So basically what it means that if you have something that fails,
21:02
let's fail something on purpose, and what we tested, we tested the query plan. Okay, so let's say instead, I have a bug here, and I'm raising an HTTP exception. Once again, I'm explicit.
21:21
The status code is, it's, I don't know, internal server level, so let's see. The test got autorerun. I didn't have to do anything, and it failed,
21:41
and I'm getting an explicit failure message saying it expected to get an okay 200, but it got an internal server error of 500. So right now, I'm fixing the bug, and again, I'm not doing anything, and I hope, okay.
22:04
Okay, and the test got reran, and it ran successfully. So that's a great pattern I recommend you all use it. One last thing that I like to talk about
22:21
is that when you develop a fast API application and it gets bigger, then your schema also gets much more complicated, and the input for the OpenAI specification three, which is the UI that I showed you earlier of the API documentation, might break. So what I like to do,
22:41
I like to add a test. The documentation is generated, so right now, I'm only delivering an application that I know this documentation is working as well.
23:07
Oh, right. The URL is wrong. So that's it.
23:22
I hope you enjoyed this talk, and I hope you'll develop a web application using a fast API, and thank you very much. Anyone have any questions? Okay, yes, we do have some questions.
23:41
Before we get started with this, a short information, the talk following you, alas, is not happening, so we have some more time for Q&A. We will keep you updated on the website if we find a new time slot for the next talk.
24:04
That being said, we now have time for Q&A, and I did not have time because everything was a bit chaotic to prepare the banners, so I'll just have to read these. And let's see.
24:21
Somebody asked, like Julian asked, what's the CRUD library? Can you say something about that? Okay, it's not a library. It's like a package that I wrote. It's like a Python package inside this project that only abstracts the eye of it, so nothing too fancy here. I have a module here named tweet
24:42
that opens the JSON files, and we implemented some methods in order to interact with it. Like in a real-world application, you probably have a database driver here and maybe a database connection, and probably the database connection will come from somewhere else, and it's only an API to interact with your data.
25:04
Okay, I've got a question from Dragos, and the question is, it would be interesting to see how you package that all and deploy it in a production environment. Maybe you can give some tips on doing that. Yeah, sure. Sebastian Ramirez is the creator of Fest API.
25:22
Also, he releases a base Docker image of Fest API with Uvicorn and GUnicorn with the basic same configuration. So what you do... Let me try to do the slide.
25:41
So you're saying from... You're saying from the Anglo... I don't remember. Like something GUnicorn, GUnicorn, Uvicorn, Fest API, something like this, and you provide it with the version,
26:02
and then what you do, you install your dependencies, and then you put in your code, and it has the entry point that it runs it. So this is what I use. Very simple.
26:20
I'm using this base image. It's great. I'm installing the dependencies and putting the code. Everything has some reasonable defaults, and this is what I use, either with Docker Compose or Kubernetes. It really doesn't matter. Okay. You showed... That's a question from Diego. You showed URL handlers as functions.
26:42
Can you group them in a class as methods instead? I haven't tried, but it makes sense to do so, but it doesn't... I know why you asked the question because Flask has this connexion, I think,
27:03
or something like this. It really makes sense. I find it... I think it's possible. I haven't tried it. It doesn't feel so comfortable. It doesn't feel so comfortable to do it with Fest API. Fest API feels more like functions-wise
27:21
instead of object-oriented-wise, but I think it's going to work as well. There's a question from Ina. I see that Fest API doesn't support Socket.IO server like the Python Socket.IO. Is there a plan or is there anything
27:42
about this being integrated in the future? Do you know anything about this? I haven't tried it. I think it is supposed to be supported. I think I saw something at the documentation, but I haven't tried it. Okay. There's a final question. Normally, you would use UVCon, for example,
28:01
to run the Fest API application. Is there a way to stop UVCon from within the Fest API so that, for example, you could run Fest API as a background service? From the logic here, you decide, oh, I need to shut this off now.
28:21
Usually, I like to control it from the outside. Usually, I like to control execution from the outside and not from the inside. It makes much more sense. I don't like that the application is aware of its state or the application changes its state. Its state should be changed from the outside.
28:41
I'm not familiar with the way, but I think it's possible is that instead of doing like I did here, you can have a main function, and you can import UVCon. If you can run it, which is equivalent to what we did
29:00
to the command line, I think you can also stop it. But I really like to control stuff like this from the outside and not from the inside. Okay. While you answered this question in the chat, David mentioned that there is WebSockets already built into FastAPI, and it's also documented on the website.
29:21
If somebody wants to do sockets, then the WebSockets or FastAPI might help. This went quite well after our little problems at the beginning. At this point, I'll just thank you for taking the time and that you managed to get everything running and that we could restart it again.
29:40
Let's have another round of applause for you. Then we'll see that we'll take a short break until the next talk. Let's see if Vince is there. I'll just say applause. Let's see. Otherwise, I'll just give you a short applause.
30:01
Thank you. Bye.