new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

FastAPI · Tutorial · all subjects

request-bodies

101 notes in this subject, read out of this brain and free to use. This is page 1 of 2.

Optional body parameter with None default

To make a body parameter optional, set its default value to None. FastAPI will then not require that parameter in the request body.

Mix Path, Query, and body parameters in one operation

FastAPI allows you to mix Path, Query, and request body parameter declarations freely in the same path operation function. You can declare body parameters as optional by setting the default to None.

Multiple Pydantic model body parameters

When you declare multiple body parameters (such as item and user, where both are Pydantic models), FastAPI uses the parameter names as keys in the JSON body. FastAPI will expect a JSON body with each model nested under its parameter name as a key.

Multiple body parameters JSON structure

When declaring multiple body parameters like item (Item model) and user (User model), the expected JSON body structure is: {"item": {item_fields}, "user": {user_fields}}. Each parameter name becomes a top-level key with its model contents nested inside.

Body import for singular values in request body

FastAPI provides a Body import similar to Query and Path for defining extra data for parameters. Use Body to explicitly instruct FastAPI to treat singular values (non-Pydantic models) as body parameters rather than query parameters.

Singular value treated as query parameter by default

By default, if you declare a singular value (not a Pydantic model) in a path operation function, FastAPI assumes it is a query parameter. You must use Body to override this and make it part of the request body.

Body parameter with singular value in JSON

When using Body with a singular value like importance: int, FastAPI includes it as a top-level key in the JSON body alongside any Pydantic model parameters. The expected structure would be: {"item": {...}, "user": {...}, "importance": 5}.

Query parameters with multiple body parameters

You can declare additional query parameters alongside multiple body parameters. Singular values are interpreted as query parameters by default, so you do not need to explicitly use Query for them. For example: q: str | None = None.

Body has same validation and metadata as Query and Path

The Body parameter has all the same extra validation and metadata parameters available as Query, Path, and other FastAPI parameter types.

Embed single body parameter with Body(embed=True)

When you have a single Pydantic model body parameter, FastAPI by default expects the JSON body to be the model's contents directly. Use Body(embed=True) to make FastAPI expect the model nested under a key matching the parameter name.

Single body parameter with embed=True JSON structure

When using Body(embed=True) with a single Item parameter, FastAPI expects the JSON body to be: {"item": {item_fields}} instead of directly: {item_fields}.

Annotated with Body embed parameter

To use Body with embed for a single body parameter, use the syntax: item: Annotated[Item, Body(embed=True)]. This annotation tells FastAPI to embed the model under its parameter name as a key.

Single request body constraint

An HTTP request can only have a single body. FastAPI handles multiple body parameters by using parameter names as keys in that single body, and it validates and documents the correct schema.

FastAPI automatic validation and documentation for multiple body parameters

When you declare multiple body parameters, FastAPI performs automatic conversion from the request, validates the compound data against all models, and documents the schema correctly in the OpenAPI schema and automatic docs.

Partial updates workflow with PATCH

To apply partial updates with PATCH: (1) Optionally use PATCH instead of PUT, (2) Retrieve the stored data, (3) Put that data in a Pydantic model, (4) Generate a dict without default values from the input model using exclude_unset, (5) Create a copy of the stored model using .model_copy(update=...) with the partial updates, (6) Convert the copied model using jsonable_encoder, (7) Save to database, (8) Return the updated model.

PUT operation replaces entire item

HTTP PUT is used to receive data that should replace the existing data entirely. If you send a PUT request with incomplete data (missing fields that exist in the stored item), those missing fields will be replaced with default values from the model definition.

PUT replacement warning - missing fields reset to defaults

When using PUT to update an item, any fields not included in the request body will be replaced with their default values. For example, if an item has tax: 20.2 but the PUT request doesn't include a tax field, the stored item's tax will be replaced with the model's default value for tax (e.g., 10.5).

PATCH operation for partial updates

HTTP PATCH is used for partial updates, allowing you to send only the data you want to update while leaving the rest intact. PATCH is less commonly used than PUT, and many teams use only PUT even for partial updates. FastAPI does not impose restrictions on how you use them.

Pydantic exclude_unset parameter for partial updates

Use the exclude_unset=True parameter in Pydantic's .model_dump() method to generate a dict containing only the data that was explicitly set when creating the model, excluding default values. This is useful for partial updates to avoid overwriting stored values with default values.

Pydantic model_copy with update parameter

Use .model_copy(update=update_data) to create a copy of an existing Pydantic model while updating specific attributes with new values from a dict. This is useful for applying partial updates to a stored model.

jsonable_encoder converts data for storage

