Saltar al contenido

Modelos de Parámetros Header

Si tienes un grupo de parámetros header 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 Header con un Modelo Pydantic

Declara los parámetros header que necesitas en un modelo Pydantic, y luego declara el parámetro como Header:

from typing import Annotated

from fastapi import FastAPI, Header
from pydantic import BaseModel

app = FastAPI()


class CommonHeaders(BaseModel):
    host: str
    save_data: bool
    if_modified_since: str | None = None
    traceparent: str | None = None
    x_tag: list[str] = []


@app.get("/items/")
async def read_items(headers: Annotated[CommonHeaders, Header()]):
    return headers
🤓 Otras versiones y variantes

Consejo

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

from fastapi import FastAPI, Header
from pydantic import BaseModel

app = FastAPI()


class CommonHeaders(BaseModel):
    host: str
    save_data: bool
    if_modified_since: str | None = None
    traceparent: str | None = None
    x_tag: list[str] = []


@app.get("/items/")
async def read_items(headers: CommonHeaders = Header()):
    return headers

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

Revisar la Documentación

Puedes ver los headers requeridos en la interfaz de docs en /docs:

Prohibir Headers Extra

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

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

from typing import Annotated

from fastapi import FastAPI, Header
from pydantic import BaseModel

app = FastAPI()


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

    host: str
    save_data: bool
    if_modified_since: str | None = None
    traceparent: str | None = None
    x_tag: list[str] = []


@app.get("/items/")
async def read_items(headers: Annotated[CommonHeaders, Header()]):
    return headers
🤓 Otras versiones y variantes

Consejo

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

from fastapi import FastAPI, Header
from pydantic import BaseModel

app = FastAPI()


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

    host: str
    save_data: bool
    if_modified_since: str | None = None
    traceparent: str | None = None
    x_tag: list[str] = []


@app.get("/items/")
async def read_items(headers: CommonHeaders = Header()):
    return headers

Si un cliente intenta enviar algunos headers extra, recibirá una respuesta de error.

Por ejemplo, si el cliente intenta enviar un header tool con un valor de plumbus, recibirá una respuesta de error diciéndole que el parámetro header tool no está permitido:

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

Deshabilitar Conversión de Underscores

De la misma manera que con los parámetros header regulares, cuando tienes caracteres de guion bajo en los nombres de los parámetros, son automáticamente convertidos a guiones.

Por ejemplo, si tienes un parámetro header save_data en el código, el header HTTP esperado será save-data, y se mostrará así en la docs.

Si por alguna razón necesitas deshabilitar esta conversión automática, también puedes hacerlo para modelos Pydantic de parámetros header.

from typing import Annotated

from fastapi import FastAPI, Header
from pydantic import BaseModel

app = FastAPI()


class CommonHeaders(BaseModel):
    host: str
    save_data: bool
    if_modified_since: str | None = None
    traceparent: str | None = None
    x_tag: list[str] = []


@app.get("/items/")
async def read_items(
    headers: Annotated[CommonHeaders, Header(convert_underscores=False)],
):
    return headers
🤓 Otras versiones y variantes

Consejo

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

from fastapi import FastAPI, Header
from pydantic import BaseModel

app = FastAPI()


class CommonHeaders(BaseModel):
    host: str
    save_data: bool
    if_modified_since: str | None = None
    traceparent: str | None = None
    x_tag: list[str] = []


@app.get("/items/")
async def read_items(headers: CommonHeaders = Header(convert_underscores=False)):
    return headers

Aviso

Antes de establecer convert_underscores en False, ten en cuenta que algunos proxies y servidores HTTP no permiten el uso de headers con guiones bajos.

Resumen

Puedes usar modelos Pydantic para declarar headers en FastAPI. 😎