Sling Academy
Home/FastAPI/Getting the Request Body in FastAPI

Getting the Request Body in FastAPI

Last updated: March 19, 2023

In POST requests, values are sent in the body of the request. When the client side wants to upload files or images, they are most likely sent with a media type of multipart/form-data or application/x-www-form-urlencoded.

In FastAPI, parsing data from the request body works almost the same as query parameters except for one crucial thing is that you always have to use the Body function (don’t forget to import it from fastapi, otherwise you will receive an error). Let’s examine the minimal example below for more clarity:

from fastapi import FastAPI, Body

app = FastAPI()

@app.post('/products', status_code=201)
async def add_product(name: str = Body(...), price: float = Body(...)):
    return {"message": f"Product {name} with the price {price} has been added successfully."}

Launch our API:

uvicorn main:app --reload

Now use an HTTP client like Postman, Thunder Client, or whatsoever to test our work. Make a POST request with the following JSON body to http://localhost:8000:

{
  "name": "Blue Sling",
  "price": 99.99
}

And you will get this response:

{
  "message": "Product Blue Sling with the price 99.99 has been added successfully."
}

The status code is 201 (Created).

Using Pydantic Models

We can define pydantic models and use them as type hints in our path arguments. By doing so, FastAPI will automatically instantiate a model instance and validate the data of incoming requests.

Let’s rewrite the example above as follows:

from fastapi import FastAPI, Body
from pydantic import BaseModel

app = FastAPI()

class Product(BaseModel):
    name: str
    price: float


@app.post('/products', status_code=201)
async def add_product(product: Product = Body(..., embed=True), status_code=201):
    return {"message": f"Product {product.name} with the price {product.price} has been added successfully."}

Now send a POST request to our API with the following body:

{
  "product": {
    "name": "Blue Sling",
    "price": 99.99
  }
}

The response should look like this (with the status code 201):

{
  "message": "Product Blue Sling with the price 99.99 has been added successfully."
}

If the input data is invalid (such as the type of price is string or a field is missing like this:

{
  "product": {
    "name": "Blue Sling",
    "price": "abc"
  }
}

We’ll end up with the error 422 Unprocessable Entity:

{
  "detail": [
    {
      "loc": [
        "body",
        "product",
        "price"
      ],
      "msg": "value is not a valid float",
      "type": "type_error.float"
    }
  ]
}

If you go to http://localhost:8000/docs, you’ll have a detailed explanation of the API:

That’s it. Happy coding!

Next Article: FastAPI: How to extract request headers (2 approaches)

Series: FastAPI Request & Response Tutorials

FastAPI

You May Also Like

  • Popular useful built-in Jinja filters you should know
  • How to remove consecutive whitespace in rendered Jinja pages
  • How to format large numbers with thousand separators in Jinja template
  • How to format date time in Jinja templates
  • FastAPI + Jinja: How to create custom filters
  • How to pass variables from Python (FastAPI) to Jinja
  • How to decode Jinja response to string
  • How to create and use macros in Jinja
  • How to use namespace in Jinja
  • How to use if/ else in Jinja
  • How to use loops in Jinja
  • FastAPI + SQLAlchemy: Using cursor-based pagination
  • FastAPI: How to use macros in Jinja templates
  • Fixing Common Swagger UI Errors in FastAPI
  • FastAPI Error: 307 Temporary Redirect – Causes and Solutions
  • FastAPI Error: Expected UploadFile, received ‘str’
  • Resolving FastAPI ImportError: No Known Parent Package
  • FastAPI Error: No module named ‘pydantic_core._pydantic_core’
  • Resolving FastAPI 422 Error: Value is not a valid dict