Skip to main content

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:

  1. It identifies the default success response based on the status_code and response_class.
  2. It adds the application/json (or other media type) content based on the response_model.
  3. It merges any additional responses provided in the responses decorator parameter.
  4. It automatically adds a 422 Unprocessable Entity response 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.