Data Validation in FastAPI

Data Validation in FastAPI

Data Validation in FastAPI ensures that incoming request data is correct, complete, and in the expected format. It uses Pydantic models or Python's Annotated type hints to define and enforce validation rules. This helps prevent errors, improve API reliability, and make the code cleaner and more secure.

Query Parameter Validation

Query Parameter Validation in FastAPI ensures that values passed as query parameters meet specified criteria like type, length, range, etc., using function parameters and Query() from fastapi. This helps catch invalid inputs automatically and returns detailed error responses.

Commonly Used Parameters in Query():

default: Sets a default value for the query parameter if not provided.

alias: Use a different name in the URL than in the function parameter.

title: Adds a title in the documentation.

description: Adds a description in the API docs.

min_length: Minimum length allowed for string values.

max_length: Maximum length allowed for string values.

pattern: Validates string format using regular expression.

ge: Value must be greater than or equal to this number.

le: Value must be less than or equal to this number.

gt: Value must be greater than this number.

lt: Value must be less than this number.

deprecated: Marks the parameter as deprecated in the documentation.

include_in_schema: If False, hides the parameter from OpenAPI docs.

Type Conversion Example
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/search/")
def search_items(
        keyword: str = Query(default=None, alias='q', min_length=3, max_length=50),     
        page: int = Query(defualt=1, ge=1, le=100, description="Page number (1-100)")
    ):
    return {"keyword": keyword, "page": page}

# Example request: http://localhost:8000/search?q=python&page=5

Path Parameter Validation

Path Parameter Validation in FastAPI ensures that values passed through URL paths meet specific criteria like type, length, or pattern using validators such as Path(). This helps enforce constraints and improves API reliability by validating inputs directly in the route.

Commonly Used Parameters in Path():

Path parameters use Path() with similar validations as Query() (like min_length, ge, le), but cannot use default or alias since they're always required and part of the URL path.

Type Conversion Example
from fastapi import FastAPI, Path

app = FastAPI()

@app.get("/items/{item_id}")
def read_item(
        item_id: int = Path(..., ge=1, le=100,
        description="ID of the item (1-100)")
    ):
    return {"item_id": item_id}

# Example request: http://localhost:8000/items/10

Data Validation with Annotated

Data validation with Annotated in FastAPI combines type hints with validation metadata, making code cleaner and more readable. It allows you to attach constraints (like Query, Path) directly to parameter types using Python's typing.Annotated .

Query Parameter with Annotated:

Multiple Query Parameters Example
from fastapi import FastAPI, Query
from typing import Annotated

app = FastAPI()

@app.get("/search/")
def search(
        q: Annotated[str, Query(min_length=3, max_length=50)],    # Required
        page: Annotated[int, Query(ge=1, le=10)] = 1             # Optional
    ):
    return {"query": q, "page": page}

# Example request: http://localhost:8000/search?q=mobile&page=5

Path Parameter with Annotated:

Multiple Query Parameters Example
from fastapi import FastAPI, Path
from typing import Annotated

app = FastAPI()

@app.get("/users/{user_id}")
def get_user(user_id: Annotated[int, Path(ge=1, le=100)]):
    return {"user_id": user_id}

# Example request: http://localhost:8000/users/10

Combining Query and Path Parameters

In FastAPI, you can use Annotated to validate both path and query parameters together in one function. Path parameters are required and part of the URL, while query parameters are optional and used to filter or modify the request.

List Query Parameters Example
from fastapi import FastAPI, Path, Query
from typing import Annotated

app = FastAPI()

@app.get("/products/{product_id}")
def get_product(
        product_id: Annotated[int, Path(ge=1, le=1000)],
        show_details: Annotated[bool, Query()] = False
    ):
    return {"product_id": product_id, "show_details": show_details}

# Example: http://localhost:8000/products/42?show_details=true

Exercise

  1. Fill in the Blanks:
    • - Django is a __________ written in Python that simplifies web development.
    • - Django follows the __________ architecture, which stands for __________.
    • - To install Django, the package manager used is __________.
    • - You can check the installed Django version using the command __________.
    • - MVC stands for __________.