FastAPI with SQL - Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] what's going on you guys and welcome back to the channel in this video we're going to be doing some more fast api however a bit more in depth compared to the last videos so we'll also be integrating sql within fast api using sql alchemy and if you're familiar with flask then hopefully this shouldn't be so much of a learning curve if you're new to fast api but yeah it's pretty simple in terms especially in terms of code like we don't have to write too much i think python allows us allows that anyway um but yeah like as you can see here we'll be uh creating users and we'll also be creating posts uh we'll also be making use of query parameters so um like here we can specify like our parameters in our get requests um and also with posts we can also we'll also be updating posts deleting them and getting like uh a post in general so all the basic crud stuff which is create read update and delete and yeah also one thing to point out as uh as we'll be creating users we won't be focusing on authentication that i'm saving for another video and i want to make this as clean cut as possible in terms of information so it's mainly just the basic crowd functions in an api and how we can apply that with fast api and the database but yeah like hopefully you enjoy this video the code for this demo will be in the description below so go check that out if you don't hear me ramble but yeah hopefully you enjoyed this video and now we'll jump to the code so let's first start off by setting up the project itself and to do that we'll first create our python environment so i'll just make that a bit bigger and hopefully you can see that so what i'll be running is python three python four python three uh dash m v e mv vmv so i use virtual vm or ven for my virtual environment um and yeah you can use whatever preference yours is uh but in this case i'll be using this and i'll be naming it vmv so in order to activate it we will do source vmv tab bin activate like so and we'll see or you should see the name of your virtual environment with within brackets uh and yeah this is set up with inside a yeah just create any uh directory or folder and then just within that set up your virtual environment because now what we're going to do is create the source folder and this is where our code is going to live in so we can do source like so and here in this uh like file viewer we will see source and i'm using vs code uh you can use pycharm if you want or whatever text editor you prefer so within source we will create the underscore init underscore underscore init dot py and of course we won't be writing any code in here i'll just make that a bit smaller and get rid of that and now we can first we'll first start off by creating our database and for that we will need the sql alchemy so we can do pip install i'm using pip so whichever package install python installer package you use uh go ahead and use that but sql alchemy like so sql in capitals alchemy with a in capital and then spell like so hit enter and then we have it and whilst we're at it as well we can also install let me just clear that we can install fast api fast api like so so fast api open square bracket all close square bracket now that's done we can let me just clear that and just make a little bit shorter so we'll first go about creating uh the sql alchemy like database or like setting all that up for us to use later on so to start with we'll do import sql alchemy as underscore sql and if you've watched any of my previous videos and you'll see how i import things and rename them with an underscore the reason being is to keep these imports protected so if you're using like if you're ide or if you're using pylint then you will it will this it will it will warn you that if you're importing something with it underscore that you should be doing that as it's protected uh and yeah that's um more of a preference if you want to import sql alchemy and without that then yeah by all means just make sure to replace where i put underscore square alchemy etc so we can do import sql alchemy dot ext dot declarative and we'll name that as declarative nice yeah and then we will also import the orm so sql dot orm as underscore or like so and yeah so we'll be using sqlite we if you want to use postgres then yeah by all means that just a couple slight changes um so to start with we can do sql alchemy capital alchemy uh database url like so and we'll say sqlite so we will use sqlite um and we'll say dot within this uh like within the source folder create database dot db oh and yes um like down here in the bottom right you'll see formatted black is not installed i'm going to click yes on that uh just to format my code in a nice way if you prefer auto pep8 then go ahead but i'm just going to hit yes and if that didn't show up then you can always just install black like so so install black and i recommend it it just keeps your code in like a nice style format that's consistent but yeah so now that we have the url we're going to go ahead and create the the engine the sql engine so to do that we'll say engine equals underscore sql create engine yeah create engine like so we'll pass in the url and we'll and for sk so for sql lite um we need this like argument so connect args and i'll explain in a second check the same thread and we'll set this to false yeah so the reason why we need this is by default sqli sql lite uh only allows one thread to communicate with it and as we're using python and we're making use of like normal python functions uh then we could have our python functions allow for more than one thread to interact with the database and we want to set this to false as the sqlite will have different threads i guess coming towards it but again like my maybe my explanation wasn't clear enough but i would definitely recommend reading up on that as i don't want to go too deep into uh secure sql alchemy in this tutorial so yeah now that we have the engine we can go ahead and start creating the session so this session will say so session local as it will be a class underscore orm dot session my id is pretty slow today session maker uh and we'll set auto commit to false we'll also set auto flush to false and we'll say we want to bind this to the engine like oops like so and yeah this is a class like it's not like um it will be we'll use this as a database session it's not a day-to-day session now as we haven't created an object out of it but we will use this in the future to create sessions uh and finally we want to create the base uh and i'll explain the second what this is very briefly so we say declarative based like so and this is what we'll use as when we create our user model and our post model will be overriding or inheriting from base but yeah that's really it that's all it takes to or 13 lines um to create the to set up sql alchemy and from there like that's really it we haven't created any databases yet we'll go ahead now and create the model to get started with our models the first thing that we want to do is create our models.py file like so and so if you're familiar with django or flask then this is basically where we define our tables so how we want our sql tables to look inside the database the other thing to point out is model the word model takes a different form when when using pedantic so as fast api makes use of pedantic which is kind of like a type system typing system for python which is a bit more stronger than the word model means something else but in this case where it just means for our sql table or tables so we'll be creating two tables so we'll create the user table and also the post table to begin with we can start by making all the necessary imports so import sql alchemy as underscore sql and we also want the orm from sql alchemy so orm as underscore or like so and we also want to make use of our base here so this base that we create here as we'll use that to inherit when creating our user and post models so we can do import database as underscore database and we can begin so for the user we'll do underscore database dot base like so and we can go ahead and add a name to it so table name underscore underscore so these are two underscores here and we can say users create an id so we can add sql.column underscoresql.integer so the prime we want this to be a primary key so that's true and index also to true as well so now that we have the id we also want an email column so pretty much how like if you've used flask or django like i said then this might be quite similar especially if you if you've used sql alchemy in general i guess um and we can say the we want unique to be true as we don't want the same email in our database and we can also set index equal into true as well we can create a hash password as we don't want to store our passwords in plain text and also just as a reminder we won't of course be doing authentication in this um more so just crud and databases with um fast api so sql dot string like so that's it and we can also add is active so whether or not the user is active or not and this of course will be a boolean and we can just set default equaling to true so when a user is created by default is active will be set to true and finally we can do the post so the post that the user has and this will take the orm dot relationship and we can say post and this will be the name of our model which you'll see in a second and we can set back populates and we want that to be owner and now we can create the post model so database base and the table name will be posts we want the id same way we have the id in the user table in the user model like that we want to give it a title string um and we want to set index nothing to true there we want the content so this will be the the content of our post set sql to string as well index to true we also want to add the owner of the um of the posts so which user created it we'll set the owner id as sql.column this will be an integer and we also want to set this as foreign key and the foreign key will be users dot id so why users and that's because we've set the table name as users so look for that and not uh user so that's why we've put users.id so now we have that we'll add two more so the date created and this will be of course a date date time and we want to set the default to the the time it was created so we can go ahead and import dates time as um dt and we can set default equaling dt dot datetime.utc now and we can also add another one which is fairly similar so dates last updated and that's because as we will also be updating our posts it'll be nice to have this uh information there as well like that and we can literally copy this for now as we'll set the last updated to the time it was added by default and there we have it and finally we can specify owner and that will be the orm dot relationship and now i have user back populates and we'll equal posts like so so basically when we look at our user as you'll see in the api which will probably make it more clear we will also see when fetching a user for example or users will also see the posts that they've created too so this is what this whole back populates does yeah and that's really it like we've basically created our models for this tutorial which is the user and the post and we have the relationship between the two next we'll go ahead and create the schemas so that's what flask api flask api fast api will be using to kind of as validation for the data it's getting and for the data it's receiving and the data it will respond with or this the form i have the data at least and that's what we'll go ahead and create now so we'll now go ahead and create our schemas or our pedantic models and the reason why i say pedantic model is because there is a difference between a pedantic model and also the sql tables or the models that we've defined here in models.py and yeah all this will become hopefully become a bit more clear schema we'll just sorry schemas dot py and yeah hopefully all this will come a bit more clear as we progress so to begin with um we wanted to go ahead and create uh or import or make all the necessary imports as we'll be using pedantic we can import um so we can say from pedantic we want the base model uh actually we could probably just do import pedantic as pedantic like so and we will use the base model that comes from it so we'll go ahead and create our kind of like serializers um i think that might be the clearest way to put it so um this will basically uh shape the model or the data which the api will receive and the api will respond with so that's what we'll do here this is we want to kind of lay out what our responses and our requests will look like so we can create our post so we can create post space and we'll use this to inherit later from later on uh we can add an underscore as this will be private to the um to this file or protected to this file i'm gonna do pedantic dot base model like so and now we want the title as title will always be in there and we say set that to string so we're not declaring anything we're just setting the types so when we will have like a title and that will always be of type string we also want content which will also be of type string like so and now we can go ahead and create the um like post create so this is the sort of this is the data shape that we want when creating a post and we want to inherit from post space like this and these are just naming like better ways to name it so we're quite clear on what we're using when creating our api and this would just be pass as when creating a post we'll only be sending the title and the content like we won't send the id because the id doesn't exist where we won't be sending um yeah like the date created all the date last update is that will be created on the fly and we don't know that yet so now that we have the post create we can just create the post in general so this is what we'll use to read a post and this will of course have everything else so have um the id uh the title the content the owner id date created and date last updated so we can say like the id will be an integer the owner id will also be an integer so the date last updated date created sorry will be a date time object so we can also import that so we can do import date time as underscore dt and we set underscore dt dot date time date last updated as well so we can say that will literally be the same in terms of type so that will we take time like so and that's really it and the last thing to do for this is to create our config class with inside uh the post class and the reason why we're doing this is by default the orm mode is set to false and we want this to be true because we want when we let's say when we load our user we want the post to come with it if we look in our model the user will hold posts uh and we want that to show along with it like by default like um sql alchemy does lazy loading and we don't want lazy loading here we want to show the posts as well uh if if you were to use lazy loading then in order to see the posts you'd have to do something like user.posts like so in order to see it and then it will go and fetch it but with orm mode set to true it will fetch the posts uh as well and that's what we want here and all this will become a bit more clear if you're if you're confused right now then hopefully it becomes a bit more clear later on and now we can go ahead and create our user so we can say class underscore user base and that will take pedantic dot base model and here we'll have the just the email and then we can do class user creates and now inherit from user base and that will also have both the email and password so when we create a user we'll be sending the email and password and we can set that to string and finally we can do um use a just the the read one the one that we'll use for reading a user and what we don't want is the password we'd never want to return a password we do however want to return the id of the user which will be an integer we want to return the email and that will automatically be in there as we're inheriting from user base we want is active which will be a boolean and finally we want the posts that the users created and we need that to be a list so we can import from typing import list we can say that will be a list of a post so this here and we'll set that to a empty array if there are no posts and we can also do class config we don't want lazy loading or mode to true yeah so okay so to kind of go over this when we're creating a post for example what will we do when we send the body or have the um title as is as we put past here so it'll just be title and content so we'll say title this is a title and then the content like so some content for the post and that's all when we create that's the data we'll be sending um for like the post in general like we can take this so for this guy here we'll be doing um like it'll have the title and content we'll also have like the id let's say that's to one uh the owner id so like owner id let's say that's owner 23 etc and date last created date last updated um and the same goes for that so this is when we read a post we'll get back like this like that along with um date created and then like yes i'll have a date in it like i don't know um yeah and uh i will have date last updated as well and that's what what that's the format we'll get when we read a post so date last updated and that's what that will look like and the same also goes for users so when reading a user um we'll have the id is active and post when creating a user will only be sending the email and password and that's really and yeah if this uh is still isn't 100 clear just yet then um yeah hopefully the rest of the tutorial when we create the api then that will become a bit more clear in terms of why is it that we're making these schemas and how do they come into play but yeah now we'll go ahead and move on to yeah creating the api and getting everything up and running so to start off with creating our api we want to create two files so the first one being main.py and this will basically be where this will be where our api lives and we also want to create services dot py and this is to just abide with like service like this like service layer architecture um we don't want our main.py to have access to um like the database or anything like that we want access to the services in main.py and that will interact with the database so it's like a middleman services.py between our api and our database so to begin with what we want is to make all the like necessary imports so we can import fast api as underscore fast api and we can go ahead and create the app so app dot app equals underscore fast api dot fast api like so and we can use this now as our decorator when creating our end points and uh right now we don't have our database like we haven't created anything you don't see a database file here either so in order to do that we'll create that within services and so what we want is to import database as underscore database and we can say create underscore database like so and we can return underscore database dot base dot meta data not create underscore all some reason my id again is slow like we're not seeing the auto complete but this should be fine so this creates our database and now we can go ahead and use that so we can import services as underscore services and we can say underscore services dot create database and what you'll see now is here in the directory or the the directory navigator on the left side of my ide you'll see database.db being created when we run the api so to actually run the api here in the terminal we can type in uvi corn main colon app and then dash dash reload so uvi corn main colon app dash dash reload and the reload there just so when we save changes in our code base the server will restart for us hit run and there we go we have database dot d but db in here in the uh file navigation so now we've created our database we can now go ahead and create our endpoints so the first one that we want to create is our um like to create a user uh so we can do app dot post forward slash users and we want the response model to be a user so response model being there so we need the schemas now so we can import schemas as underscore schemas and say schemas dot user and so like if you remember like in the user will be displaying the email not the password because we don't want to return the password when reading a user the id whether it's inactive and the posts so now we can say create user and here like with response model like that's basically saying this is how the data format for the response of the api will be response it will be uh schema.user not the request itself or the information that we're sending to the api and that's what we'll do here so we want to send the this uh the user creates when creating a user so we want the password the email and password and um we want to create our database session so to do that we need orm so we can import import sql alchemy dot orm as underscore orm and we can say underscore orm dot session like so and then we need to actually create the session so we don't actually have a session right now so within services we can go ahead and do that so to say we can do so we want the database so the database session and the database will be represented as a session so the getdb and the db and the database equals underscore database dot session local so remember this that we created like now we're creating an actual session we can add a try block here so we want to yield the db the database and no matter what happens we always want to close the uh the session off so the kind of session we're having with the database and so now we can do equals um the like we want to depend on that so it's our like dependency uh we can do fast api dot depends and we can say services dot get db like so and this isn't a function call um it's just dot get db underscore db and yeah so um that does seem like a bit of a mouthful especially for python we're using types here so uh user colon will be of type user create um the database will be of type uh oram uh and you can see if you like highlight over it it says uh manages persistent operations for orr mapped objects is basically like our database like a session within our database and um that will be that will be set to the database that we create uh here like our session here like i don't want to go too much into this this is more of a sql alchemy sort of thing but that's that's what we need um and we can go ahead and create the user so we can say db underscore user equals uh and we want to create a service that like first checks so we want to first check to see if the email that we send is already in use so what we want now is to create a we want to create a method that basically gets user by email and this will take in again like uh an orm session so we want to imp import um oops here so import sql alchemy.orm as underscore orm and we can say underscore orm dot session so we have type session and we also want to pass in the email like so and this will return the like uh where we will return either if the email does exist it will return like the user a user instance um of that and if it doesn't then it will return none so we can do return db dot query underscore models so we want to also import models as underscore models and this will do models oops models dot user and we want to filter by the with the email so we can say models dot user dot email and whether or not that equals the email um that we've uh passed in here and we want to get the first in the first like uh instance of that there should only be one and we just want the first one as filter will return like a list of it um we just want the first element so now within main.py we can go ahead and make use of that so we can say database user equals services dot it's not loading um my ide is i don't know what's what's wrong with it get user by email i think that's the name get user by email and we can pass in the dbsdb and the email will basically be passed in as email equals user dot email like so i'll just make this smaller so yeah now we want to check to see if if db user exists then we want to raise http exception saying that like okay look the user is already in use and with the status code of 400 um has like a bad request so we can say raise underscore fast uh api dot http x section like so and we want the status code to equal 400 and the message so we'll say detail equals let's say whoops the email is in use otherwise we can just return we can create the user so to do that we can go back to services and create a method that says create user so we can do create user and this again will take in like the uh the orm session so a database session so we can say oram session and we'll also take in the user which is from schemas so we need to import schemas like so and user create because it will take in the email and password and then from there we can go ahead and create and hash our password and again this will be very very weak i like do i do not recommend in any situation to use this as a hashing way as hashing a password um say hey fake password and we'll say user.password and we can say let's put like a message this is not secure like so and then we can create our user that we want to store so we can say underscore models.user and this will take in the email which is user dot email and the hash password which will be the fake password like so and then we want to add that to the database so db add db underscore user and we want to commit that and we want to refresh on the instance so add db underscore user and then finally we can just return db user and when we return that this will be in the format of this response so the user so read it and then format it so that it aligns itself with the schema so i have an id email as emails coming from user base is active and posts and will not include password as we haven't included anywhere here and finally we can say return services dot create user and we'll pass in the db which is this thing here and the user as user yeah hopefully this works now we can go check it out so as the server is already running all we need to go to now is one two seven um one two seven uh zero zero one and then the port eight thousand eight hundred eight thousand and yeah you should say detail not found that's because we haven't created a root um endpoint but we can go this is what i really love about fast api is that it comes with this really nice interface you can go to four slash docs and there we can we have our interface with users so we can interact with our api like this so now let's try this out fingers crossed it works so we can say email and again there's no email validation here either but we can say something like john gmail.com password this is some password execute it we have an internal server error and that is because um yeah it's just here model is not defined let's just fix that um [Music] models and this is because my id is very slow today so i apologize otherwise we would have seen that before hopefully everything else aligns let's just refresh this so we can try out now email john gmail.com some password execute it and there we have it we get our response which is this thing here so email we get the email and this is where the schema will come into play so we've asked for email actually let's just copy this here if we go back to our schema now um we get our email and as we're using user as our response model here so schemas response model equals schemas.user and dot user is this bad boy here so we get the id which we have we get the email which we get from user base as we're inheriting from it we get his active as true as we set that to by default to true and we get all the posts and because john gmail doesn't have any posts we get an empty array so yeah hopefully that makes a bit more sense now um but yeah that creates our users we can now go ahead and create some more endpoints for our user so we can say like read users and this is where we'll make use of like query parameters so we can say app.get again this will be forward slash users same as before and we want the response model to be a list so we're getting all users so we'll return a list of all the users that we have and we can import that from typing so from typing import list so list and that will be of um like the user so we want dot user like so we could also name this to user read but i think users find here um i'm going to say read users and we want to add a uh we're going to add query parameters so the starting point and the finishing point and we also want the ourselves to adjust it so we can say skip which is of an integer and we set the default to zero we can set limit to integer and we can set that to 10 and we also want the database session here so we can basically copy that but i just want to type it out um as like i don't want to make this to look too busy by just copying and pasting it so what we want is to pass in the orm session and that will again fast api.depends and we can say services.getdb and again not calling get db so now we have um read users we can just put pass here for now if we go back to our interface hit refresh and we get this the get read users and of course we don't like it doesn't work right now is where there's no there's nothing inside this um endpoint so um we want to go ahead and create create a service that allows us to get all the users so this is pretty simple we can go ahead and say get users and this will take in an orm session like so and uh we want to set these we will also be passing in skip which will be of type int and the limit which will also be of type print and what we want now is to return all the users so we can say db.query underscore models dot user and we want to offset so the offset will be the skip and we want to limit the amount by limit and we can just say all so like if you imagine um just to quickly go over it like if we had a list of let's say all these objects um that that oh how to put it um apple orange and it's basically just like a array like slicing a raise um pine apple and mango the uh the skip part is like how many do we want to skip because we've set this by default to zero it will include apple if we were set to skip to one then it would go past apple and start with orange and the limit is like where do we want it to end and by default we set it to 10. so that's our get users and now we can make use of this service by saying like within read users we want to basically just return we can say users equals services dot get users and this will ask for our database sessions we say db which is this skip equals skip so like zero by default and limit equals limit like so and then we can just do return users or we could just put this all in one line but just to make it clear so now we we have this working so if we go back now like remember we already created um a user so we can try out click try out and we can leave that there and there we have it we have a list of right now one user we can go ahead and create another one so uh actually let's try out let's say if we need to use john gmail again so if we do john gmail dot com uh i don't know hello world execute then we get this we get the 400 code whoops that email is in use so we can try something else so we can just clear that we can say um carol gmail.com execute and there we have it we get our we get carol and now if we go back up to get users we can execute again and now we have carol and john um and yet for if we want to skip so we could say like one execute then we just get carol because it goes past john it starts at the first index so index one instead of index zero uh and also if you want if you're interested in like the um the url uh or the request url uh we can set this we can take this oops we can get this url open up a new tab paste that in and we get carol if we need to set skip now to um zero then we get uh all of our users so john and carol but yeah like um this can be difficult to read of course um and swagger ui helps us with that so now we have uh read users and create users we can also just add another end point where we can read a in an individual user so we can do app.get and we can say forward slash users and then we also want to specify the uh user id so we're only returning like one user here so you can say response model schemas and we want to use the user and we can say read user so not users but user and as we're only returning uh like a single object we can't really use query parameters for um for our list um so we want to pass in the user id and we want the user id to be an integer the db session of course being um underscore orm dot um session and we'll set that to fast api dot depends services.getdb okay and now we can go ahead and like get the user so we can say we can create a service saying get user and in order to do that we can go ahead and say get user db or and session and we also will pass in the user id which is an integer and now we can query our database so we can see return db.query models.user i want to filter by the models dot user dot id and we want to check to see if it matches with the user id that we pass in then we do move on the first one as it will return a list so hopefully that works there's no typos here we can go ahead now and say db underscore user equals service and we can say because my id is so slow we can do get user pass in the database and the user id like so so what we want so what if we pass in a user id that um doesn't exist we also want to raise a 404 there as in like not found so to do that we can say if db underscore user uh is none so if it doesn't exist it'll will get a response from services is none we can raise fast api again http exception like so and we can say status equals 404 and detail we can say it to um sorry this user does not exist so creating a very fly api here exists so that's if the user doesn't exist if it does exist then all we have to do is return db underscore user like so so now we can go back refresh so we can say not this one sorry oops in uh read user we can try out and say one that should be john execute it then we get john gmail.com as a response we can do two which should be carol execute we get carol now if we need to do three what we should expect is a 404 an error message execute and we get an internal server error which is kind of expected keyword argument ah because this is status code it's the problem i'm blaming my id here um ide here as it's not helping me do the autocompletes i'm heavily reliant on that um but now if we just refresh there we can try out let's say like five which shouldn't exist and there we have it we have our 404 code and our little message saying sorry this detail this user does not exist and that's really yeah that's basically the user created what hopefully like there is a lot going on i think a lot of it is also us doing the typing and setting defaults that's why it looks a lot busier compared to like a standard python um like methods but i definitely like fast api like really wants you to do that because it allows us to know like because we're using user create within user if my ide isn't slow we can get the pass email and get password like if we were to do like dot id that wouldn't work because user create doesn't hold the id uh it doesn't call like is active if we would set this to dot user then we would so if we go back here down to where we're using so this one here uh actually not this one but if we were to accept that to user like so then we could do um user dot id is is active etc which we don't want we just want user create here and that's why um this is where pedantic comes into play as it's kind of like this type validation for our api the data is getting and the data it will respond with and to reiterate this is our response model so return a user but when we send a user to create a user we'll be sending the email and password not id or is active as those things haven't been created but yeah that's basically our user endpoints created so we can um we can read users we can create a user and we can return like an individual user and now we'll go ahead and create the endpoints for our posts so we will do creating a post reading an individual post reading all posts um updating posts deleting posts and that's really it yeah and you also see within our users you'll see the posts that they've created so as we create a post um if we go here is it like an example uh within posts we'll have like all the posts that given users created but yeah now we'll go ahead and do that so to get started with posts um we can go ahead and start creating our endpoint so we'll do a create post endpoint and that will basically be app.post and then forward slash users forward slash users forward slash user id because we need the id of the user and then posts like so forward slash and the response model will be schemas dot post and this will be what was returned from or how the api will respond once you've created a post and now we can do create post and this of course will take the user id which will be an integer we want the post which will be schemas dot post create and finally we want the database to be orm dot session which will equal fast api depends on services dot get db okay and we can just for now just put pass for now um what we want to do is first um get the uh the user so we can to check to see like if that user exists we want to return like uh um like a 404 uh or a 400 like a bad request um in this case we'll do we'll just copy from above so this here and so we have the user get and get user um and we can say 404 sorry this user did not exist and now we can create a service for creating a post oops so below getuser we can say create post so to create a post we want to do get post i'll start on get post create post this okay again we'll take in the uh session and the post which will be schemas dot post create and also the user id which is an integer and to do this we can do post equals models dot post and we want to unpack so we can do post as a dictionary so this will get the title and the content or pass that in and we also want to set the owner id as the user id so now we've got our post um what we can do is just now add this to add the post to our database we can say dbe dot commit and we want to just refresh on the instance of post and finally we can return post like so so yeah pretty simple and here back in the main.py in create post we can do return services dot create post and then we can set db the post which will be post and also the user id which is user id like so hopefully that works the no errors uh we can go back to the interface hit refresh and we can see now that we have a new post which is for creating post so create post we can try out let's say user id one so for john gmail.com we set the title to this is my first um post maybe this isn't you have to zoom in a bit uh to make it more clear this is my first post um hello world as content would say hello world i just wrote my first api using fast api and now fingers crossed execute it and there we have it we have our post so we have the title it responds with the post schema and there we'll have the um the title the content id owner id date created date last updated there we go that's it and then if we go back now to um let's say we want to get the user and we want to get john so we can say 1 execute and now we can see here we have posts and we get the posts that come with john and this is where that whole orm mode equals true comes into play because it fetches a post as well um but yeah that's that's basically create post now we want to do we want to add some more endpoints so we want to read posts and this will be quite similar to this here so the read users um so we could yeah let's copy it for now and just make the adjustments so get users um we don't want that we want get posts so we set this to posts the response model will be a list of posts uh we can keep the skip limit uh and the orm session [Music] and now instead of um getting um like the changes to read posts like so so instead of uh getting users we can instead creates we'll save password now and we can create our service for getting the um like the posts so in services we can do um like a method called get posts and this will take in an orm session and yeah that should be that should be it uh apart from like we won't skip um so that we already set a default so we could understand default here uh limit which is also an integer so yeah now that we have that we can just do return db.query and we want the post model and what we need is the offset so quite similar to this here so we can sort of copy it let's just add it in like so so uh offset skip and limit limit i'm going to do dot all like so and that's gets our post and all we have to do now is back in main dot py we can just say posts equals services dot get posts pass in the db goes db skip skip and limit equals limit and we can just do return posts like so and that's that endpoint working so just refresh this and we do post so this one here read posts try it out execute and we have a list of all our posts so for now just one but that's that end point working fine um now we can go ahead and read an individual post so to do that we need to create our endpoint app dot get posts and we can say like the id of the post so post id um which will be post underscore id the response model will be the schema of posts you can say read post and this will have the post id which is a integer the db session so we'll have again underscore rm session equals fast api.depends services dot gets db so we can put parts here for now and then back in services we can create a function that basically returns a individual post so to do that we can do just do like get post so not plural singular and this will take in underscore orm session and the posts id which is an integer and then we can return like a the the a post with the id so we can say db.query models dot post filter and we want to filter for models a post dot id equals post id so we want that and we can just say fast and that should do it so we can do just return services dot get post and we say db equals db and post id equals post scroll down a bit id um we also we we could also add like this here so like a http exception uh and we could do a not found so what we can have is um we could actually set this to post if post is none we can raise just copy that this post does not exist otherwise we can just return post so yeah that should do the trick so if we go back to our interface we can now check it out so we do read post and the id of the first one is one execute and there we have it and if we were to do let's say two execute then we get our 404 error and sorry this post does not exist so yeah pretty simple like quite repetitive to like the the user but now we can go ahead and spice it up a bit more by doing a delete request for posts and also an update so we can say delete post path sorry dot delete and within that we can say the post post id same as get and there we can do delete post and this two will take in literally the same as um like reading an individual post we want to delete it based on this id and let's just say pass for now so yeah if we go back it's quite cool because it like it color codes it so delete is shown in red of course this doesn't do anything now but it's quite nice to like categorize them by color as well so now for delete post we can go back to services and create a method that allows us to do that so we could say delete post again this will be underscore orm dot session and then post id is an integer and we can basically we could make use of that but i just want to keep it um like understandable so we can say db.query [Music] models.post let's just copy this actually uh and then we can um filter by that instead of doing dot first all we have to do now is don't delete and the last thing we want to do is just commit that and we can do this now so in main.py if we go back we can go ahead and implement the delete so we can say services dot delete post db equals db and then post id equals post id and then we can just return a message saying um uh like successfully deleted post with id and we can say post underscore id and there we have it so now if we were to go back hit refresh um in delete we can basically say uh we can try out we can say post id one so that's the one that we wrote execute it and there we have it messaged deleted a successfully deleted post with id one and if we were to go back to reading all the posts try out execute we have no more posts so uh yeah that's that we can go back and add uh our post now i think it might be good to have one so we can create posts because we'll need it now for updates so let's just create a couple so for one we can say a cool title and for content we can say some amazing content for this post execute it yep that's not there uh we can create another one so uh we'll create another one for john we can say and what's really cool is that like you just have to adjust it and execute again so we don't have to keep going back so we're gonna create another one so we can say um this is another post fast api is awesome execute that and there we have it so if we go back to um posts uh and we execute it so now we have two posts i mean we could create other endpoints or like all the posts um yeah like we could do like put on patch i'll patch later on all the other fancy kind of um http requests we can make but we'll stick to just basic crud um and yeah that's really it so we have two posts now uh we can delete them if we want but it's all good for now um so now finally we can go ahead and implement our last one which is to update a post so we can do app dot put and this again will have the same url put that in we can let's yeah let's just copy this for now so we can copy delete we can say update post post id we want db session we want and this we can keep put past for now so if we go back and if you look at the colors now we have a put so which is really nice and yellow yeah it just looks really pleasing to the eye and makes the interface so much more understandable okay so in the services we can go ahead and create a method that allows us to update our post so to do that we can do update post again takes in a db session orm session post id which is an integer and what we want now is to get the db po get the post so yeah i mean we didn't make use for it and delete post but we could probably make use of it here so db post equals get post oops and we can say db equals db post id equals post id and then we can do db dot title equals the um ah sorry um what we want uh is uh okay so we go back i made a mistake here um so in uh update post um yeah of course we want the post id we want the database but the last thing that we want or one thing that we want to put it here in between um we also need the post so post create so schemas dot post create sorry bit tired um so apologies to that mistake but we also want the post create because we want to update the title and uh the content we also want to update uh if we go back to models the date last updated however we won't be passing that that will be generated within like the in the within the server so we also want here the um post so we can say i don't know where my head is post create like so there we have it so um yeah now we also want post create so in our services what we can now add is um so like db post dot title and we want post dot title db post dot content and we want post dot content and finally we can just do db.commit so commit our changes we also want to refresh on the instance so db underscore post and we want to return um db underscore post like so we'll go back to main we can set the response model to schemas dot posts so we'll return the post itself we also want to before i forget we want to change the db dot underscore post dot last update last updated so if we go back to models date last updated and we can say we can import time date time so say import date time as underscore dt and back down here we can say underscore dt dot um datetime dot utc now and that should work so we can go back to main and here we can basically say like we can just make use of the the update so we can just return underscore services dot update post they want the database post which is post and post id which is just post id like so so now if i am not too tired and i haven't made any mistakes there shouldn't be any um errors when using the put request so input we can say post id what posts why these do we have so we'll go back to repost try it out execute so let's change this one here uh with a cool title so we have that so keep in mind it will be id1 here and we can try out say id1 and we set the title i have updated the title i have updated the content so the desired response we want now or the expected one is um a cool title will be changed to i've updated title and we also want and the same goes for content we also want to update this as well so this should change it shouldn't no longer match day created so we can execute that hopefully no errors and we have an internal server error i think the reason is in services i think we can do now like so hopefully that does a trick if we go back we want to uh put and like i said they are like this video has kind of gone a bit too long and anyway like in terms of time so if this doesn't work out then i'd skip over the whole updating last updated but hopefully should be fine uh updated title and updated content fingers crossed and there we go we have it we have uh this working now so the times also adjusted so this was created at 108 and this has now been created at uh 3 17. yeah so and we've updated our content so if we go back now to like get i'll read post we can try out execute and there we have it updated title updated content and that is working fine so that basically concludes this tutorial i know it dragged out for a lot longer than i thought it would but hopefully if you followed along then you have an idea of how the how to integrate sql alchemy or sql within fast api and also some of the basics around it uh i'm thinking uh for my next videos to do further to do some more content on fast api on more of the basics so without this whole database integration or like user authentication and also jumping into other languages like golan so if you are interested in that or if you want to see more content on that please like and subscribe um and yeah comment to let me know what you thought of this video any feedback and also what you'd like to see more of but yeah thank you very much i hope that you enjoyed this video again the the code for this will be available in a git repo which i'll put the link in the description so if you want to check that out feel free but that's about it and thank you for watching
Info
Channel: rithmic
Views: 31,424
Rating: undefined out of 5
Keywords: Python, FastAPI, Python Project, SQL, SQLAlchemy, Software Engineering, Programming, Software Engineer, Code, API
Id: eltKL8kC160
Channel Id: undefined
Length: 79min 31sec (4771 seconds)
Published: Sat Apr 24 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.