FastAPI POST Requests
00:00 In this lesson, you’ll see how to implement the C in CRUD and create new items. But first you’ll need a database. Perhaps you’ve heard of the MEAN stack for web development.
00:12 And this is an acronym that stands for MongoDB, Express, Angular, and Node. There’s also the MERN stack that replaces Angular with React. If you add React and MongoDB to FastAPI, you get the FARM stack.
00:29 This course won’t be covering React, and it won’t go that in-depth into MongoDB, but here’s a crash course on how to quickly get started with MongoDB. So Mongo DB is a NoSQL database. TLDR, NoSQL means non-relational.
00:47 So instead of tables created by keys, MongoDB persists data in something called a document. The structure of a MongoDB database is a group of collections, and each collection is a group of documents.
01:00 Each document is conceptually a JSON object. The documents don’t have a schema, or at least it’s not required, so you can insert any JSON document into any collection.
01:11 That’s oversimplifying a real-world implementation a bit, but it is enough to get you started in this course. A real-world MongoDB database, just like a real-world relational database, lives on a server, and you have to connect to it via a network.
01:26 This can get tricky and be a hassle while developing. Thus for relational databases, many developers rely upon SQLite. This is a file-based database that doesn’t require the ceremony of connecting to a server.
01:40 You simply open a file to connect to the database. For MongoDB, there’s a file-based database called Mongita that you’ll use for the remainder of this course.
01:53
To install Mongita, use pip
and install the mongita
package.
02:03
Creating a Mongita database requires just a single line of code. You can create one on disk or in memory. This course will use the on-disk client. Import the MongitaClientDisk
class from the mongita
module in main.py
.
02:20
Then create a new MongitaClientDisk
instance. Now you can create a new database dynamically—I’ll call mine db
—and a new collection dynamically as well, which I’ll call shapes
.
02:40
Be sure to remove the shapes
list previously put into code to avoid conflicts.
02:52
To insert a new document, call the .insert_one()
method with a dictionary. And to see the inserted document, get all the documents in the shapes
collection with the .find()
method on the collection. The dictionary here is a filter.
03:08 An empty dictionary means retrieve all documents in the collection. So how does this relate to FastAPI? Let’s take a look. You want to be able to insert a new shape into the database from the API, and that’s going to involve a POST request.
03:25
Just like the @get
decorator you’ve seen up to this point, there is also a @post
decorator. With a REST API, the data to create a new item is often included in the request body as JSON. As you’ve seen, the shape has a string name, integer number of sides, and finally an integer ID. To communicate this to FastAPI, you’ll use a pydantic base model.
03:49
So go ahead and import the BaseModel
class from the pydantic
module. Next, subclass BaseModel
to create a Shape
class.
04:02 Similar to a Django model, specify the properties of the shape, except use Python type hints.
04:12
The handler function for the post
route will now accept a shape instance.
04:23
The .dict()
method of the base model will return the data in a dictionary, and this dictionary can be used by Mongita to insert the document into the shapes
collection in the database.
04:37
And finally, it is customary to return the newly created item in the body of a response from a POST request. Next, change the .get_shapes()
method to remove the shape_id
and return all of the documents in the shapes
collection.
05:09
This code creates a dictionary for every document in the shapes
collection. Since the object_id
with key _id
that Mongita assigns to the document cannot automatically be serialized to JSON, add an if
clause to remove it. Real quick, before looking at Swagger, update the get_shape_by_id()
function to work with Mongita. The decorator and signature will remain the same.
05:39
First, check for the number of documents with the specified id
.
05:50
Use .find_one()
to get the document and then create a dictionary from the document.
05:57 When a document is found, return it
06:06
and omit the _id
key as it can’t be implicitly converted the JSON. And raise an exception if the document is not found. Time to look at Swagger. After the application restarts, expand the POST request for the /shapes
endpoint and click the Try it out button. The Request body is a text area with a boilerplate JSON document. Fill it out with the details of a new shape.
06:41
The API will return a response with a 200
status code. The body will contain the JSON for the new shape. Switch to the command line and insert another document using HTTPie.
06:56 This command formats a JSON string from the key-value pairs in the body of the POST request. As mentioned earlier, the body of the POST request for a REST API has the JSON data for the item to create.
07:11
And you can see that a status of 200
is returned, along with the JSON for the new item in the body. So FastAPI serializes and deserializes the BaseModel
subclasses to and from JSON for you, and also enforces the type hints for the model properties.
07:27 Pretty cool. Take one more look at the list of shapes in Mongita.
07:38 Whoops, a dodecagon has twelve, not fifteen, sides. But how can this error be resolved? You need a way to update existing items. And in the next lesson, you’ll learn how to do that.
danilolimadutra on March 17, 2024
Hi Carlos, I tried your code and all the endpoints are working fine. maybe you had some problem with the auto reload after changes.
sndselecta on Oct. 28, 2024
Irrelevant for course, I searched whether dodecagon was an actual term, and it was! Never heard of it before. Thank you. Quick correction: Dodecagon: 12 sides Pentadecagon: 15 sides
Become a Member to join the conversation.
Carlos Pumar-Frohberg on Feb. 24, 2023
Thank you for this awesome intro to FastAPI! I am not able to render the POST-method as shown in the course:
The docs do not render the option for submitting a POST request. They only render the prior GET requests.
Could anyone please help to see what I am missing here?
Thx in advance!