Use jsonable_encoder to convert input data to data that can be stored as JSON, such as converting datetime objects to strings. This ensures data can be properly stored in databases like NoSQL systems.

Optional fields required for partial updates

To receive partial updates that can omit all attributes, the Pydantic model must have all attributes marked as optional with default values or None. For models used in creation endpoints, all required fields should be mandated. The Extra Models pattern can help distinguish between update models (all optional) and creation models (required fields).

Partial update model still validates input

Even when receiving partial updates, Pydantic still validates the input model against the schema. The input model will validate according to its field definitions, so optional fields must be properly marked to allow partial updates.

Parameter requirement determined by default value, not type annotation

FastAPI determines if a parameter is required based on whether it has a default value, not based on type annotations like `str | None`. A parameter with `= None` as default is not required, regardless of its type annotation. Adding type annotations allows your editor to give better support and detect errors.

Request body definition and purpose

A request body is data sent by the client to your API. A response body is the data your API sends to the client. Your API almost always has to send a response body, but clients don't necessarily need to send request bodies all the time—sometimes they only request a path with query parameters.

Alternative to Pydantic models for request bodies

If you don't want to use Pydantic models, you can also use Body parameters. See the documentation for Body with multiple parameters and singular values in body.

HTTP methods for sending request bodies

To send data in a request body, you should use one of: POST (the most common), PUT, DELETE, or PATCH. Sending a body with a GET request has undefined behavior in the specifications and is discouraged. FastAPI supports it for very complex/extreme use cases, but interactive docs with Swagger UI will not show documentation for the body when using GET, and proxies in the middle might not support it.

Use Pydantic BaseModel for request bodies

To declare a request body, you use Pydantic models with all their power and benefits. First, import BaseModel from pydantic, then declare your data model as a class that inherits from BaseModel, using standard Python types for all attributes.

Optional and required attributes in Pydantic models

When a model attribute has a default value, it is not required. Otherwise, it is required. Use None to make an attribute optional. For example, if an attribute is declared as `description: str | None = None`, the description field is optional.

Declare request body as path operation parameter

To add a request body to your path operation, declare it the same way you declared path and query parameters, and declare its type as the Pydantic model you created.

FastAPI automatic request body processing

With a Pydantic model type declaration, FastAPI automatically: reads the body of the request as JSON; converts the corresponding types (if needed); validates the data and returns a clear error indicating exactly where and what was incorrect if the data is invalid; provides the received data in the parameter as the declared model type; generates JSON Schema definitions for your model; and includes those schemas in the generated OpenAPI schema for use by automatic documentation UIs.

Request body provides editor support and type hints

When you use a Pydantic model for request bodies instead of receiving a dict, you get type hints and auto-completion in your editor for all model attributes and their types. You also get error checks for incorrect type operations. This support works across Visual Studio Code, PyCharm, and most other Python editors.

Combining request body with path parameters

You can declare path parameters and request body at the same time. FastAPI will recognize that function parameters matching path parameters should be taken from the path, and function parameters declared as Pydantic models should be taken from the request body.

Combining body, path, and query parameters

You can declare body, path, and query parameters all at the same time. FastAPI will recognize each of them and take the data from the correct place based on these rules: if the parameter is declared in the path, it will be used as a path parameter; if the parameter is of a singular type (like int, float, str, bool), it will be interpreted as a query parameter; if the parameter is declared as a Pydantic model type, it will be interpreted as a request body.

jsonable_encoder function purpose

The jsonable_encoder() function converts data types like Pydantic models to JSON-compatible formats. It is useful when you need to store data in a database or other system that only accepts JSON-compatible types like dict, list, str, int, float, bool, and None.

jsonable_encoder return value

jsonable_encoder() receives an object (such as a Pydantic model) and returns a Python standard data structure (like a dict) with all values and sub-values converted to JSON-compatible types. It does not return a JSON string, but a structure that can be passed to json.dumps().

jsonable_encoder converts datetime to string

When jsonable_encoder() encounters a datetime object, it converts it to a string in ISO 8601 format, since datetime objects are not JSON compatible.

jsonable_encoder converts Pydantic models to dict

The jsonable_encoder() function converts Pydantic model objects (objects with attributes) to dictionaries, making them compatible with JSON serialization and database storage.

jsonable_encoder is used internally by FastAPI

FastAPI uses jsonable_encoder() internally to convert data, but it is also available for direct use in many other scenarios where JSON-compatible conversion is needed.

Unpacking dict with ** operator to create Pydantic models

You can pass a dictionary to a Pydantic model constructor using the ** unpacking operator. For example, UserInDB(**user_dict) unpacks the dictionary as keyword arguments to the UserInDB constructor. This can be combined with additional keyword arguments: UserInDB(**user_in.model_dump(), hashed_password=hashed_password).

