跳转至

Cookie 参数模型

如果你有一组相关的 cookies,可以创建一个 Pydantic 模型 来声明它们。🍪

这将允许你在 多个地方 复用该模型,并一次性为所有参数声明验证规则和元数据。😎

Note

该功能自 FastAPI 版本 0.115.0 起支持。🤓

Tip

同样的技术适用于 QueryCookieHeader。😎

使用 Pydantic 模型声明 Cookies

在一个 Pydantic 模型 中声明你需要的 cookie 参数,然后将参数声明为 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 会从请求接收到的 cookies 中为 每个字段 提取 数据,并返回你定义的 Pydantic 模型。

查看文档

你可以在 /docs 的文档界面中查看已定义的 cookies:

Info

请注意,由于 浏览器处理 cookies 的方式特殊且是在后台进行的,它们 容易允许 JavaScript 操作 cookies。

如果你访问 /docsAPI 文档界面,你将能够看到你的 路径操作 的 cookies 文档

但即使你 填写了数据 并点击“执行”,由于文档界面使用 JavaScript 工作,cookies 不会被发送,你将看到一条 错误 消息,就像你没有填写任何值一样。

禁止额外的 Cookies

在某些特殊用例中(可能不太常见),你可能希望 限制 你想要接收的 cookies。

你的 API 现在有能力控制自己的 cookie 同意 了。🤪🍪

你可以使用 Pydantic 的模型配置来 forbid(禁止)任何 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

如果客户端尝试发送一些 额外的 cookies,他们将收到一个 错误 响应。

可怜的 cookie 横幅费尽心思获取你的同意,结果 API 却拒绝了它。🍪

例如,如果客户端尝试发送一个值为 good-list-pleasesanta_tracker cookie,客户端将收到一个 错误 响应,告知他们 santa_tracker cookie 不被允许

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

总结

你可以使用 Pydantic 模型FastAPI 中声明 cookies。😎