Building A Simple REST API with FastAPI in Python

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] what is going on guys welcome back in this video we're going to build a simple rest api in python using the module called fast api now i have a video already on this channel where i do the same thing with flask but the problem with flask is that it is a full web framework so it's a little bit overkill to just build a simple rest api uh so you can do much more with it and if you just want to build a rest api there are better options also fast api does a lot of the stuff that we want to do automatically writes documentation automatically and so on um we have um we have to manually specify types which speeds up the api because then we don't have to check for the types uh fast api does the validation for us the documentation for us the checking of the types for us everything is done automatically and when i talk about documentation i don't just mean that fast api is well documented they document or the tool documents your api automatically that you're building so you don't have to uh design your own documentation page your api is already documented by using fast api so let's get into the code let's get into the implementation the first thing that we want to do is we want to open up cmd uh or your terminal of choice for example your terminal on linux and then pip or pip3 install and we want to install fast api this is one thing then we also need something to host the api for this the fast api tutorial recommends uv corn and later on we're also going to use pydantic uh i think we have to install this as well i don't think that it's uh pidentic i don't think that it's part of the core python stack so all these things are used in a tutorial everything i show you today is based on the fast api tutorial itself so i don't have to um i'm basically just providing examples here so you can go to the fast api tutorial and read it it's a text-based tutorial in this video here i'm giving you a video based tutorial and i'm also showing you um an example on how to use these things but basically you can read that on the fast api page as well so what we're going to do first we're going to import from fast api we're going to import fast api like that so capital f and capital api and then we're going to define a new app this app is going to be uh just fast api constructor and now what we're going to do is we're going to define functions for example hello world function and then we're going to add a decorator an annotation to that function to map it to a certain request type on a certain path so for example if i have a very simple function hello or let's just call it hello and this function returns a dictionary so a json object basically where i pass as a key hello and as a value world like that this is a function and if i want to make this function uh be triggered at a certain get request for example what i do is i go um above the function and i say at app dot get so i'm using the app and i'm saying dot get and now i have to specify a path if i just pass um a slash this basically means the base url i can also say slash hello then it's going to be triggered if i make a get request on slash hello and so on we're going to leave it like that for now um and then we can do the same thing i can copy this here and we can do it for another uh for another path here for example something and here we're going to pass data equals something and the function is going to be something for example doesn't have to be the same name by the way so this is just my choice here in this case so once we have that all we need to do is we need to run this using uv coin so we're going to open up cmd again and uh we're going to navigate to the directory that we're coding in and here i'm going to just run uv corn and then main colon app and we're going to specify dash dash reload so that we can get live updates so once this is started we're going to be able to change the code and then we're going to see that we don't have to stop and restart this uh hosting here but we can just use it so first of all we can use it via the terminal so before we go into the browser i hope i have curl here on windows but i can just curl this um it is running on localhost port 8000 so if i curl localhost 8000 does this work i'm not sure or was did curl have a different syntax i'm not sure not sure if we have to provide like that doesn't matter let's go into the browser then we're going to check out if it works with curl as well no actually this should work not sure why it doesn't work let's restart it ah there you go just had to to run this again so maybe we're going to rerun this and i'm going to go to neural directory and then we're going to say again uv corn main app reload so now let's go again there you go now it works so basically it was just um yeah i had to restart it with some buck but now we should also be able to access it via curl so if i open up cmd and i say curl we should be able to do that and this means we can also go with post i think it was like that right yeah there you go so now if i go into my code and i also specify i don't know let's call the function hello post for example and here we're going to return you post it like that and the mapping is going to be app.post on the base path so now it should be reloaded already because we provided the reload tag and now if i run this first this should still work and if i now go and make crawl post again you can see that post is now also supported so by using curl we can just uh specify the method here and because if you go into the browser unless you have some submit button or anything a form with action post we're always going to make just get requests so this is the very basic of uh those are the very basics of the fast api all right so let's get into an actual example what we're going to build in this video is a simple rest api for managing people so we're going to have a person class or a person person-based model and then we're going to be able to add a new person to remove a person to change people to look for people and so on so a very basic example that we're going to build all of this around um and as a data storage we're going to use a simple json file now in practice you would use something like a database and the api is going to connect to the database make select statements and all that we today are going to use a simple json object for the sake of simplicity because we don't want to teach database programming here this is a fast api tutorial and because of that we're going to create a new json file and we're going to call this people.json and the structure is going to be a very very simple one we're going to have curly brackets we're going to have the people key and then we're going to have a list of person objects and these per person objects are just going to be dictionaries with id one for example with name mic for example with h 25 for example and with gender uh m for example for male and then here we pass a comma and then we can copy all this and do it with id 2 and so on now i'm not going to bore you with all the sample data so i'm just going to use the prepared sample data that i have here just wanted to show you the procedure so we have a people list and here we have the individual people with id name age gender so you can generate your own data if you want to uh what we're going to do now is we're going to import from pydantic the base model because this is what we're going to use to create our class and then we're going to let me just switch to my prepared code here uh then we're going to create a new class and this class is going to be called person it's going to extend from the base model and it's going to have a bunch of attributes so for example it's going to have an id now for the id we want to have an optional field because the id is going to be the unique identifier and everyone has to have an id but when we create a new object when we create a new person we as the user of the api do not want to provide the id the system should provide the id and we just say okay um create a new person then we know the id then we can look for the id and all that but we don't want to specify it we want the system to calculate the next id so we're going to say id is going to be an integer but it's going to be an optional integer and because of that we're going to have to import from typing uh the optional now typing is a core python module for type hinting type hinting basically just means that um we are hinting the type so we're saying this is the type of this field but it doesn't mean that python now uses static typing it's just a hint but other modules like pedantic or fast api can take this and say okay this is going to be an integer if it's not an integer i'm going to reject it for example so we're going to say this is an optional integer and it's going to have the default value of none then we're going to have a name this is going to be a string we're going to have h this is going to be integer and we're going to have gender which is going to be a string as well so this is the base model and now we can use these functions uh that we talked about earlier in order to change or um to to add stuff to a collection to remove stuff from the collection and so on in our case the collection is a dictionary which is based on the json file so in order to create this what we need to do is we need to open the json file when we start the script so with open people.json in reading mode sf we're going to say people equals json.loadf for that of course we need to import json also part of the core python stack but keep in mind that we have here the people object so we want to do is we want to actually get people alternatively of course you can also just uh yeah just have a list without the keyword but we're going to do it like that so i think this should work so let's test this before we do anything else we're going to just print people to see that we didn't mess up anything here in the process and there you go we have it this is a list of um of dictionaries that represent people and now we can do a very simple function that gets the information about one person so we're going to say get person and this function is going to have the parameter pid i'm using pid and not id because id is reserved a reserved keyword and this has the integer type hint here and what we're going to do basically is we're just going to say person equals and then p for p in um and people if p [Music] id is the same as pid like that so why can we do it like that because in in essence this is essentially just uh quarrying out the one element with this id if we assume that the id is unique this is going to return only one object now of course if we have some data where we have the same it id multiple times this will not work perfectly but if we have a unique id for each person we're going to be able to do it like that and what we're going to return is the person object so person 0 the first thing in the list if the length of the person list is larger than zero and else we're going to return an empty dictionary because we didn't find a person and of course we need to add a mapping here so we're going to say app.get and we're going to get this on slash person and we're going to pass the id of the person so we can actually go ahead now and use curly brackets here and pass p underscore id and what what this will do is that when i visit slash person 5 for example it will call this function and pass 5 here as the parameter of course these names has to be have to be the same but if i pass here as a pid 5 it's going to take it here and it's going to query out the person with the id 5. so we can see that this works by visiting the browser and then person slash one um didn't work why is that said not found let me just restart the server maybe we have a bug here slash person one there you go works so you can see we have one mic 25 m of course i can go with two and we can see we have alice here and so on so this feature seems to work now one thing that i want to show you here that i haven't showed you uh up until now is the documentation i told you in the beginning that fast api generates documentation automatically for the api if you want to see how this looks or what this looks like you can pass slash docs here and you can see that our api is now documented now i didn't do anything for documentation it documented it itself so you can see here we have get person we have the path and we can see it's a get function if i expand this you can see the description here this is an integer it's required uh and the response the successful response code is 200 and you can also see that the return value is a string and i can also use this api from this interface here so i can click on try it out and i can pass here for example 5 as a value and execute this and you can see that i got the response here so it executes a curl command actually so this definitely works and this is quite cool and the more information we add the better documentation we will get obviously so let's go back into the code now and add some more functionality now one thing i want to mention though is that of course you can also pass here the status code so if for some reason you don't want to return 200 but 201 because 201 as far as i know means successfully changed or successfully created you can just type status code equals 201 in this case we're going to type 200 even though it's the default because in this case 200 is the proper code now let's implement a feature that's a little bit more complicated and we're going to also add we're going to learn about some new keywords here i have to look at my code here because um i always forget how the keywords are written because i don't use fast api too often but the next function is going to be a search function so we're going to have uh the get person function here uh actually i can use the same name i think i'm just not sure if that's even intelligent so let's go ahead and call this function search person in the prepare code i use the same the same function name but with different parameters seems to work usually it doesn't work with python uh so what we're going to search for is h and name so we're going to filter for h and for name uh h is going to be a parameter here it's going to be an optional parameter integer and we're going to set this equal to and for this we need to import something from fast api query so query is an object we can use to define query parameters now of course i can also just pass none as a default value but with query i can pass none as well and i can also pass a title so what is this in this case h but i could also call this h if the name was a for example and i can provide a description for the documentation i can say the h2 h2filter4 for example um and this is one parameter so this is the query and then i can say comma and name is going to be an optional parameter as well it's going to be a string and it's also going to be query default is going to be none title is going to be name and the description is going to be the name to filter 4 for example then colon and then we can define the functions so there you go this is the full signature and um essentially what i prepared here i don't know if that's the most efficient way to do it i basically said i'm going to say person one so you can call this a more a better way a more suited way a better a better name that's more suited to the task but essentially what i do here is i say p for p in people if p h come on if ph equals the h so that is one query that i do and then what i do is i say if name is none what i do is i say also okay if h is also none then i return people so i return the full list if i don't specify anything so if both parameters here are none i'm going to just return all the people um if one of them is not none i'm going to filter for it now why does this work because in this case we don't have any problems because if h is none this is not going to cause an exception it's just just going to say no because none equals something is not going to be true but it's also not going to cause an exception for the name we don't want to filter for the exact name we want to filter for a substring and because of that we're going to have to make sure that that the name is not none um [Music] if the age is not none but the name is none what we're going to do is we're going to return people one so we're going to return actually person one uh maybe i should call this people one though people1 and people one uh what's the idea behind that here we only filtered for h so if someone has this h they're in the list and if name is none we're going to just filter for h so we're going to return all the people that match the h otherwise if the name is not none but the h is none so if h is none before that we need to create people two and people two is going to be p for p in people if p name uh actually let's do it like that if name in p name but we're going to also say lower so it's case insensitive like that so if whatever we pass this name is a substring sorry it's a substring of the name of a person it's going to be listed here and if h is none we're going to return all these people and otherwise we're going to say combined equals p for p in people one if p and people two so we're going to combine the lists and then we're going to return combined now notice that all this is not a uh tutorial on the api so all this part here this is just logic you can also try to implement your own logic uh what is fast api specific is the query keyword here so now we're going to say app dot get and we're going to say slash search and the status code will be one uh 200 if it's successful now what's important here is that we don't pass anything like this we do it with a query keyword and because of that we're going to have to specify it manually so let's take a look we can go to search uh not found why is that do we have to update this again this is a bit buggy so it's going to reload in a second like always there you go and now if i call this you can see that i get all of the all of the people because i didn't provide anything now i can say question mark name equals i and since mike and alice contain the letter i they're going to be listed if i say a we're going to get alice and susan all that uh and then h equals 30 for example i'm going to get the two people that have the h30 and if i also say end name equals o for example then we're going to get only bob because bob has an o and the age of 30 alice does not have an o that is a simple search function so up until now we have worked with path parameters we have worked with request parameters and now we're going to look at request buddies so we can pass a full person object as well instead of just passing the individual fields and for this we're going to implement an add person function but before we do that i want to show you that the documentation was extended so if we go to slash docs you're going to see that we have a search function here with the description that we provided with the query so indicating that it's a query parameter and of course we can play around with that as well so i can pass 30 execute we can see here we have the two uh response buddies or one response buddy with two people uh we can pass o here to get only bob so you can also play around with that as well and the more functions we add the more documentation we add or the more descriptions we add the better the documentation is going to look like in the end um so let's go ahead now and implement a add person function so the function is going to be add person [Music] and we're going to pass a full person object not just the individual fields and what we're going to do is we're going to create a new dictionary here so new person dictionary where we're going to use the fields of that object to create a new dictionary to add it to the list save it to the json file and then basically we have a new person so like that but before we do that we need to calculate the id because when we create a new person we don't want to provide the id manually the system should calculate the id and for that we're going to say pid it's just going to be the maximum value of the following list comprehension p id so the id of p where p is everything in the people list so we're going to get the maximum id by doing that and we're going to increase it by one and because of that we're going to get an id that is not in the list because obviously if we take the maximum and one more this is the new maximum uh so we can say id is pid name equals person.name h is person dot h and gender is person dot gender like that uh and all we need to do now is we need to just say people dot append new person [Music] and with open people.json in writing mode sf we're going to save the changes by using json dump the people object into the file and of course we returned a new person with the new id so this is come on now i can use the surround plugin ysw quotation marks there you go um [Music] yeah so that's the add person function of course we need to add a mapping so we're going to say app.post this time because we're adding something we're creating something and the status code for this one by the way should be 201 so we're going to say post on add person and the status code on success is going to be 201 uh let's go ahead and test this we're going to go back to the api and we're going to go to add person but we're not going to have anything supported here so we're going to this time just use the documentation uh directly to test this feature so we have post ad person and now i can just try it out to see if it works and as you can see here we passed the full json object so here i can pass whatever i want i can also leave this empty uh as far as i know it's not uh required so the name is going to be i don't know florian this is my name i'm 22 years old and my gender is male and if i now go ahead and execute this uh i get it i get an internal server error which is not good so let me just see what we have here can only concatenate list not int twist oh of course the problem is that my plus one belongs outside of the list because i want to get the maximum and then plus one and not you know add plus one to a list i hope this is now uh reloaded there you go so you see i got the id six even though i didn't provide the id six and if i now go to uh search where is it here and i try it out and i just execute it you can see that i'm now part of the list so this works this add feature we can now also create a change feature it's going to be quite simple we're going to define a function change change person and this function is going to also take a person object and we're going to say that the new person here is going to be also dictionary again this time we're going to take the id because the person should already be existing so we don't need to calculate anything person dot id name person name and so on person h and gender person gender and now we're going to find the person with this id and update it if the id doesn't exist we're going to say error so we're going to say if we're actually going to say person equals actually this time person list because we already have person person list equals p for p in people if p id equals person id if the length of this list is larger than zero we have a hit and then we basically say people remove the person from that list and add another person to that list which is the new person that we created and of course change uh save the changes to json we're going to copy this here and alternatively what we're going to do is we're going to uh throw an exception so we're going to return the http exception which i think we need to import from fast api there you go the http exception uh with the status code 404 because we didn't find it and detail is an fstring person with id personal id does not exist and of course in the success case we need to return the person to the new person essentially they go so this should also work now if i reload the documentation the api seems to be down or something i have to restart it again it's a little bit buggy maybe it's because i'm using windows wouldn't surprise me uh but also i forgot one thing so while it's loading we can add the mapping here so this time it's going to be a puts mapping because we changed something and we're going to have change person here and we're going to have a status code 204 if it succeeded because that's for change successfully um [Music] not add but app what happened now they go app and here we pass again a request buddy unable to connect let's run this again let's go to docs again once it's loaded why does it say that i cannot list indices must be oh i think the json object changed now because i saved it okay now we only have the list so let's remove the people here you need to take care of that obviously um that is the problem now i think i have to rerun this one more time because the problem is that the initial the initial json object had people as a key and then a list and then we overwrote it and we had no longer the people keyword but only the list which of course is a problem and now now it should work so here you can see again if i search i should have still everything tried out execute there you go i also have florian the new object here um now let's go to change person and try to change the person with the id uh let's actually change florian so we're going to change the person with the id six and we're going to give them a new name which is going to be neural neural nine and neural nine is two years old because the channel is i think one or two years old and the gender is going to be a for uh agender i don't know because it's a youtube channel actually so execute that and as a response what do we get as a response uh did we actually get an object response header successful response i don't think that we got a response right but it should still have changed something so let's see if it changed there you go changed neural nine so yeah yeah works now last but not least we're going to add a delete function just for the sake of com uh of completeness here so we're going to say def delete person and we're going to pass a person id i'm going to delete by id this is going to be an integer um i think this is indented too much there you go uh and here we're going to just say the person that we're trying to delete is going to be for p in people again if p [Music] id equals p id and of again if the length of the person is larger than zero then we found something and we're going to say people dot remove the person at position zero because it's going to be only one then of course update this again there you go and otherwise we're going to throw a uh an http exception with the status code 404 because we didn't find it and the detail is going to be there is no person with id whatever the id was all right add the mapping app dot delete which is also another operation and the path is going to be delete person and here we're going to pass pid as a path again and i think we can also i think this is one thing that i didn't mention let me find an example where i did this uh we can also add the same thing that we did for query we can add for path so i can also say path here um and i can make the path variable here uh as well so let me just see again where i did this uh there i did this so for example i can go here and say path none and so on i'm not going to do that right now i just wanted to mention it the same way we did it for quarry we can also do it for path so same syntax uh we're not going to do that and now if i run this again we have this function documented as well so let's go ahead and delete number six execute and we got response buddy null but 200 actually the status code should be 204 because that's the proper status code so let's go for status code 204 and this should also be documented by the way so if i go to change person it says here the success response is 204 i think it didn't update it yet for delete so maybe i should reload one more time now it still doesn't doesn't get it it doesn't matter but you can see that we get also the proper code here and uh it also shows us that we're going to i think it shows us no it doesn't show us but if i for example try to change someone let's maybe try with delete if i try to delete someone who doesn't exist for example eight and if i try to execute that i'm going to get 404 not found there is no person with id 8 and if i now search because we deleted number 6 you can see that number 6 is no longer part of the list and also no longer part of the json object so that's it for this quick tutorial today i hope you enjoy hope you learned something if so let me know by hitting the like button leaving a comment in the comment section down below and of course don't forget to subscribe to this channel and hit the notification bell to not miss a single future video for free other than that thank you so much for watching see you next video and bye [Music] you
Info
Channel: NeuralNine
Views: 44,022
Rating: undefined out of 5
Keywords: python rest api, fastapi, fastapi python, fast api, python fast api, python fastapi tutorial, python rest api tutorial, python REST, REST api in python, python code rest api, simple rest api, simple rest api in python
Id: VSQZl43jFzk
Channel Id: undefined
Length: 37min 11sec (2231 seconds)
Published: Sun Nov 14 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.