Create Pydantic model from another model's data

You can create a new Pydantic model instance from another model's data by calling .model_dump() on the source model and unpacking it with ** into the target model's constructor. This allows data conversion between related models.

Reduce duplication with UserBase inheritance

To avoid repeating attribute names and types across multiple related models, create a base model (like UserBase) with common fields and inherit from it in specific models. The subclasses inherit all validation, type declarations, and documentation from the base model while declaring only their differences.

Union response type with anyOf in OpenAPI

You can declare a response as a Union of two or more types using typing.Union, which appears as anyOf in OpenAPI. This allows an endpoint to return different model types. When defining a Union, place the most specific type first, followed by less specific types.

Union syntax in response_model argument vs type annotation

When using Union in a type annotation, Python 3.10+ allows the | syntax (e.g., PlaneItem | CarItem). However, when passing Union as a value to the response_model argument, you must use typing.Union even in Python 3.10, because the | operator would try to perform an invalid operation instead of being interpreted as a type annotation.

Declare response as list of models

You can declare responses as lists of Pydantic models using the standard Python list type hint. For example, response_model=list[Item] declares that the response is a list of Item models.

Multiple models for users with different password states

When handling users, create multiple related models: an input model that accepts plaintext passwords, an output model that excludes passwords from responses, and a database model that stores hashed passwords. Each model handles a different state of the user entity.

Arbitrary dict response without Pydantic model

You can declare a response using a plain dict without a Pydantic model by specifying only the type of keys and values. This is useful when you don't know the valid field names beforehand. For example, response_model=dict[str, str] declares a response dict with string keys and values.

Multiple data models per entity for different states

You don't need a single data model per entity. Entities can have multiple related models representing different states. For example, the user entity can have different models for the state with a plaintext password, the state with a hashed password, and the state with no password.

Pydantic model_dump() method

Pydantic models have a .model_dump() method that returns a dictionary containing the model's data. For example, if user_in is a UserIn Pydantic model, calling user_in.model_dump() returns a dict with the model's fields and values.

Declaring header parameters with Pydantic model

Declare the header parameters you need in a Pydantic model, then declare the parameter as Header in your route. FastAPI will extract the data for each field from the headers in the request and give you the Pydantic model you defined.

Header parameter models for grouping related headers

You can create a Pydantic model to declare a group of related header parameters. This allows you to re-use the model in multiple places and declare validations and metadata for all the parameters at once. This feature is supported since FastAPI version 0.115.0.

Forbidding extra headers with Pydantic model configuration

Use Pydantic's model configuration to forbid any extra fields by setting forbid to True in the model config. If a client tries to send extra headers, they will receive an error response with type 'extra_forbidden' indicating which header parameter is not allowed.

Automatic underscore to hyphen conversion in header parameter names

When you have underscore characters in header parameter names, they are automatically converted to hyphens. For example, a parameter named save_data in the code becomes the HTTP header save-data and displays that way in the docs.

Disabling underscore to hyphen conversion in header models

You can disable the automatic conversion of underscores to hyphens in header parameter Pydantic models by setting convert_underscores to False in the model configuration. However, be aware that some HTTP proxies and servers disallow headers with underscores.

Query parameter models with Pydantic

You can declare related query parameters as fields in a Pydantic model, then declare the parameter as Query in your path operation function. FastAPI will extract the data for each field from the query parameters in the request and validate them according to the model definition.

Forbid extra query parameters with Pydantic model configuration

You can use Pydantic's model configuration to forbid extra query parameters by setting the model config to forbid extra fields. If a client sends a query parameter that is not declared in the model, they will receive an error response with type 'extra_forbidden' and a message stating 'Extra inputs are not permitted'.

Extra query parameter error response format

When a client sends an extra query parameter and the Pydantic model forbids extras, the error response includes a detail array with an object containing: type set to 'extra_forbidden', loc set to ['query', <parameter_name>], msg set to 'Extra inputs are not permitted', and input set to the value provided.

Pydantic models for declaring form fields

You can declare form fields in FastAPI using Pydantic models. Declare a Pydantic model with the fields you want to receive as form fields, then declare the parameter as Form. FastAPI will extract the data for each field from the form data in the request and provide you with the Pydantic model instance.

Form models support in FastAPI versions

Form models using Pydantic are supported since FastAPI version 0.113.0.

Forbid extra form fields with Pydantic configuration

You can restrict form fields to only those declared in the Pydantic model and forbid any extra fields by using Pydantic's model configuration to forbid extra fields. When a client sends extra data not declared in the model, they will receive an error response with type 'extra_forbidden', location in the form body, and the message 'Extra inputs are not permitted'.

Give your agent this brain