Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Getting an Item

00:00 In the previous lesson, I showed you how HTTP methods are used in REST to perform CRUD operations on data. In this lesson, I’ll put that in practice and begin our FastAPI application.

00:12 You’ve already seen how you can return a dictionary from a FastAPI function. You can do more than that, though. You can return Pydantic objects as well, and just like with the dictionary, FastAPI serializes them to JSON for you.

00:26 The rest of this course is about building a single FastAPI app that stores information about books. In this lesson, I’ll start by implementing a call to fetch a single book.

00:36 Every book in the system will have a unique ID. To specify what book you want to retrieve, you need to provide that ID to the get call. You do this by embedding it in the URL to make FastAPI aware of this. You still declare the URL in the decorator, but you leave a placeholder for the ID by declaring a variable in brace brackets.

00:57 This is like a little template. You then use the same name that’s in your brackets as an argument to your function, and FastAPI will automatically parse the URL and pass the argument’s value to your code.

01:10 Let’s go start our library API. I’ve put the app in a directory called books, and like before, all the code is going in main.py.

01:20 In the real world, you might break things up and just use main.py as your entry point, but our code will be small enough that I’m going to stick with a single file.

01:29 Here ,I’m declaring a Pydantic class almost identical to the one you saw earlier, with one additional attribute: the ID of the book. Again, in the real world, your API is probably going to interface with some data storage mechanism like a database. To keep it simple and stay in the realm of Python, I’m going to store our books in a dictionary that I’ve named library.

01:51 The library dict starts out with two books in it. Keep in mind this will reset any time you restart your server, so it isn’t very permanent, but that’s not necessarily a bad thing when you’re just learning. If something goes wrong, you don’t have to reset your DB and start all over again.

02:07 The code to populate the library dictionary is a bit involved, and uses a dictionary comprehension. The keys in the dict will be the book IDs, while the values will be Pydantic Book objects.

02:19 The line highlighted here is a dictionary containing data for the scary clown book, which the comprehension will use to create an actual Pydantic object.

02:29 I want to automatically create unique IDs for our book objects. So I’m enumerating over the list of book dictionaries that provides the fields. The enumeration returns a number and a dict, which I’m calling fields.

02:43 The number then gets used as the ID. Since enumerate() starts with zero, I’m adding a 1. You don’t really need to do this, but IDs and databases usually start with 1 so ID zero just seemed wrong to me.

02:56 And then this is the last part, which creates the Pydantic Book object. It explicitly sets the ID, and then uses the **kwargs trick to turn our fields into constructor arguments.

03:09 When this is done, I’ll have a library dictionary with two Pydantic Book objects in it: our scary clown and our scary fish.

03:18 Before showing you a templatized get, let me start with a practice run. This decorator is like the one in the “Hello, world!” example, mapping the URL /king_it to this function.

03:30 Then inside of the function, I get the book with ID 1 and return the corresponding Pydantic object. FastAPI takes care of serialization and turning this into JSON.

03:42 This is kind of fake. You’re not likely to need a get that returns a single item in the real world, but I wanted to make sure it was clear how this worked before I added the complexity of parameterizing the URL.

03:53 In the background, in a different window, I’m running the FastAPI dev server, so let me use curl and check that this code works.

04:05 And there you go. Hitting the /king_it URL results in a serialized JSON dictionary containing our scary clown book. Alright, let’s try something a little closer to reality.

04:17 Having to hard-code a URL for every book in your library doesn’t make a lot of sense. So instead, here I’m creating a single, templated URL to fetch any book given an ID.

04:28 The brace brackets in the URL string tell FastAPI to match that part of the URL, and put it in an argument named book_id. Then in the function signature, I include an argument of the same name.

04:41 All URLs are strings, and since an ID should be an integer, I can tell FastAPI that I need the argument converted by providing a type hint. I’m not a huge type hint guy.

04:53 I don’t tend to use them in my regular code, but this is one of those places I think they shine. Without it, you’d have to type-cast every single variable, but instead FastAPI takes care of that for you. Less code for you to write, which means you’re less likely to forget to do it and have to fix a bug later.

05:10 Here I check if the provided ID is in our library dictionary, and if so, all I have to do is return it. It is important to check if the ID is in the dict, because if it isn’t, you’d get a KeyError.

05:23 If your code results in an unhandled exception, FastAPI will return an HTTP 500 error, which isn’t really what you want. It’s better to tell the user what they did wrong.

05:34 So I check the ID, and if it isn’t there, I return a dictionary that informs the user that something went wrong. If you consistently handle your errors this way, your users can always look for a dict coming back with an error key, and show the reason for the problem in their output.

05:50 One pattern that you’ll see sometimes is for every call to return a similar structure. So instead of returning just a serialized book, instead I would return a dictionary with a key book, and the value being the serialized book.

06:04 This is actually a little safer, because at the moment, if our Book class had an attribute called error, it would be confusing. With this particular dictionary. I’ve gone the lazy route, though, and seeing as our server is relatively simple, I can get away with it.

06:19 Let’s try this one out.

06:25 There’s book 1, the scary clown,

06:32 and there’s book 2, the scary fish,

06:40 and there’s something truly frightening. There’s no third book.

06:45 That’s the first of the two common ways of using get. In the next lesson, I’ll show you the other one: getting a list of things as well as using URL query parameters to affect how much data comes back in that list.

Avatar image for Ranudar

Ranudar on Feb. 28, 2026

Hi Christopher, thanks for the nice course. Why don’t you use the start parameter for enumerate though? To not make the dict comprehension even more involved? Cheers

Avatar image for Christopher Trudeau

Christopher Trudeau RP Team on March 1, 2026

Hi Ranudar,

Good question; simple answer: I always forget it is there. 99% of the time I’m iterating from 0 and since I don’t use it I don’t think about it. You’re right, it would have been a better choice.

Become a Member to join the conversation.