Saltar a contenido

Modelos de Cookies

Si tienes un grupo de cookies que están relacionadas, puedes crear un modelo de Pydantic para declararlas. 🍪

Esto te permitirá 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 compatible desde la versión 0.115.0 de FastAPI. 🤓

Consejo

Esta misma técnica se aplica a Query, Cookie, y Header. 😎

Cookies con un Modelo de Pydantic

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

from typing import Annotated

from fastapi import Cookie, FastAPI
from pydantic import BaseModel

app = FastAPI()


class Cookies(BaseModel):
    session_id: str
    fatebook_tracker: str | None = None
    googall_tracker: str | None = None


@app.get("/items/")
async def read_items(cookies: Annotated[Cookies, Cookie()]):
    return cookies
🤓 Other versions and variants
from typing import Annotated, Union

from fastapi import Cookie, FastAPI
from pydantic import BaseModel

app = FastAPI()


class Cookies(BaseModel):
    session_id: str
    fatebook_tracker: Union[str, None] = None
    googall_tracker: Union[str, None] = None


@app.get("/items/")
async def read_items(cookies: Annotated[Cookies, Cookie()]):
    return cookies
from typing import Union

from fastapi import Cookie, FastAPI
from pydantic import BaseModel
from typing_extensions import Annotated

app = FastAPI()


class Cookies(BaseModel):
    session_id: str
    fatebook_tracker: Union[str, None] = None
    googall_tracker: Union[str, None] = None


@app.get("/items/")
async def read_items(cookies: Annotated[Cookies, Cookie()]):
    return cookies

Tip

Prefer to use the Annotated version if possible.

from fastapi import Cookie, FastAPI
from pydantic import BaseModel

app = FastAPI()


class Cookies(BaseModel):
    session_id: str
    fatebook_tracker: str | None = None
    googall_tracker: str | None = None


@app.get("/items/")
async def read_items(cookies: Cookies = Cookie()):
    return cookies

Tip

Prefer to use the Annotated version if possible.

from typing import Union

from fastapi import Cookie, FastAPI
from pydantic import BaseModel

app = FastAPI()


class Cookies(BaseModel):
    session_id: str
    fatebook_tracker: Union[str, None] = None
    googall_tracker: Union[str, None] = None


@app.get("/items/")
async def read_items(cookies: Cookies = Cookie()):
    return cookies

FastAPI extraerá los datos para cada campo de las cookies recibidas en el request y te entregará el modelo de Pydantic que definiste.

Revisa la Documentación

Puedes ver las cookies definidas en la UI de la documentación en /docs:

Información

Ten en cuenta que, como los navegadores manejan las cookies de maneras especiales y detrás de escenas, no permiten fácilmente que JavaScript las toque.

Si vas a la UI de la documentación de la API en /docs podrás ver la documentación de las cookies para tus path operations.

Pero incluso si rellenas los datos y haces clic en "Execute", como la UI de la documentación funciona con JavaScript, las cookies no serán enviadas y verás un mensaje de error como si no hubieras escrito ningún valor.

Prohibir Cookies Extra

En algunos casos de uso especiales (probablemente no muy comunes), podrías querer restringir las cookies que deseas recibir.

Tu API ahora tiene el poder de controlar su propio consentimiento de cookies. 🤪🍪

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

from typing import Annotated, Union

from fastapi import Cookie, FastAPI
from pydantic import BaseModel

app = FastAPI()


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

    session_id: str
    fatebook_tracker: Union[str, None] = None
    googall_tracker: Union[str, None] = None


@app.get("/items/")
async def read_items(cookies: Annotated[Cookies, Cookie()]):
    return cookies
🤓 Other versions and variants
from typing import Annotated

from fastapi import Cookie, FastAPI
from pydantic import BaseModel

app = FastAPI()


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

    session_id: str
    fatebook_tracker: str | None = None
    googall_tracker: str | None = None


@app.get("/items/")
async def read_items(cookies: Annotated[Cookies, Cookie()]):
    return cookies
from typing import Union

from fastapi import Cookie, FastAPI
from pydantic import BaseModel
from typing_extensions import Annotated

app = FastAPI()


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

    session_id: str
    fatebook_tracker: Union[str, None] = None
    googall_tracker: Union[str, None] = None


@app.get("/items/")
async def read_items(cookies: Annotated[Cookies, Cookie()]):
    return cookies

Tip

Prefer to use the Annotated version if possible.

from fastapi import Cookie, FastAPI
from pydantic import BaseModel

app = FastAPI()


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

    session_id: str
    fatebook_tracker: str | None = None
    googall_tracker: str | None = None


@app.get("/items/")
async def read_items(cookies: Cookies = Cookie()):
    return cookies

Tip

Prefer to use the Annotated version if possible.

from typing import Union

from fastapi import Cookie, FastAPI
from pydantic import BaseModel

app = FastAPI()


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

    session_id: str
    fatebook_tracker: Union[str, None] = None
    googall_tracker: Union[str, None] = None


@app.get("/items/")
async def read_items(cookies: Cookies = Cookie()):
    return cookies

Si un cliente intenta enviar algunas cookies extra, recibirán un response de error.

Pobres banners de cookies con todo su esfuerzo para obtener tu consentimiento para que la API lo rechace. 🍪

Por ejemplo, si el cliente intenta enviar una cookie santa_tracker con un valor de good-list-please, el cliente recibirá un response de error que le informa que la cookie santa_tracker no está permitida:

{
    "detail": [
        {
            "type": "extra_forbidden",
            "loc": ["cookie", "santa_tracker"],
            "msg": "Extra inputs are not permitted",
            "input": "good-list-please",
        }
    ]
}

Resumen

Puedes usar modelos de Pydantic para declarar cookies en FastAPI. 😎