Create an API in 20 MINUTES with FastAPI (2024 tutorial)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
if you've ever wanted to build an API and weren't sure how to go about doing that then this video might just be for you we'll be talking about fast API specifically which is a library designed to make API creation easy and quick in Python in fact in this video we'll be talking about how to create an API how did you get create and post request and set up a DB all in 20 minutes of course if you find this video helpful at any point then consider leaving a like to let me know and maybe subscribe if you want to see more videos like this but before we get into the main topic let me talk to you about authorization if you've ever built authorization before you know it can be a nightmare ooc cloud is a solution that allows you to quickly model centralized permissions and more fine grain Access Control within your applications if that sounds like a dream conod true then don't skip this creating authorization policies is easy using polar the open source declarative configuration language and to get you started you can use the built-in visual editor workbench to build your policies from the ground up from there you can model test and integrate your rules into your application the iso cloud service itself which is but and rust secures secely stores all your authorization data for you so all you have to do is make a few API calls they provide clients in the programming languages you use every day like nodejs Python and go as well as tools like their Visual Studio code extension and their comprehensive documentation to make the entire process as slick as possible to use Oso authorization in your python application all you need to do is PIP install uh Oso cloud like that and then you just need to create a client using the osoc cloud URL provide an API key which you can get from the desktop I have it in myn file over here just need to create a user and an organization and then tell the client that your user has a particular role so in this case I'm saying that Bob has a role of owner in the organization and from there you can just call the authorized method on your client to check that a user in this case has the comment permission in your organization if they do you're good to go organizations like intercom product board and page of Duty are already using ocloud for their authorization needs and if you or the company you work for fancy joining them you can sign up for free today by using the link in the description below with all that out of the way let's create your first API to be absolutely clear the duration in the title of the video refers the amount of time I spent programming not the overall length of the video before anyone gets smart in the comments uh but to install fast API all you need to do is do pip install fast API uh and this will install fast API also install pedantic which I made a video about before if you want to learn how that works um fast AP is very heavily reliant on pedantic and while I want to keep this as much like just fast API as possible uh so we don't get distracted by you know SQL Alchemy all that stuff uh pedantic is pretty vital so we will be using that and we also need a way to run our API and you know fast API doesn't provide a way to do that uh and it's well there are two things it recommends in the docs the first one in the list was uvicorn and I actually do quotes here here cuz uh I on zsh and then just standard we'll install the standard stuff I already have everything installed uh but you can see that fast a is actually built on Starlet for those of you that have heard of that and then we have pedantic here as well uh and I'm not actually sure what versions of oh bloody hell of things we have so pantic 2.6.3 we have fast API 0.11.0 and then we have uicorn 0. 27.1 for all those that are curious so I'm going to create a directory over here just called app and inside this directory we need to create an init.py file uh this app can be called whatever you want I'd recommend you you know name that the name of your app rather than just app but for the purposes of a tutorial we just calling the app uh this in it can stay any it just needs to be a package for everything to work and then we create a file just called main.py and this would be pretty much where all of our logic goes uh in terms of this video anyway so to actually create an API you just need to do from Fast API import fast API app equals fast API and then we're going to give it a title so I'm going to call it just carra app and you'll see what that does in a second and then I'm going to give it a version as well this defaults to 0.1.0 I'm going to do 1.0.0 just to be different and then we can do app.get SL so this will be you know a get request against our index and then once someone does that we can run this function and that's going to return a dict of string string and then we're going to return uh aary saying message hello world and this is our API we're done I will be doing more advanced stuff but I do want to show you that this works so if I do uicorn uh what is it let me go in my history there we go app uh domain and then app reload uh so this is is the the name of the module so app is the name of the package main is the name of the file and then colon app is the name of the actual app itself if you run that we'll see that we get um uh the server running on our Local Host if we click that it should there we go and then I'm going to have to zoom very far in there we go 400% that should be fine or maybe 500 there we go we can always zoom out if we need to so we have message hello world and we are just on you know 1.7.0 0.1 Port 8,000 and we have our thing here if we go to Raw data then we can see that we have just a normal Json object which is cool so we have an API that works now what to do with it I'm going to create just a really simple fact API and we're going to be doing some get requests some creates and some deletes uh we don't need to do an edit because Twitter lasted God knows how many is almost 20 without an edit button um so quite frankly uh we don't need one either so first I want to model what a fact is going to look like and for that I'm going to come up to the top again and do from pedantic import base oh God not that base model and we're going to create a class called uh fact we're going to inherit from base model and then it's going to have an ID which is an integer a body which is a string and then we're actually just going to leave it that and this is what each fact is going to look like so it will return a Json object with just an ID and a body and then when we actually get it to use it within uh fast API it would be a pedantic model um so now is as good a time as any to create our database so I'm going to come in here and I'm going to create a new file called schema.sql we are just going to use raw SQL today you can use SQL Alchemy if you prefer but again as I said at the start I don't really want to pollute this with other technologies that people just have to learn um so yeah we're doing it like this uh so create table if not exists uh we need to give it a name there we go fact and then we are going to have an ID which is an integer and a primary key and in SQL light if you have an integer primary key it will auto increment on its own which is pretty cool and then we're going to have body text not null which B basically means that facts have to have a body in order to be inserted and then we'll leave that for now and what we're going to do now is we're going to create something called a dependency which will fetch a database connection when we require it and this will make a little bit more sense um once we actually start doing creating and getting but for now if we just do get DB as a function and that takes nothing and then it returns an iterator of connection and I need to do from typing import it Ator there we go and from sqlite 3 import connection like that and we can do with oh I need to import SQL SQ 3 don't I with SQ light 3. connect and we're just going to have a db. SQ light 3 and we we do actually need to do check same thread equals false uh this is recommended in the fast API documentation basically what this means is that you can have multiple op connections at once and they don't conflict with one another in reality you'd probably want to have some sort of additional checking to make sure that things aren't going wrong but at that point you probably want to use post ciz and we're getting way off topic again uh so we're just going to leave it like that for now and we're going to call that connection and then we're going to do connection. execute script uh and then we're going to have a script path uh so we're going to do from path lib inut import path and we're going to Def find some constants up here so we're going to have DB path equals path uh db. sqi 3 whoops and then we're going to have script path equals path and then app SL schema.sql and this is basically just the path to our database and a path to our script so I can actually replace this with DB path now DB path and then we just want to execute script path. read text now its current state this will execute the script every single time for an example sake I'm I'm going to say I'm not worrying about that but you know if you were to do something with SQL Alchemy You' do something a different way maybe I'll do a video on that at some point uh but for now again don't want to pollute it so we're just doing like that we do want to do connection. row Factory equals esite 3. row and this will instead of returning a list of two PS what it will do is it will return effectively a list of dictionaries they don't it's not quite the same but you access them in the same way and that would be essential to what we're doing and then we just want to do yield connection like that so this is yielding the connection and then once we're finished with the connection it comes back into this function and it it closes out this width statement here and that's also why we're returning an iterator this is how you would uh type hint anything to do with yielding and this will be used um to get our database whenever we need it so now we can actually start creating things so if I do app do uh post and a post request is what creates things I'm going to do slash fact and I'm going to set the status code equals 21 this is you know generally the status code you would expect to see when you've successfully created something and then we're going to set response model equals fact and I'll show off what this is doing a little bit later because this is doing something internally to help fast API uh and we're going do def create fact and then we're going to take uh the body which is a string uh and this is is treated as a request parameter uh and then we're going to have DB which is a connection and then we're going to go up to the top actually and import something so we're going to do from Fast uh API import depends like that and then we do connection equals depends get DB then we return fact and I'm just going to pass here for a second while to explain what's going on so our body is our you know request parameter when we send a request we will need to provide a body and that will be of type string obviously our DB is set to a you know our SQ connection and this depends is essentially a class or I think it's a function but it's rendered as a class in terms of its name inst structure which is a bit odd um and then we pass the callable in here and what that does is it basically you runs that function gets the DB connection from here and then assigns that to DB it's sort of a little bit of I guess it's dependency injection but it's yeah it's a little bit of magic that goes on uh and this is why we call get DB a dependency because we use depends to then you know call this function to assign to DB now from here we can simply just do db. execute insert into fact and then we just want to insert into body uh values and we use a prepared statement I did a video a long long long time ago on um the basics of SQL I don't know how relevant that still is or how good that video is I'll I'll link it in the cards and we'll see if it's if it's still any good because that was a very old video of mine and then we're just going to return a fact so we're going to return a pedantic model and then we're going to get uh execute and then we're going to select the facts so this is I I guess optional but I I would say it was good practice order by ID descending limit one fetch one there we go uh if you're using something like SQL Alchemy you'll probably avoid some race conditions but this is basically just getting the last fact in the list um all the yeah all the fat you just created and then returning that back out to you so if you then oh it's already running so if you come back over here and if we go to slash docs this is really cool you'll see that we actually get some some cool little documentation and from here you can actually run things in the API so we ran this and we got hello world back if we create a fact we click this try out button here we can put something in here so carbra uh started in 2019 which is an actual real fact that's very true click execute and we can see that we get our response body back so we get a 2011 code we get ID equals 1 and then a body of a fact there and if we go back over we can see in the logs that you know everything worked okay but we don't have any way to actually get that fact yet so so we could uh do app.get SLA so this would be now a get request fact and then we want to response model equals fact like that and if we do get fact fact ID so again this is another um request parameter and we do the same thing with our database I'm just going to copy and paste it so not typing it all out again and this will return a fact much in the same way and then we run fact equals db. execute select star from fax where ID equals that and that' be facted ID don't forget the trailing comma maybe we do a fetch one and we actually want to do some error validation here so before we do that we want to come up and we want to import HTTP exception from Fast API come back down here if not fact so if the fact doesn't exist it won't error it will just return none so we can use this if something is none then we raise HTTP exception the status of 404 saying that the fact not found that's what you really need to do and then beyond that you just need to return fact uh and unpack fact into it like that and now if we refresh this page close that we can see we have this get fact in there now and if we were to get fact number one we could see that we get the fact back if we do fact number two fact number 21 error not found detail fact not found and we have our you know four or four here so before we move on something I've realized I've forgotten to do but it actually still worked which is really strange was to do this um so we have slash fact slash and then this um represents the fact that there is a like a a root parameter in here so I guess at this point it's taken you know fact ID as a query parameter if we wanted to do it as a as a root instead then we pass fact ID into here if we then do this we can see that we have fact fact ID and then the request actually looks slightly different so if I to do one there we can see that it's now fact SL one instead of fact question mark fact ID equals 1 so it depends what you want to do if you don't provide roots in here then these will be treated as query parameters if you do provide roots in here they'll be provided as root and these names do need to match otherwise it won't match up um so yeah that was something I forgot to do and it worked and I wasn't expecting it to but there you go final thing I want to do before we finish up is do some deleting uh so we can do app. delete uh it was fact slash and this is actually what um prompted me cuz my notes uh my notes have fact ID in the get but uh yeah I just saw in a delete and realiz I hadn't done it and we want a status code equals 204 so this will be the same thing we use um fact slash and then the number rather than a query parameter and if we do def delete fact uh we pass fact ID as in again and then we do our database is it the same yes that's still on the paste buffer awesome and then we were going to return none out of this and you can actually do something Fancy with raw SQL here that you can't do an SQL Alchemy as far as I know and that is by uh performing the deletion and then retroactively raising an error if it didn't work so if you do row count equals db. execute delete from fax where whoopsy do is where ID equals that and then we pass fact ID here and then row count uh this row count is the number of rows that were inserted updated or deleted from the database in this query so select um it will always be zero actually I think it's always none I forget if it's zero or none but essentially what this will do is if a fact was deleted from the database this will be one otherwise it will be zero and then we think oh nothing was deleted that fact couldn't have existed because it doesn't error on its own so we can then do if not uh row count raise HTTP exception 404 fact not found and then retroactively say you know from a user experience perspective we do want to let them know that the ID didn't exist so we can do that here so if you then come back over and then we have our red delete fact if we then delete fact number one then we get 204 back which I believe is 204 uh no content yeah because we don't need to send any content back because we've just deleted the content that we would potentially want to if you run that again we will get an error saying you know fact not found because it tried to it didn't error it just returned none and so we can retroactively erise the fact so yeah that's all I wanted to show in this video as a little bit of homework see if you can work at how to list all the facts and I'll give you a hint it's very similar to get fact it's actually even simpler than get fact um so see if you can list all the facts stored within the database and if you really want to you can add an edit as well a little bit of a thing for that it would be either app do put or app patch depending on what you wanted to do this is part of the reason why I didn't really want to talk about it because there are two different things for edit um but I'm going to leave that as homework for you if if people really want me to talk about it I will make another video about it but for now I just wanted to keep things really simple so you sort of understood what was going on within fast API how the status CES work how the response models work uh and yeah this response model is actually responsible if I go back here for what have I done I'm not sure what I've done here actually oh there we go I just clicked that for um rendering all of this so in these examples here you have your responses and this is um this let me know in the comments what you plan to build using fast API I want to know what sort of things people are getting up to I want to say a massive thank you to all my members and patrons on screen now especially Mazar Rosman II third for being so generous if you want to know five ways to optimize your python code then make sure to check out last week's video but I'll see you in the next one where we do whatever we do next
Info
Channel: Carberra
Views: 1,449
Rating: undefined out of 5
Keywords: pyfhon, pytho, pytbon, pytjon, ptyhon, pytyon, ptthon, pyyhon, pythn, pythoh, pythpn, ython, pytgon, pyhon, pytohn, phthon, oython, pthon, pyghon, pythoj, pythno, pythkn, ypthon, pytuon, lython, pyrhon, pythom, pythob, puthon, pgthon, python, pyhton, pythln, pythin, pytnon, pyton
Id: ICnKq9fgLrI
Channel Id: undefined
Length: 21min 17sec (1277 seconds)
Published: Mon Mar 18 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.