Learn Fast API With This ONE Project
Key Takeaways
This video teaches Fast API by working through a real project, covering the basics of API design, data handling, and endpoint creation, and using tools like Fast API, Streamllet, Image Kit, and PyCharm.
Full Transcript
In this video, I'll teach you Fast API by working through a real project. I'll go over everything from the absolute basics to some more advanced concepts like setting up authentication, logging in various users, connecting to a database, and all of the components that you actually need if you want to build a real production-grade application. Now, that said, this video is not designed for absolute beginners. While I will teach you everything from scratch as it relates to APIs and kind of web app development, I'm going to assume that you have some experience in Python. That said, let's quickly have a look at the finished project and then we'll get into some of the theory and start writing some code. So, the project we'll be building here is a simple photo and video sharing application. Think of it like the really early days of Instagram except it won't have nearly as many features. Now, the way this works is you can sign in. So, I've set up a really simple user interface here in something called Streamllet. We'll talk a little bit about that later in the video, but this isn't going to be focused on building the interface. It's more going to be focused on the back end and the logic and the well API with fast API. So, you can see that I was able to sign in here and then immediately I'm brought to a feed where I can see some different photos. I can see the date they were posted and the user that posted them. And then I also have some videos as well. Now, you have the ability to upload something. So, for example, if you were to come here and let's just pick maybe a random photo that we have here. Okay, let's just go like this and call this thumbnail. And then we share it. It's just going to take a second. And then this will be uploaded to our feed. So right now it's just uploading the video. And if we go back to the feed here, we should see the photo app. And you can see the photo shows up by us and that it's on today's date when I'm recording this video. Okay, so that's the application. I know it seems pretty basic, but I promise this is going to teach you a ton of concepts that you need to understand as it relates to fast API. And I think the most important thing is all of the authentication and authorization which most people skip in these beginner type tutorials. So with that said, let's hop over to this myro board that I put together because I want to start going through some theory that's really important to understand before we can even start building APIs. And by the way, as we get later into the video and we're going to start setting up the images and videos, that is notoriously pretty difficult to do. In order to do that effectively, we're going to use today's sponsor, Image Kit. Don't worry, they are free to use and play with. you don't need to pay for them and they just make this process significantly easier. So big shout out to them, but more on that later. Okay, so let's get into the video. Now, we're going to use fast API, right? This is fast application programming interface. That's what API stands for. Now, this is essentially a back-end framework. What that means is that this is going to be running on some type of server and it is going to be essentially controlling data. All an API really does for us is it facilitates the access and control of data. In our case, it's going to be image or video posts, right? Or different user accounts. But before we can get into all of that, we need to start understanding some kind of core concepts of web apps in general. So, let's start by talking about URLs and endpoints so that we can get the terminology out of the way. Now, this whole thing right here and this one as well is a URL. You've seen this, you know, millions of times before, especially when you've browsed to a website. And I want to just go over the components of the URL so that we understand what they are. Now the first is the domain. Okay, the domain is essentially the website, you know, the space of the URL. So training.devlaunch us. This is our domain. techwithim.net. This is the domain. The domain will typically end in like us or.com or.net or.ca or something along those lines. Now after the domain, you have what's referred to as the path or sometimes called the endpoint. Now, this is the particular route or kind of the page or resource that you're going to be accessing from this domain. So, for example, we have training.devaunch.us/tim. So, I'm going to the /tim page right here. /courses/python. So, I'm going to the python courses page right. And for a typical website, these make a lot of sense. But for our APIs, we're going to have to design these ourselves to kind of control the access and the route or the endpoint to particular resources. So when we look at the project that we're going to build here where we're sharing, you know, videos or photos, we might have an endpoint that is, you know, our Aapi.com/photo, right? And then we can access a particular photo. You'll see what I mean in a second, but let's keep going. Now, the next point is the query parameter. Now, the query parameter is some extra bit of information that is typically used to filter the page or to get some more specific type of data. It always will come after a question mark. You'll see some kind of path or endpoint, a question mark and then one or multiple query parameters. In this case, we have a parameter video equal to 1 2 3. Okay. And then if we come here, we have UTM source is equal to YouTube and page is equal to two. So we have two parameters and you can have as many parameters as you like. You just have to have these amperands that separates them. Okay? So just understand that these are the core components of a URL and an endpoint. Now let's keep going here and talk about the request and the response structure. So whenever we visit some type of website, we refer to that website as the client or the front end. Okay, so us as a user, we go to our computer, we type, you know, some website. Okay, and then we are now on the client or the front end. Okay. And the front end is this kind of visual interface that we're able to interact with, that we're able to use. In the case of our post application or our photo application, we can see the different post, right? We can make a post, we can sign in, we can sign out. Now, the way that that actually works behind the scenes is that this user interface is communicating with some type of API. API stands for application programming interface. The API you can essentially see as kind of a secure layer. it's running on a different device, some kind of server, so some computer essentially sitting in some location and it's facilitating all of the access to our data. So if we want to sign into our account, we send a request from the front end or the client to this API and this API returns some response. Okay, this is the flow that I'm trying to get you to understand. You go to some website, you do something. If this thing involves some access to data, right? Especially if it's maybe some confidential data or something, what needs to happen is a request will be sent to some backend, this kind of secure location. It will essentially check can this user do the thing that they want to do and then if they can, it will send this response back doing that thing. For example, deleting a post. We would send a request to the backend. The backend would say, "Okay, yep, you know, I'm going to be able to delete this post." And then it would return the response saying, "Hey, this post was deleted. I want to upload a photo. I send a request to my backend. I say, I want to upload some photo. It returns some response and says, "Yes, your photo was uploaded successfully." So, all of the heavy lifting, all of the secure operations, everything related to data essentially takes place on this backend or this API. And that's what I'm going to be showing you how to build in this video. Now, when we send a request, so we have this front end, right? This client, it sends some data to the back end. And the main parts of a request are the following. Okay, we have a type of the request which we're going to talk about in a minute or the method. We have a path. The path is what we looked at here, right? So this path or this endpoint and oops, I didn't mean to save that. And we have a body. This is optional, but this includes additional data that we want to send along with the request. So for example, like the image that we want to upload or the caption or the name of the post or something like that. And then we have headers. This is typically other additional information that has to do with things like authentication. So in the header of our request, we would include something that indicates that we are, you know, this user. Okay, we are signed in as, you know, Tim attechwithtim.net. The header would kind of indicate that when we send that to the back end. I know this seems a little bit vague. Just bear with me. We're going to make all of this crystal uh clear, sorry, when we actually get into the API example. We then have the response. Okay, so the request is the thing that we send from the front end to the back end essentially saying hey we want to do something and the response is what comes back from the back end to our front end or to our client. Remember the front end is the thing that you as the user actually see and then the backend is the thing that we as a developer typically write that facilitates all of the communication and the data. So from the response we include a status code. You may have seen something like you know 404 before which means not found. That's an example of a status code. So our backend will send a status code to the front end indicating what happened with the request. Common status codes are something like 200 for example, which means successful. I'm going to show you a few more in a second and you get the idea. Then we have a body. Same as we have the body in the request, we can send some additional data back to the front end that the front end might need. And then we have headers. Same thing. headers will be related to typically security, authentication, the type of data, some weird things like that. If I scroll down here, I'm just going to show you a few status codes and a few of the request types which are important to understand. Actually, let's start with the request types. So, here is an example of a very simple API. This is a books API and this is the /books route or path or endpoint or whatever you want to call it. Now, you can see that we have something called a get endpoint. What this means is that we are retrieving some data from this resource essentially from /books. We then have delete. This is the type of method you would use when you want to delete something. We have post. This is the type of method you use when you want to create something. And you have put. This is the type of uh method you would use when you want to update something. So remember how I mentioned when we send a request, we specify some type or some method and that indicates what the front end wants to do. So, if the front end wants to get some data about some books, it sends a get request. If it wants to delete a book, it sends a delete request. If it wants to create a new book, it sends a post request. And you can send all of these requests to the same route or the same endpoint. Okay? And based on the type of the request, you can do something different. So, I hope that makes sense. But these are the common methods or types of requests that you can send. Then we go over to HTTP status codes. Now, you don't need to memorize all of this, but these are just some examples of status codes that you may see. So, you send this request, right? You say, "Hey, I want to get a book, for example." All right? Then, what the uh back end or the API is going to do is it's going to retrieve that data for you. It's going to send it to you and along with that, it's going to give you a status code. So, for example, it may say 200, which means okay. May say 2011 because it created something. You know, you get all these different ones like these redirection. You have errors like bad request, unauthorized, payment required, a bunch of stuff that you can look at. You know, internal server error. Don't need to memorize them. I'm just showing you that there's a bunch of status codes that are commonly used in web development. Okay. Now, let's just have a look at an example request and response. And I promise we'll get into the API. And again, this will all crystallize, but this is just going to really help you understand how we design the APIs. Okay, so user wants to update a post that they made. So, the type is patch. This is actually the exact same thing as put. So if you ever see patch, it's the same as put, which just means you want to update something. If I wanted to create something, I would use post, right? But I don't want to do that. I want to update. So I'm using patch. Okay, so the type or the method of my request is patch. The path is / API/post. And then this is the ID of the post. So I'm saying, okay, I want to go to my API. I want to modify a post. This is the ID of the post that I want to modify. And then the body would be this. This is the data that I'm actually sending where I'm saying, hey, this is the updated title. And this is the new caption that I want to use or the description or whatever for my post. Then the headers includes this. This is essentially my authorization token indicating, hey, I'm authorized to be able to perform this operation because of this thing right here, which we'll talk about later on. So we take all of this, we send this to our backend and then this is the request, okay, that we create. Now from the backend we get a response back. So we send a request, we get a response back and the response looks like this. We have status code 204 which stands for updated and then we have some body and this body says hey this is the title, this is the description, this is the post ID, this is when it was updated, this is when it was created and it gives us that information back to the front end so we can display it to the user. We then have some headers and in this case we say hey the type of you know data that we're returning back here is application/json which is essentially just the format of this data which we can talk about later. Okay I know that's a lot of information but that is the kind of flow of an API and hopefully this is going to help us understand how we create APIs in a minute when we start coding them out. Now last thing that we'll talk about a little bit later I'll just quickly show it to you is the authentication. So, when it comes to using an authenticated API, um it's a little bit more complex than simply sending requests and getting responses. Essentially, what you need to do is get something called a JWT token. This JWT token looks something like this where you send this along with every single request to indicate, hey, I'm authorized to perform this type of operation. Essentially, you're identifying yourself and what user you are so that the API knows you can do this thing or you can't do this thing. You'll we'll look at that later. I don't want to confuse you at this point. But that is kind of the primer on web app development and APIs. Again, think of an API as essentially this kind of back-end server that sits there that facilitates all of the operations that have to deal with data. Creating, reading, updating, deleting data. That's effectively what an API almost always deals with. And it's doing that so it can do it in a secure way and then return data to some front end where the user can view it, display it, you know, mess with it, etc. So with that said, let's get onto the computer and let's start actually writing some code in fast API. All right, so I'm inside of my code editor here and for this video I'm going to be using PyCharm. Now you can use any code editor or IDE that you want, but I typically do recommend PyCharm, especially for Python projects because, well, it is PyCharm and it supports Python the best. In fact, I do actually have a long-term partnership with PyCharm. So, if you want to use it for free, you can click the link in the description, try it out, and see if you like it. It definitely is a great editor, and again, what I recommend for pretty much any heavy Python projects. Okay, so what I've done inside of PyCharm is I've just opened up a new folder. You can see I've got a folder here called fast API tutorial. The way I did that is I essentially just went to open and I just opened a folder on my desktop. Okay? And you can again use any editor that you want. Um, just make sure you open a folder. Now, from here, what I'm going to do is I'm going to open up my terminal and I'm going to start setting up my fast API project. Now, in order to do that in Python, you need to use something called a package manager. There's two notable package managers in Python. The first is pip. The second is UV. Now, I'm going to suggest that you use UV because this is significantly more modern and it just works a lot better. Uh, but if you don't want to use UV, you can replace the commands I'm going to show you with pip. Okay, so UV is something that you need to install. If you don't have it installed, I will leave a video on screen that explains how to do so. But once you have UV installed on your computer, what you can do from this open folder is you can type UV innit and then dot. What this is going to do is create a new UV project for you where you're able to isolate all of the dependencies for this particular project in this kind of one folder. Okay, so we're going to type uvanit dot. What that's going to do for you is it's going to create a few files inside of your folder. You're going to see a main.py file, a piprotoml, and a few other files that you don't really need to worry about too much. Now, this piprotoml file is going to include all of the dependencies for your project. And it's what we're going to start modifying now by installing some different dependencies that we need for this project. So, if you want to work with fast API, in order to do that, you need to install it. So, what we're going to do is we're going to type uvad and then we're going to start by just adding fast API. Okay? So, we're going to type uvad fast api. When we do that, if we go back into pi project autotoml, you'll see this dependency has automatically been added for us. Okay, now that we have it installed, we'll be able to actually use it inside of our Python code. Now, as well as fast API, what we're going to do is we're going to type uvad and we're going to install python-env. Now, this is something that we need to use to manage environment variables because in a minute we're going to have some environment variables for handling our images and videos. So, we're going to go ahead and install this. Now, there's a few other things that we need to install as well, so just bear with me. We're going to type uvad and we're going to install fast API- users and then inside of square brackets, we're going to type SQL alchemy like this. Okay, so make sure it's spelled exactly like this. UV add fast API- users SQL alchemy. This is what we're going to use when we start handling the authentication and the authorization later on in our project. So, we're going to go ahead and press enter. And then same thing, it should get added to our dependencies. Okay, there's a few other ones that we're going to need here. So, we're going to type UV add and then we're going to add the image kit. So, we're going to say image kit like this. Uh, and sorry, it's going to be image kit io. Now, this is the package we're going to use to handle our images and videos again, which we'll look at later on. We're also going to say uv and we're going to add uvicorn and then standard. Unicorn is a web server in Python that allows us to serve our fast API application. You'll see how that works in one minute. So, we're going to add Unicorn. And I promise we are almost done. Just a few more that we need to add. And then, sorry, we're going to add one more here, which is going to be a io sq light. Like that. We're going to use this for interacting with our database. We may potentially need some more later, but for now, I think this should be fine. And that should handle all the dependencies that we need for this project. Okay. Okay, so we're going to close that and we're just going to quickly go here and make a new environment variable file. Now to do that, we're going to go new file and we're going to call this file env. This is the file that you create when you want to store sensitive credentials, tokens or keys that your application is going to rely on. In our case, we need to access a key for image kit which is going to allow us to handle the image and video uploads which I want to do now. Okay, so inside of this file, there are three variables that we need to define. The first is going to be imagekit_private_key. All right. The next is going to be the imagekit_public_key. And then the last is going to be the imagekit URL. Okay. So, we're going to put equal signs for all of these. And we're just going to quickly grab these three values. So, we don't need to come back to this until much later in the video. Now, you may be wondering, what the heck are we doing, Tim? We haven't even started writing the API. I promise we're going to get there. I just want to get through everything, do all of the setup, and make sure that it's all ready to go. So we can just focus on coding and I'm not moving around too much. Right now what we're doing is we're creating this essentially kind of secret environment variable file. This is something that's going to hold some values that we need for uploading the images and videos. Like I mentioned, we're going to use image kit to do this. So what I need to do is get some keys and values from ImageKit. So I'm quickly just going to open up the ImageKit website. I'm going to leave a link to this in the description. What we're going to do is we're just going to make a new account on here. Again, it is free to use this. You do not need to pay for it. And essentially what this does is give you all kinds of amazing tools for handling your images and videos, which is typically a huge pain, but they have all kinds of things like image and video optimization, formatting, cropping. It's very interesting. So anyways, what we're going to do is make a new account. I've already just made a new one. So again, I'll leave that link in the description. And from here, what we're going to do is go on to the developer options. From developer options, we're going to look for our public key, our private key, uh, and then we're going to get our URL, which is up here. So, I'm going to copy my public key and then I'm going to put my public key right here. I then am going to copy my private key, which is something that you do not want to share with other people. And before it will allow you to do this, you need do need to set a password for your account. So, if you press this, I'm just going to blur my email, but I'll press the profile page and I'll just quickly set a password. Okay, now the password is set. So, we'll go back to developer options. We'll go private key and I'm just going to copy this after I use my password. So, let's use that and copy this. Okay, so now that I've copied it, I'm going to go back to PyCharm. I'm going to paste it. Again, don't share this with other people. I will delete it afterwards. And then lastly, we're going to grab this URL endpoint. Okay, which should be right up here. And we're going to paste this inside. And now we have the keys that we need. Okay, so we're going to close the environment variable file. And now what we're going to do is start setting up kind of the scaffolding for our project. So I'm going to make a new folder. And this folder is going to be called src. This is typically best practice when you're writing a fast API application. you create this source or actually let's change it to be an app directory where you actually have all of the code for your application and then you have this main py file which is kind of what triggers the application to run. So what we're going to do inside of this app folder is we're going to make a new file and we're going to call this app. py and this is where we're going to start actually writing our fast API app and start getting into some Python code. All right, so let's start writing a API. We've gotten to the point where everything is set up. what we're going to do from this uh file right here. So from here we're going to type from fast API import fast API with this capitalization and we're going to say app is equal to fast API with a set of parenthesis. Now this is the fast API application that we just created. And what we'll need to do now is start setting up the different paths or endpoints that we want to have accessible on our API. Now remember for our API, we're setting this up essentially to handle data, to be able to accept some type of request from our front end or our client and to return some type of data. So we can create data, delete data, read data, update data, right? We need to decide because we're designing this API. So I'm going to start by just writing some simple dummy endpoints just to test and see how this works. Then we'll get into endpoints that actually make more sense. So the way that you make an endpoint in fast API is you type app which is the name of this variable right here that we defined dot and then you specify the method for this particular endpoint. So it can be get, post, put, delete depending on what you want this to do. Now the most basic type which is common is to use app.get. Now when you do this what you're going to do is you're going to specify the endpoint. So we're going to say slash and then something like you know hello dashworld. Okay, so this is the path or the endpoint. Now, I also forgot I need to put an at symbol here because this needs to be a decorator in fast API. A decorator is something with the at before it. And what you do beneath this is you define a function. The function should typically be named something similar to this endpoint or path, but it doesn't need to be. You put a set of parenthesis, and then inside of here, you can return some data. So, let's just quickly return the autocompleted data where it says message hello world. Okay, so we have atapp.get/hello world. What we're saying is, hey, when you go to our API and you go to /hello world, this function is going to be called and then we're going to return this data. Now, the data that we always return from our endpoints is either going to be a paidantic object, which we'll talk about later. I know that might not make a lot of sense, or it's going to be a Python dictionary. The Python dictionary looks like this, right? You have some key associated with some value. And the reason why we return Python dictionaries is because when we create APIs, we work with something called JSON. Now, JSON stands for JavaScript object notation. It is the format essentially for dealing with data across the web. And you can essentially think of JSON the exact same as you would think as a Python dictionary. Okay, it's not exactly the same. There's a few minor differences, but in our case, we can assume that anything that is a valid Python dictionary will be a valid JSON object. Again, keep in mind there's some caveats there, but generally that is the case, especially with simple data. Okay, so now we've got this application, right? We've defined this endpoint, but what we need to do is run it. Now, there's many different ways to run the API, but the way that I'm going to suggest we do it is by going into this main.py py file here, deleting everything inside of here, and then importing this app file and running it using something called Unicorn. So, what we're going to do is we're going to say import uicorn like this. We're then going to say if_ame is equal to_main then we're going to say unicorn.run. We're going to put app colon app. I know this seems weird. I'll explain what it is in one second. We're going to say host is equal to 0.0.0.0 and we're going to say the port uh is equal to 8,000 and we're going to say reload is equal to true. Okay. Now, what are we doing here? Well, first what we're saying is all right, I want to use this web server called Uicorn, which we've already installed, right, with UV, and I want to run a web server. Now, for the web server, I want to run an API on it. the API that I want to run is app.app. So that's inside of app. So the app folder here, the app file and then I want to run the API which is inside of the variable app. So let's say I were to change this and I called this hi. Okay, then I would change this to be hi. All right, so just keep that in mind. That's how I'm getting these variables essentially. So we have the name of the folder is app, right? The name of the Python application is app and then this here is app and we have app.app. Probably should have picked a better name for that, but it's okay. Hopefully, you get the idea. Now, when I say host, this is specifying the domain essentially that I want to run this server on. Because we're running this locally on our own computer, when I specify 0.0.0.0, that just means run it on any available domain. So, it's going to run on what's called local host, which is just our own host, so only we can access it. as well as our private IP address, meaning anyone else on the network would be able to access this as well if they knew the private IP address of this machine. Now, there is ways to run this publicly, so anyone can access it. Not going to get into that in this video, but essentially the way that you're going to be able to access this application is you're going to go to whatever the IP address of this machine is. If we're on the same machine, it's going to be localhost. We're going to go to port 8000, and then we can access this resource right here, which is /hello-orld. So for this what we can do is run this main.py file. To do that we simply type uv run main.py. Go ahead and press enter. And it says that there's some issue. This is because I'm currently running this app on another um uh what is it? Editor. So let me just shut the other app down and rerun it. And then we should be good to go. You can see that it's running now. Again that issue you wouldn't have run into. It's cuz I had a demo application running in a different um editor that I have open. You'll see what's happened here is it now says Unicorn running on and then it shows you the URL or the domain where this is running right and then it kind of goes through this thing saying hey you know started the reloader process and by me specifying reload equals true anytime I save or make a change to this file like if I do something I don't know hello here and then I save this you'll notice that the file or sorry the server will shut down and restart with the changes that I made. So, it's really useful for when we're debugging and building something because it just shuts down and restarts anytime you make a change. Now, if I want to actually be able to view my application, what I can do is go to this URL. So, you can just click it and open it up. Now, it's saying this 0.0.0 isn't working. So, what we can do is change this to be 127.0.0.1 or localhost port 8000. And when we do that, it should give us this uh thing here saying detail not found. That is totally fine. That's exactly exactly what we're expecting. Okay, so our API is now running and it's time to talk about the coolest feature of fast API, which is the docs endpoint. So here, what you can do whenever you have a fast API application is you can go to /doccks. Okay, when you do that, it's going to bring you to a page that looks like this, which actually specifies all of the endpoints and the configuration that you've set up for your API. So from here, if I open this up, we'll be able to actually test out our API by pressing this try out button. This is going to send a sample request to this endpoint and then tell us what the response would have been. So what I can do is press try it out. I can press execute and then you see what it does is it sends a request to this URL and then it tells me that I got this as my response saying message hello world and then it also told me the code of this was 200 which means success. Okay, 200 successful response. So there you go. We just sent a request, right? We tested it out. It's all working. This is the thing I love about Fast API is that you can actually do this. You can directly go here and test out all of your endpoints by simply going to the slashdocs endpoint. This will become more useful later on, but always check this out. It's very, very useful. Now, there's also another endpoint uh called /redoc. This is kind of a newer version of that docs endpoint. It works the exact same way. We can test this out if we want um you know test the API etc etc uh and kind of see how this works. I am not going to uh dive into this too much right now but the point is there's this other endpoint called redoc which you should be aware of but the one that I prefer to use is called /doccks. Now just another quick thing if we wanted to we also could just directly go to slashhello-world. If we do that you see it will give us message hello world because we set up a get endpoint and by default whenever you go to a URL in your browser you send what's called a get request right and because we sent the get request we got the response back and the browser is able to actually render it and show it for us. But generally for all of the other endpoint requests we're going to be looking at, we're going to have to use this /docs page or another tool to test the API. So we've now written kind of this dummy get endpoint. However, it doesn't really help us accomplish our project goal, right, of creating, you know, posts. So what I want to do now is I want to start adjusting the endpoint to actually make sense to our project. It will change over time, but we're going to slowly kind of build towards what's called a CRUD application where we have create, read, update, and delete functionality. So, what I'm going to do is I'm going to delete this and I'm going to start setting up some stuff for handling posts. So, what I want to do is I want to set up my application so I can essentially retrieve and create new user posts. For now, we're going to start with text posts, but then later we'll get into the images. So, I'm going to make a new dictionary and I'm going to call this my text posts is equal to and we're just going to have an empty dictionary like this. Okay. Now, what we're going to do is we're going to make an endpoint and we're going to say at app.get get and this is going to be slash posts. Okay. And for the function, we're going to say define get all posts like that. Now, what this is going to do is just return all of the posts that we have. So, we're simply just going to return text post like that. Super simple. If we go back here now to this and we refresh, you'll see that we have uh why is it still showing that? Okay, let me just restart my server because for some reason sometimes this messes up. So, we'll just restart it. Okay. And I don't know what was going on there. I had some weird issue. But anyways, I got this now back to the docs page. And you can see we now have slashposts. And if I just try this out and execute, you see it just gives me an empty response. Okay. That's what we're expecting because currently we don't have any posts. However, if we put a post in here, then we would be able to retrieve it. So, that's a good endpoint. But what I'm going to do now is I'm going to start making some posts. So, I'm going to have some ID like one. Okay. And I'm going to have this associated, if I can type properly, with some post. So for my post, I'm going to have another dictionary. I'm going to have title, you know, new post and content, you know, cool test post. Okay. And now I want to make an endpoint that allows me to retrieve one individual post. So first of all, let's just go back actually and let's quickly test and go refresh. Okay. And let's try this out and execute. And you can see that we get the one post showing up. But maybe I want to be able to kind of filter and get just an individual post. So I'm going to make a new endpoint. I'm going to say at app.get and I'm going to type /post slash and then inside of parenthesis I'm going to type what's known as a path parameter. So this is a dynamic value that we can actually change and adjust in order to get an individual post. So we're doing ID, right? And then what I'm going to do here is say define get_ost and I'm going to say ID is of type int. Now what this is doing is it's going to directly map this ID parameter to the ID value that I have inside of this path parameter inside of curly braces and give it as a parameter to my function so I can use it inside of here. So now what I can do is I can say return text post okay do get and then I can get id okay so now what I'm able to do is if I go here and I refresh we should see that we have another endpoint you can see it says get post with an ID we can pass the ID so let's pass ID of one and we execute this um it's not giving us anything and I see the problem that is because ID is a string when it should be a number. So if we change this to a number now and we go refresh and then try out go with one and execute. You can see now that we get the individual post rather than a list of all of the posts. Okay. So just showing you this is how you create what's called a path parameter. Now if we want to return an error here if the post doesn't exist, what I need to do is I need to import this HTTP exception. Now from this function I can do something like if id not in text posts then I can raise an HTTP exception. I can specify a status code in this case something like 404 and I can say the detail post not found. When I do that that's going to indicate okay we've had a 404 error you know not found and then post.found and that's how you can return an error. So now if we go back here and we refresh and we try to access a post with ID like four or something and execute, you'll see that it says detail 404 and then it gave us a 404 error code. Okay, so what I just did quickly is I just had chatbt generate a bunch of test posts because I'm going to use these um throughout the rest of this kind of section here to demo a few more things. All right, so what we've done is we've added a bunch of text posts. We've added what's called a path parameter. We had a normal kind of query endpoint here. And the next thing that I want to do is show you how we can use what's called query parameters inside of our functions. So up until this point it's been pretty straightforward, right? We just can call /ost. We can call for a particular ID. Now I want to make it work so that we can do some kind of more advanced filtering using query parameters and then we'll continue from there. So I'm actually going to go inside of this function right here and I'm going to start adding some optional query parameters that we can pass to this that will allow us to kind of filter some of the content. So a query parameter remember is the thing that comes after the question mark. So something like maybe you know length equals 10 or something right whatever. Um so that we can actually filter kind of the number of posts maybe that we're receiving. So what I'm going to do is I'm going to add a query parameter called limit. I'm going to say limit colon int is equal to and by default it's going to be none. Now what I've just done is I've just specified that I now have the ability to pass a query parameter called limit to this post endpoint. And I can then check if this query parameter exists. If it does, I can use it. If it doesn't, I don't have to. So my idea with the limit parameter is that maybe I don't want to receive all 10 posts. Maybe I only want to receive the first three. Well, I can specify that with the limit. So let me show you how this works. I can do something like if limit, then what I'm going to do is say return text post up to the limit. Okay, now this is not bulletproof because if the limit is larger than the number of posts, that will give us an error. But for now, that's fine. and we'll just use that and then otherwise we'll just return the text post. So now if I go back to my page here and I refresh you're going to see that if I look at post we have the ability to add this limit query parameter. So what I can do is go try it out for limit I can pass maybe three for example and then execute and what it gave us an error. Okay that's weird. So the reason we got that error sorry is because uh we're trying to apply a list operation on a dictionary. There's multiple ways we can fix this, but for now, what I'm going to do just to make it easy is I'm going to say list of text posts dot and this is going to be uh values like that. So, we'll just convert the values into a list and then return them. So, let's go back here and let's go refresh. And then we'll go here. You can see we have a limit again. Let's go maybe five and execute. And now you see we get a list with five items. If we change this to three, we get only three items. And if we don't have any limit at all and we execute, we get all of the items showing up. Okay, so just showing you that's how you add a query parameter. If you want to do that, you simply specify it in the uh parameters here. You can make it optional, which means you can have something like is equal to none or you can make it mandatory by removing this and now you have to pass the query parameter. If you don't um then you could potentially get some errors inside of the function. You can pass multiple parameters like maybe you know content length or something or whatever and then you can specify something like int can make it string. The reason why you need to specify the type here is so that it can be auto documented and validated by fast API. The way the fast API works is that it automatically validates all of the data input that's coming into the function and out of the function for you. So when I specify that this is an int, if I try to send something other than an int to this function, it's actually going to raise an error for me, okay? Other than a number. So this documentation is actually very very good inside of fast API. And that's why you use what's called a Python type hint inside of the parameters and you specify like what does the function return, what does it accept so that it can be really well documented and it can have what's called this data validation. Okay, so at this point we've looked at query parameters, we've looked at path parameters, we've looked at the get endpoint extensively. Now I want to look at the post endpoint and creating new data. So what I'm going to do is type at app.post and I'm going to do slashpost. Okay. Now from here what I want to do is be able to create a post. So I'm going to make a function called create_ost. what we're going to take for creating a post is actually something different than for getting a post. So, like I said in fast API, it has automatic data validation, which means it's going to check the data that's being sent into the function to make sure it's accurate. Now, up until this point, we looked at the query parameters and the path parameters, but there's another way that we can send data to our API, and it's by using something called the request body. Okay, the body is kind of like more hidden information. It's not directly inside of the URL. It's in the field called body. And the way that we accept that type of data is by creating something called a schema in fast API. So what I'm going to do is I'm going to make a new file here. And I'm going to call this schemas. py. Okay. Now inside of here, what we're going to do is we're going to define the type of data that we want to accept in our various endpoints. So in order to do this, we're going to say import or we're going to say sorry from piantic import the base model and we're going to define a python class. So we're going to say class post create. Okay. And this is going to inherit from the base model. And then we're going to specify in here the fields that we want to uh accept essentially for a post. So for a post we're going to accept a title and we're going to accept some content. Okay, so we have title and content for our post. Now, the way that this works is that you inherit from this base model, which is kind of this special object in Python that has some special features. And what we're able to do now is use this as a type to kind of receive body data inside of our functions. Again, I know it seems a little bit confusing. This is referred to as something called a schema. Very common inside of fast API to use this and it's common that you put it in a separate file called schemas. So from app.py, Pi we're going to say from app do schemas import and then we're going to import the schema that we just wrote which is the postcreate schema. Okay. Now what we can do is for our create post we can say post. So let's do this post colon post create. Now when we do this because we're using a pidantic model by default fast API knows that we're receiving request body. Okay. So not receiving the uh query parameter receiving the body. So now what we can do is we can use this post data directly inside of the function to create a new post. So we can do something like let's do the following. Um okay we're going to say text post and then max of text post.keys plus one because we need to find what the next ID essentially should be. And then we're going to say is equal to and we're not going to do post.dict. What we're going to do is we're going to make a dictionary and we're going to say the title is post.title and the content is post dot content. Now, because in my schema I've defined that my title is a string and my content is a string, fast API will make sure that these are indeed strings before it allows me to call this function. If they aren't strings, it's actually going to automatically raise an error for me and tell me that I have a bad request, which means when I try to access the title or access the content here, I know that they're going to be valid. So again, fast API automatically validates the data that comes into the API based on the types that you set, which is extremely useful. So now we've created this post endpoint. It's just going to create this new post. But what we really should do is we should return the new post that was created. So to do that, actually, let's just do this. We can say post is equal to like this or maybe just new post is equal to this and then we can say this is equal to new post and we can return the new post. So now we have a post endpoint to create a new post. So what we can do is we can save should automatically reload. So now if we come here and we go try it out and we change this to like you know cool post and new post or something and we go execute you can see it gives us the data back. And then if we go back to posts, uh looks like the limit is required this time. So let's go like 12 and execute. And you can see we get the new post and our cool test post is showing up. Awesome. So all of that is working. We now know how to accept request body, right? So this different type of data and to create data. Now to delete data, it would be pretty straightforward. You go app.delete and then same thing and you would kind of continue along these lines. And there's more stuff that you could do related to that. I'm not going to show that this second. and we'll show it more when we actually get into kind of the finalized project. All right, so we're almost going to move on to databases, but I just want to cover one or two small more things about fast API that you should be aware of. Now, the first is going to be the output type. So, when we created the post here, right, we're just returning new post. And if we go back to our kind of documentation here, let's just go to /docs and have a look at it. You'll see that it doesn't show us like what type of data is going to be returned. Okay, it gives us kind of an example, but this isn't exactly, you know, what we're looking for. It's not the best documentation in the world. So, what we can do to enhance the documentation and actually give us um some more validation in our code, which is better, is we can specify the type of data that's going to be returned from these functions. So, for example, for my create post, I can actually put this arrow here, and I can specify that I'm going to be returning this postcreate type. Now that's going to look exactly like this, right? So it's the same schema that we had here. Now if we wanted to return something else, we can do class post return or post response for example can be the same thing but just so the name makes more sense. And then we can change this to post response. And we can import this from here post response. So now we're indicating okay whatever we're returning from this function is going to be of this type. Now what this is going to do if I go back to my documentation here and I refresh is it's now going to indicate to us if we look here the type that's actually going to be returned to us. You can see it gives us the value here. Example value is going to have title and content being returned on the successful response because we've specified that type. Now what it also does is it means we can only return data from this function. Now that is of this type. If I try to return something else like just a normal dictionary, if I w
Original Description
ImageKit is an image and video API plus AI-Powered DAM that we use in this project to handle all of our image and video operations, check it out here: https://tinyurl.com/bdf3mxxx
I'll teach you Fast API by working through a real project. I'll go over everything from the absolute basics to some more advanced concepts like setting up authentication, logging in various users, connecting to a database, and all of the components that you actually need if you want to build a real production grade application. This video is not designed for absolute beginners.
DevLaunch is my mentorship program where I personally help developers go beyond tutorials, build real-world projects, and actually land jobs. No fluff. Just real accountability, proven strategies, and hands-on guidance. Learn more here - https://training.devlaunch.us/tim?video=SR5NYCdzKkc
🎞 Video Resources 🎞
ImageKit: https://tinyurl.com/bdf3mxxx
ImageKit Docs: https://imagekit.io/docs/integration/python#generating-url-for-rendering-images-in-python-app
FastAPI Users Docs: https://fastapi-users.github.io/fastapi-users/latest/
Code in this video: https://github.com/techwithtim/FastAPIPhotoVideoSharing
UV Tutorial: https://www.youtube.com/watch?v=6pttmsBSi8M
⏳ Timestamps ⏳
00:00:00 | Video Overview
00:00:35 | Project Demo
00:01:58 | Web App Architecture & Theory
00:14:07 | Project Setup & Install
00:20:45 | FastAPI Setup & Basics
00:28:10 | FastAPI Docs
00:30:10 | GET & Fetching Posts
00:32:25 | Path Parameters
00:33:49 | Raising Errors & Status Codes
00:34:56 | Query Parameter
00:38:34 | Request Body & POST
00:43:28 | Output Type & Pydantic Models
00:46:30 | Database Connection
00:59:57 | Creating Posts & Saving to Database
01:05:22 | Retrieving from Database
01:10:27 | Image & Video Upload (ImageKit)
01:27:08 | Deleting Posts
01:30:54 | User Authentication and JWT Tokens
01:52:02 | Protecting Endpoints
01:58:00 | Streamlit Frontend
Hashtags
#FastAPI #ImageKit #SoftwareEngineer
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Tech With Tim · Tech With Tim · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
A* Path Finding Algorithm(Visualization)
Tech With Tim
Python Programming Tutorial #1 - Variables and Data Types
Tech With Tim
Python Programming Tutorial #2 - Basic Operators and Input
Tech With Tim
Python Programming Tutorial #3 - Conditions
Tech With Tim
Python Programming Tutorial #4 - IF/ELIF/ELSE
Tech With Tim
Python Programming Tutorial #5 - Chained Conditionals and Nested Statements
Tech With Tim
Python Programming Tutorial #6 - For Loops
Tech With Tim
Python Programming Tutorial #7 - While Loops
Tech With Tim
Python Programming Tutorial #8 - Lists and Tuples
Tech With Tim
Python Programming Tutorial #9 - Iteration by Item (For Loops Continued...)
Tech With Tim
Python Programming Tutorial #10 - String Methods
Tech With Tim
How to Overclock a NVIDIA GPU
Tech With Tim
Python Programming Tutorial #11 - Slice Operator
Tech With Tim
Python Programming Tutorial #12 - Functions
Tech With Tim
Python Programming Tutorial #13 - How to Read a Text File
Tech With Tim
Python Programming Tutorial #14 - Writing to a Text File
Tech With Tim
Python Programming Tutorial #15 - Using .count() and .find()
Tech With Tim
Python Programming Tutorial #16 - Introduction to Modular Programming
Tech With Tim
Python Programming Tutorial #17 - Optional Parameters
Tech With Tim
Python Programming Tutorial #18 - Try and Except (Python Error Handling)
Tech With Tim
Python Programming Tutorial #19 - Global vs Local Variables
Tech With Tim
Python Programming Tutorial #20 - Classes and Objects
Tech With Tim
Cool VBS Script to Prank Your Friends!
Tech With Tim
How to Overclock an AMD GPU
Tech With Tim
Best GPU'S For Mining Ethereum (2018)
Tech With Tim
Recursion and Memoization Tutorial Python
Tech With Tim
Ethereum Mining Rig - Hardware Guide
Tech With Tim
Pygame Tutorial #1 - Basic Movement and Key Presses
Tech With Tim
How to Install Pygame (Windows 8/10)
Tech With Tim
How to Trade Your Cryptocurrency (Bitcoin, Ethereum etc.) For Cash!
Tech With Tim
How to Mine Ethereum 2018 - WORKING (Super-Easy)
Tech With Tim
Microphone Comparison - $10 Mic vs $150 Mic (Blue Yeti USB)
Tech With Tim
Pygame Tutorial #2 - Jumping and Boundaries
Tech With Tim
Pygame Tutorial #3 - Character Animation & Sprites
Tech With Tim
Pygame Tutorial #4 - Optimization & OOP
Tech With Tim
OBS Studio Tutorial - Best OBS Settings
Tech With Tim
Linear Search Algorithm - Python Example and Code
Tech With Tim
Make Any Mic Sound AMAZING! (WITH OBS)
Tech With Tim
Binary Search Algorithm - Python Example & Code
Tech With Tim
Pygame Tutorial #5 - Projectiles
Tech With Tim
Pygame Game - Mini Golf
Tech With Tim
Pygame Tutorial - Projectile Motion (Part 1)
Tech With Tim
Pygame Tutorial - Projectile Motion (Part 2)
Tech With Tim
Pygame Tutorial #6 - Enemies
Tech With Tim
Pygame Tutorial #7 - Collision and Hit Boxes
Tech With Tim
Pygame Tutorial #8 - Scoring and Health Bars
Tech With Tim
Cloud Mining vs. Hardware Mining - 2018
Tech With Tim
How to Install Pygame on Mac OSX (Fast-Simple)
Tech With Tim
Pygame Tutorial #9 - Sound Effects, Music & More Collision
Tech With Tim
Pygame Tutorial #10 - Finishing Touches & Next Steps
Tech With Tim
How to Fade Your Screen in Pygame [CODE IN DESCRIPTION]
Tech With Tim
How to Create a Button in Pygame [CODE IN DESCRIPTION]
Tech With Tim
Pygame Side-Scroller Tutorial #1 - Scrolling Background/Character Movement
Tech With Tim
Pygame Side-Scroller Tutorial #2 - Random Object Generation
Tech With Tim
Pygame Side-Scroller Tutorial #3 - Collision
Tech With Tim
Pygame Side-Scroller Tutorial #4 - Scoring and End Screen
Tech With Tim
How to Create A Message Box in Python - Tkinter
Tech With Tim
Is Ethereum Mining Still Profitable - Is It Worth It (April 2018)
Tech With Tim
How to Run MAC OSX on a WINDOWS PC (Clover Boot-loader)
Tech With Tim
Programming Problem #1 - Alphabet Soup (Beginner/Novice)
Tech With Tim
More on: LLM Foundations
View skill →Related Reads
📰
📰
📰
📰
10 Most Common Mistakes Java Developers Make in Interviews
Medium · Programming
# C++ Error Messages Translated — 10 Common Compilation & Link Errors Explained
Dev.to · Yilong Wu
# Picking What to Read Next: The Trade-offs of Ranked-Choice Voting in a Django App
Medium · Python
The Ultimate Rust ORM Comparison 2026: Diesel vs SQLx vs SeaORM vs Rusqlite — Pick Your Powerhouse!
Medium · Programming
Chapters (20)
| Video Overview
0:35
| Project Demo
1:58
| Web App Architecture & Theory
14:07
| Project Setup & Install
20:45
| FastAPI Setup & Basics
28:10
| FastAPI Docs
30:10
| GET & Fetching Posts
32:25
| Path Parameters
33:49
| Raising Errors & Status Codes
34:56
| Query Parameter
38:34
| Request Body & POST
43:28
| Output Type & Pydantic Models
46:30
| Database Connection
59:57
| Creating Posts & Saving to Database
1:05:22
| Retrieving from Database
1:10:27
| Image & Video Upload (ImageKit)
1:27:08
| Deleting Posts
1:30:54
| User Authentication and JWT Tokens
1:52:02
| Protecting Endpoints
1:58:00
| Streamlit Frontend
🎓
Tutor Explanation
DeepCamp AI