API Responses and Media Types
In this codebase, API responses and their associated media types are modeled using Pydantic classes that directly map to the OpenAPI Specification. These models allow for detailed documentation of status codes, response headers, and the structure of the data returned by the API.
The Response Object
The Response class in fastapi/openapi/models.py represents an OpenAPI Response Object. It is the primary container for describing what a client can expect from a specific status code.
class Response(BaseModelWithConfig):
description: str
headers: dict[str, Header | Reference] | None = None
content: dict[str, MediaType] | None = None
links: dict[str, Link | Reference] | None = None
In practice, you define these responses using the responses parameter in path operation decorators. FastAPI's internal logic in fastapi/openapi/utils.py processes this dictionary to generate the final OpenAPI schema.
Defining Additional Responses
You can provide a dictionary where keys are status codes (as strings or integers) and values are dictionaries describing the response.
@router.get(
"/items/{item_id}",
responses={
"400": {"description": "Error with str"},
"5XX": {"model": ResponseModel},
"default": {"model": ResponseModel},
},
)
async def read_item(item_id: str):
return {"item_id": item_id}
As seen in tests/test_additional_responses_router.py, FastAPI supports status code ranges like "5XX" and the special "default" key for responses that don't match any other defined status code.
Media Types and Content
The content field of a Response maps media type strings (like application/json) to MediaType objects. The MediaType class defines the schema and examples for the response body.
class MediaType(BaseModelWithConfig):
schema_: Schema | Reference | None = Field(default=None, alias="schema")
example: Any | None = None
examples: dict[str, Example | Reference] | None = None
encoding: dict[str, Encoding] | None = None
When you provide a model in the responses dictionary, FastAPI automatically creates a MediaType object for the default media type (usually application/json) and assigns the model's schema to the schema_ field.
Rich Examples with the Example Object
To provide detailed documentation, you can use the Example object. Unlike most other OpenAPI models in this codebase, Example is implemented as a TypedDict in fastapi/openapi/models.py.
class Example(TypedDict, total=False):
summary: str | None
description: str | None
value: Any | None
externalValue: AnyUrl | None
Using openapi_examples
FastAPI parameters like Body, Query, Path, and Header (defined in fastapi/params.py) accept an openapi_examples argument. This allows you to provide multiple named examples that appear in the generated documentation.
@app.post("/examples/")
def examples(
item: Item = Body(
openapi_examples={
"Example One": {
"summary": "Example One Summary",
"description": "Example One Description",
"value": {"data": "Data in Body examples, example1"},
},
"Example Two": {
"value": {"data": "Data in Body examples, example2"},
},
},
),
):
return item
This pattern, demonstrated in tests/test_openapi_examples.py, ensures that the examples are correctly placed in the examples field of the OpenAPI Media Type Object, rather than the JSON Schema examples field, which is handled separately.
Encoding for Complex Media Types
For complex media types like multipart/form-data or application/x-www-form-urlencoded, the Encoding class defines how individual properties of the object are serialized.
class Encoding(BaseModelWithConfig):
contentType: str | None = None
headers: dict[str, Union["Header", Reference]] | None = None
style: str | None = None
explode: bool | None = None
allowReserved: bool | None = None
This is particularly relevant when using Form or File parameters. FastAPI uses these models to describe how form fields should be encoded, including custom content types for file uploads within a multipart request.
Internal Schema Generation
The conversion from route definitions to these OpenAPI models happens in fastapi/openapi/utils.py. The function get_openapi_path iterates through the routes and builds the responses dictionary:
- It identifies the default success response based on the
status_codeandresponse_class. - It adds the
application/json(or other media type) content based on theresponse_model. - It merges any additional responses provided in the
responsesdecorator parameter. - It automatically adds a
422 Unprocessable Entityresponse if the operation has parameters that could fail validation.
This structured approach ensures that the generated OpenAPI documentation is a faithful representation of the actual API behavior defined in the code.