FastAPI Path Parameter Value Validation |
\n\nJust like using Query to add validation for query parameters, you can use Path to declare value validation and metadata for path parameters.
\n\n
Import Path
\n\nImport Path from fastapi, and Annotated from typing:
from typing import Annotated\n\nfrom fastapi import FastAPI, Path\n\napp = FastAPI()\n\n@app.get("/items/{item_id}")\n\nasync def read_items(\n\n # Add metadata and validation to the path parameter\n\n item_id: Annotated[int, Path(title="Product ID", description="Product ID to retrieve", ge=1)],\n\n):\n\n return {"item_id": item_id}\n\n\n\n\n\nPath parameters are always required because they are part of the URL path. Even if you declare a default value for them, they are still treated as required parameters.
\n
\n\n
Numeric Validation
\n\nBoth Path and Query support the following numeric validation arguments:
| Argument | \nMeaning | \nEnglish Source | \n
|---|---|---|
gt | \n Greater than | \ngreater than | \n
ge | \n Greater than or equal | \ngreater than or equal | \n
lt | \n Less than | \nless than | \n
le | \n Less than or equal | \nless than or equal | \n
Greater than or equal (ge)
\n\nRestrict item_id to be β₯ 1:
from typing import Annotated\n\nfrom fastapi import FastAPI, Path\n\napp = FastAPI()\n\n@app.get("/items/{item_id}")\n\nasync def read_items(\n\n item_id: Annotated[int, Path(ge=1)], # item_id must be β₯ 1\n\n):\n\n return {"item_id": item_id}\n\n\nCombining numeric validations
\n\nfrom typing import Annotated\n\nfrom fastapi import FastAPI, Path, Query\n\napp = FastAPI()\n\n@app.get("/items/{item_id}")\n\nasync def read_items(\n\n # item_id must be > 0 and β€ 1000\n\n item_id: Annotated[int, Path(gt=0, le=1000)],\n\n # Query parameters can also use numeric validation\n\n size: Annotated[float, Query(gt=0, lt=10.5)] = 5.0,\n\n):\n\n return {"item_id": item_id, "size": size}\n\n\nFloat validation
\n\nNumeric validation also applies to floats. The distinction between gt (greater than) and ge (greater than or equal) is important in float scenarios:
from typing import Annotated\n\nfrom fastapi import FastAPI, Path, Query\n\napp = FastAPI()\n\n@app.get("/items/{item_id}")\n\nasync def read_items(\n\n item_id: Annotated[int, Path(ge=1, le=1000)],\n\n # size must be > 0 and < 10.5\n\n # 0.5 is valid, but 0.0 and 0 are not (because gt=0 strictly requires > 0)\n\n size: Annotated[float, Query(gt=0, lt=10.5)],\n\n):\n\n return {"item_id": item_id, "size": size}\n\n\n\n\n
Mixing Path and Query Parameters
\n\nWhen using both Path and Query, using Annotated avoids issues related to parameter order:
from typing import Annotated\n\nfrom fastapi import FastAPI, Path, Query\n\napp = FastAPI()\n\n@app.get("/items/{item_id}")\n\nasync def read_items(\n\n # With Annotated, parameter order doesnβt matter\n\n item_id: Annotated[int, Path(title="Product ID", ge=1, le=1000)],\n\n q: Annotated[str | None, Query(max_length=50)] = None,\n\n):\n\n results = {"item_id": item_id}\n\n if q:\n\n results.update({"q": q})\n\n return results\n\n\n\n\n
Summary
\n\nKey points for numeric validation of path parameters:
\n\n- \n
- Use
Annotated+Pathto declare validation rules for path parameters \n - Numeric validation:
gt(greater than),ge(greater than or equal),lt(less than),le(less than or equal) \n PathandQueryshare the same validation arguments, including string validation (e.g.,min_length) and metadata (e.g.,title,description) \n - Path parameters are always required, regardless of whether a default value is declared \n
YouTip