Saltar al contenido

Modelos de Parámetros de Consulta

Si tienes un grupo de parámetros de consulta que están relacionados, puedes crear un modelo Pydantic para declararlos.

Esto te permitiría reutilizar el modelo en múltiples lugares y también declarar validaciones y metadatos para todos los parámetros a la vez. 😎

Nota

Esto es soportado desde la versión 0.115.0 de FastAPI. 🤓

Parámetros de Consulta con un Modelo Pydantic

Declara los parámetros de consulta que necesites en un modelo Pydantic, y luego declara el parámetro como Query:

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
🤓 Otras versiones y variantes

Consejo

Preferible usar la versión con Annotated si es posible.

from typing import 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: FilterParams = Query()):
    return filter_query

FastAPI extraerá los datos de cada campo de los parámetros de consulta en la petición y te dará el modelo Pydantic que definiste.

Revisar la Documentación

Puedes ver los parámetros de consulta en la interfaz de documentación en /docs:

Prohibir Parámetros de Consulta Extra

En algunos casos de uso especiales (probablemente no muy comunes), podrías querer restringir los parámetros de consulta que quieres recibir.

Puedes usar la configuración del modelo de Pydantic para prohibir cualquier campo extra:

from typing import Annotated, Literal

from fastapi import FastAPI, Query
from pydantic import BaseModel, Field

app = FastAPI()


class FilterParams(BaseModel):
    model_config = {"extra": "forbid"}

    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
🤓 Otras versiones y variantes

Consejo

Preferible usar la versión con Annotated si es posible.

from typing import Literal

from fastapi import FastAPI, Query
from pydantic import BaseModel, Field

app = FastAPI()


class FilterParams(BaseModel):
    model_config = {"extra": "forbid"}

    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: FilterParams = Query()):
    return filter_query

Si un cliente intenta enviar algunos datos extra en los parámetros de consulta, recibirá una respuesta de error.

Por ejemplo, si el cliente intenta enviar un parámetro de consulta tool con un valor de plumbus, como:

https://example.com/items/?limit=10&tool=plumbus

Recibirán una respuesta de error diciéndoles que el parámetro de consulta tool no está permitido:

{
    "detail": [
        {
            "type": "extra_forbidden",
            "loc": ["query", "tool"],
            "msg": "Extra inputs are not permitted",
            "input": "plumbus"
        }
    ]
}

Resumen

Puedes usar modelos Pydantic para declarar parámetros de consulta en FastAPI. 😎

Consejo

Alerta de spoiler: también puedes usar modelos Pydantic para declarar cookies y headers, pero leerás sobre eso más adelante en el tutorial. 🤫