YouTip LogoYouTip

Fastapi Path Params Validation

FastAPI Path Parameter Value Validation |

\n\n

Just like using Query to add validation for query parameters, you can use Path to declare value validation and metadata for path parameters.

\n\n
\n\n

Import Path

\n\n

Import Path from fastapi, and Annotated from typing:

\n\n
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

Path 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
\n\n

Numeric Validation

\n\n

Both Path and Query support the following numeric validation arguments:

\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
ArgumentMeaningEnglish Source
gtGreater thangreater than
geGreater than or equalgreater than or equal
ltLess thanless than
leLess than or equalless than or equal
\n\n

Greater than or equal (ge)

\n\n

Restrict item_id to be β‰₯ 1:

\n\n
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\n

Combining numeric validations

\n\n
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 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\n

Float validation

\n\n

Numeric validation also applies to floats. The distinction between gt (greater than) and ge (greater than or equal) is important in float scenarios:

\n\n
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\n

When using both Path and Query, using Annotated avoids issues related to parameter order:

\n\n
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\n

Key points for numeric validation of path parameters:

\n\n
    \n
  • Use Annotated + Path to 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
  • Path and Query share 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
← Fastapi Response ModelFastapi Request Body β†’