FastAPI Validación de parámetros de consulta

FastAPI te permite declarar reglas de validación y metadatos adicionales para los parámetros de consulta, como límites de longitud de cadena, coincidencia con expresiones regulares, etc. MedianteQueryyAnnotated, puedes mejorar la validación de parámetros sin cambiar la lógica de la función.


Validación básica

El siguiente ejemplo es para el parámetro de consultaqañade un límite de longitud máxima:

Ejemplo

from typing import Annotated
from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    # Usa Annotated + Query para añadir validación
    q: Annotated[str | None, Query(max_length=50)] = None,
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

Explicación del código:

ParteDescripción
Annotated[str | None, ...]Anotación de tipo, indica queqpuede ser una cadena o None
Query(max_length=50)Regla de validación,qsu longitud máxima es 50 caracteres
= NoneValor predeterminado, hace que el parámetro sea opcional

FastAPI recomienda usarAnnotatedpara declarar la validación, en lugar de usarQuerycomo valor predeterminado. PorqueAnnotateden el modo, el valor predeterminado de la función es el valor predeterminado real, más acorde con la intuición de Python, y con mejor soporte de editores y herramientas de verificación de tipos.


Añadir más validaciones

Puedes añadir varias reglas de validación al mismo tiempo:

Ejemplo

from typing import Annotated
from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    # Limita a la vez la longitud mínima, la longitud máxima y la expresión regular
    q: Annotated[str | None, Query(min_length=3, max_length=50, pattern="^fixedquery$")] = None,
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

Parámetros de validación de cadenas:

ParámetroTipoDescripción
min_lengthintLongitud mínima
max_lengthintLongitud máxima
patternstrCoincidencia de expresión regular

Expresión regular^fixedquery$el significado de:

  • ^-- debe comenzar con los siguientes caracteres
  • fixedquery-- el valor debe ser exactamente igual afixedquery
  • $-- termina aquí, no puede haber otros caracteres después

Validación con valor predeterminado

Puedes establecer simultáneamente un valor predeterminado y reglas de validación para el parámetro de consulta:

Ejemplo

from typing import Annotated
from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    # El valor predeterminado es "fixedquery" y se requiere una longitud mínima de 3
    q: Annotated[str, Query(min_length=3)] = "fixedquery",
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

Cualquier tipo de valor predeterminado (incluidos los noNonevalores) hará que el parámetro sea opcional. Sin valor predeterminado niQuery(default=...)el parámetro es obligatorio.


Parámetros obligatorios

UsandoQuerysi no se declara un valor predeterminado, el parámetro es obligatorio:

Ejemplo

from typing import Annotated
from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    # No hay = None, por lo que q es un parámetro obligatorio
    q: Annotated[str, Query(min_length=3)],
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    results.update({"q": q})
    return results

Obligatorio pero puede ser None

A veces necesitas que el cliente envíe un valor, pero el valor puede serNone:

Ejemplo

from typing import Annotated
from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    # El cliente debe proporcionar el parámetro q, pero el valor puede ser None
    q: Annotated[str | None, Query(min_length=3)],
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

Lista de parámetros de consulta / múltiples valores

UsandoQueryse pueden declarar parámetros de consulta que reciben múltiples valores:

Ejemplo

from typing import Annotated
from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    # q puede aparecer varias veces en la URL, los valores se recogen como lista
    q: Annotated[list[str] | None, Query()] = None,
):
    query_items = {"q": q}
    return query_items

Accede ahttp://127.0.0.1:8000/items/?q=foo&q=bar, devuelve:

{"q": ["foo", "bar"]}

Para declarar un parámetro de consulta de tipolist, debes usar explícitamenteQuery(), de lo contrario FastAPI lo interpretará como cuerpo de solicitud.


Declarar metadatos

QueryTambién admite añadir metadatos a los parámetros, esta información aparecerá en la documentación de la API:

Ejemplo

from typing import Annotated
from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: Annotated[str | None, Query(
        title="cadena de consulta",           # Título del parámetro
        description="cadena de consulta para filtrar productos",  # Descripción del parámetro
        min_length=3,
        max_length=50,
        alias="item-query",    # Alias del nombre del parámetro en la URL
        deprecated=True,       # Marcado como obsoleto
    )] = None,
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

Explicación de los parámetros de metadatos:

ParámetroDescripciónEscenario de uso
aliasAlias del nombre del parámetro en la URLCuando el nombre del parámetro contiene un guion (comoitem-query), no es un nombre de variable válido en Python
titleTítulo del parámetroMuestra el título del parámetro en la documentación
descriptionDescripción del parámetroMuestra la descripción detallada del parámetro en la documentación
deprecatedMarcado como obsoletoEl parámetro aún se puede usar, pero se marcará como "obsoleto" en la documentación
include_in_schemaSi aparece en la documentación de la APIConfigúralo comoFalsepuede ocultar el parámetro

Excluir parámetros de OpenAPI

Si un parámetro de consulta no debe aparecer en la documentación de la API:

Ejemplo

from typing import Annotated
from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    # hidden_query no aparecerá en la documentación de la API, pero aún se puede usar
    hidden_query: Annotated[str | None, Query(include_in_schema=False)] = None,
):
    if hidden_query:
        return {"hidden_query": hidden_query}
    return {"items": [{"item_id": "Foo"}]}

Resumen

Puntos clave de la validación de parámetros de consulta:

  • UsaAnnotated + Querypara declarar reglas de validación (método recomendado)
  • Validación de cadenas:min_length、max_length、pattern
  • Sin valor predeterminado = parámetro obligatorio, con valor predeterminado = parámetro opcional
  • aliasSe usa para nombres de parámetros en la URL que no son nombres de variables válidos en Python
  • deprecated=TrueMarcar parámetros obsoletos
  • Usalist[str]para recibir múltiples parámetros de consulta con el mismo nombre
Otras extensiones