Request Parameters as Dependencies
To define and reuse common request parameters like query strings, headers, or cookies across multiple endpoints, FastAPI provides specialized parameter classes that can be used with Annotated or as dependencies.
Defining Validated Parameters
You can add validation and metadata to individual parameters using Path, Query, Header, and Cookie from fastapi.params.
from typing import Annotated
from fastapi import FastAPI, Path, Query
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: Annotated[int, Path(title="The ID of the item", ge=1)],
q: Annotated[str | None, Query(alias="item-query", max_length=50)] = None,
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
In this example:
Pathensuresitem_idis part of the URL path and is greater than or equal to 1 (ge=1).Querydefines an optional query parameterqwith a customaliasused in the URL (e.g.,?item-query=fixed).
Grouping Parameters with Pydantic Models
When you have a set of related parameters used in multiple places, you can group them into a Pydantic model. This allows you to treat the entire group as a single dependency.
from typing import Annotated, Literal
from fastapi import FastAPI, Query
from pydantic import BaseModel, Field
app = FastAPI()
class FilterParams(BaseModel):
limit: int = Field(100, gt=0, le=100)
offset: int = Field(0, ge=0)
order_by: Literal["created_at", "updated_at"] = "created_at"
tags: list[str] = []
@app.get("/items/")
async def read_items(filter_query: Annotated[FilterParams, Query()]):
return filter_query
By using Annotated[FilterParams, Query()], FastAPI extracts the fields of FilterParams from the request's query parameters.
Capturing Headers and Cookies in Models
The same pattern applies to Header and Cookie. FastAPI will map the model fields to the corresponding request headers or cookies.
from typing import Annotated
from fastapi import FastAPI, Header
from pydantic import BaseModel
app = FastAPI()
class CommonHeaders(BaseModel):
host: str
save_data: bool
if_modified_since: str | None = None
x_tag: list[str] = []
@app.get("/headers/")
async def read_headers(headers: Annotated[CommonHeaders, Header()]):
return headers
Parameter Specifics
Path Parameters are Always Required
FastAPI enforces that Path parameters cannot have a default value because they are a mandatory part of the URL structure. In fastapi/params.py, the Path class explicitly asserts that the default value must be ... (Ellipsis):
# fastapi/params.py
class Path(Param):
def __init__(self, default: Any = ..., **kwargs):
assert default is ..., "Path parameters cannot have a default value"
# ...
Automatic Header Underscore Conversion
HTTP headers often use hyphens (e.g., User-Agent), but Python variable names typically use underscores (user_agent). The Header class includes a convert_underscores attribute (defaulting to True) that automatically handles this conversion.
@app.get("/user-agent/")
async def get_user_agent(user_agent: Annotated[str, Header()]):
# FastAPI looks for the "User-Agent" header automatically
return {"User-Agent": user_agent}
Troubleshooting
Path Parameter Default Values
If you attempt to provide a default value to a Path parameter, FastAPI will raise an AssertionError during application startup.
- Incorrect:
item_id: int = Path(default=1) - Correct:
item_id: int = Path()oritem_id: Annotated[int, Path()]
Duplicate Cookie Values
Unlike Header and Query, which can capture multiple values into a list[str], Cookie parameters typically only capture the last value if multiple cookies with the same name are sent by the client.
Capturing Extra Parameters
If you use a Pydantic model to group parameters and want to capture parameters that are not explicitly defined in your model, set extra="allow" in the model's ConfigDict.
from pydantic import BaseModel, ConfigDict
class DynamicQuery(BaseModel):
model_config = ConfigDict(extra="allow")
page: int = 1
When used with Annotated[DynamicQuery, Query()], any additional query parameters sent in the request will be available in the model's model_extra attribute.