ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

FastAPI Cookie 参数详解:用 Cookie 声明、验证与读取 HTTP Cookie

FastAPI Cookie 参数详解:用 Cookie 声明、验证与读取 HTTP Cookie FastAPI Cookie 参数详解用 Cookie 声明、验证与读取 HTTP Cookie【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi本文基于 FastAPI 官方教程文档 cookie-params德语版对应英文版为 docs/en/docs/tutorial/cookie-params.md展开。FastAPI 允许像声明Query、Path参数一样声明 Cookie 参数只需从fastapi导入Cookie用相同的方式设置默认值、附加验证与标注参数即可从请求 Cookie 中按名称提取并自动完成类型转换与校验。读完本文你将掌握 Cookie 参数的声明写法、Cookie在框架中的类层级关系以及为什么必须显式使用Cookie才能避免参数被误判为 Query 参数并理解 Cookie 值在依赖解析阶段的底层提取流程。1. 导入Cookie使用 Cookie 参数前第一步是从fastapi中导入Cookie。官方示例文件 docs_src/cookie_params/tutorial001_an_py310.py 的完整代码如下from typing import Annotated from fastapi import Cookie, FastAPI app FastAPI() app.get(/items/) async def read_items(ads_id: Annotated[str | None, Cookie()] None): return {ads_id: ads_id}其中关键的第 3 行from fastapi import Cookie, FastAPI即文档强调的导入步骤。Cookie与Query、Path一样是 FastAPI 顶层命名空间直接暴露的 API。2. 声明 Cookie 参数声明 Cookie 参数使用与Path、Query完全相同的结构你可以为参数定义默认值以及所有的额外验证或标注参数。2.1 现代推荐写法Annotated风格app.get(/items/) async def read_items(ads_id: Annotated[str | None, Cookie()] None): return {ads_id: ads_id}逐行解读Annotated[str | None, Cookie()]第一个元素str | None声明参数类型——字符串或None第二个元素Cookie()把该参数从默认的Query 参数语义转换为从 Cookie 中提取。 None指定默认值。当请求中没有名为ads_id的 Cookie 时参数值为None。由于参数类型包含None该 Cookie 是可选的如果你声明为Annotated[str, Cookie()]不可为空FastAPI 会在缺少该 Cookie 时返回验证错误。2.2 传统写法旧风格仓库中同时提供了旧风格示例 docs_src/cookie_params/tutorial001_py310.pyfrom fastapi import Cookie, FastAPI app FastAPI() app.get(/items/) async def read_items(ads_id: str | None Cookie(defaultNone)): return {ads_id: ads_id}这里Cookie(defaultNone)把Cookie当作一个参数工厂直接用作默认值。两种写法最终生成同样的路由行为官方文档与当前示例主推Annotated风格。2.3 可附带的验证与标注参数Cookie与Query、Path共用同一套参数选项因此声明 Cookie 时同样可以使用元数据title、description、deprecated、examples/openapi_examples、include_in_schema等影响/docs中生成的 OpenAPI 文档验证约束gt、ge、lt、le数值比较、min_length、max_length、pattern字符串正则、strict、multiple_of、allow_inf_nan等别名alias、validation_alias、serialization_alias用于 Cookie 名称与 Python 变量名不一致例如 Cookie 名与 Python 保留字冲突的场景。这些选项的完整签名可以在 fastapi/params.py 的Param基类与各参数类构造器中查证。3. 技术细节Cookie是Path与Query的姐妹类官方文档特别指出Cookie是Path和Query的一个姐妹sister类。它也继承自同一个共同的Param类。但请记住当你从fastapi导入Query、Path、Cookie等对象时它们实际上是函数会返回特殊的类。仓库源码完整印证了这两句话共同的Param基类。在 fastapi/params.py 中class Cookie(Param): # type: ignore[misc] in_ ParamTypes.cookieCookie直接继承Param并仅通过类属性in_ ParamTypes.cookie声明自己的取值来源是 Cookie。这正是它与Queryin_ ParamTypes.query、Pathin_ ParamTypes.path成为姐妹类的机制——同一个基类、同一套验证参数仅取值位置不同。顶层名字是返回类的函数。在 fastapi/param_functions.py 中Cookie被定义为一个带大量Doc文档标注的函数第 1018 行def Cookie(...)与同文件的Path第 13 行、Query第 357 行结构一致从源码结构看这些函数接收default、alias、title、description、各类验证约束等参数并转发给params模块中对应的真实类例如Path函数返回params.Path实例Query函数返回params.Query实例Cookie同理返回params.Cookie实例。这种函数 类双层设计让 FastAPI 既能在Annotated中作为标注使用又能在旧风格中作为默认值使用同时把参数文档与 OpenAPI 生成所需信息集中维护在param_functions.py中。4. 为什么必须用Cookie显式声明文档给出了一条关键提示要声明 Cookie你必须使用Cookie否则这些参数会被解释为 Query 参数。这一点在依赖解析源码中有直接证据。fastapi/dependencies/utils.py 在处理非 Body 参数时会根据Param实例的in_归属把字段分派到不同的参数列表并做了严格断言assert field_info_in params.ParamTypes.cookie, ( fnon-body parameters must be in path, query, header or cookie: {field.name} ) dependant.cookie_params.append(field)也就是说没有标注任何Param的简单类型参数如裸的ads_id: str会被归类为Query 参数框架会去 URL 查询串里找?ads_id...而不是读 Cookie只有标注了Cookie其in_为ParamTypes.cookie的参数才会进入dependant.cookie_params列表后续才从request.cookies中提取。这正是文档强调必须显式使用Cookie的底层原因。5. 注意浏览器 Cookie 的特殊性与/docs界面限制文档还提醒了一个容易被忽略的行为限制请记住浏览器以特殊方式、在幕后处理 Cookie并且不允许JavaScript随意地直接访问/修改它们。当你访问/docs的API 文档界面时可以看到路径操作中 Cookie 的文档但即使你填写了数据并点击Execute由于文档界面是基于JavaScript运行的Cookie 并不会被发送你会看到一条错误信息仿佛你没有填写任何值。也就是说/docsSwagger UI能正确展示 Cookie 参数的 OpenAPI 定义参数位于cookie位置但 Swagger UI 通过浏览器fetch发请求时无法可靠地注入自定义 Cookie点击 Execute 后服务端读不到该 Cookie若参数必填则返回 422 验证错误看起来就像没有填值。这是浏览器 Cookie 机制而非 FastAPI造成的限制。实际测试 Cookie 参数时建议使用curl、Postman 等可直接控制Cookie请求头的工具或框架自带的TestClient见下一节。6. 底层原理Cookie 值是如何被提取的结合 fastapi/dependencies/utils.py完整解析流程可以概括为收集阶段路由参数被解析后所有in_为cookie的字段被归入dependant.cookie_params同文件第 173 行初始化cookie_params: list[ModelField]并在第 189-195 行完成依赖树的扁平化收集。提取阶段在生成请求参数值时框架调用cookie_values, cookie_errors request_params_to_args( dependant.cookie_params, request.cookies ) values.update(cookie_values) errors path_errors query_errors header_errors cookie_errors即把 ASGI/Starlette 解析好的request.cookies字典键为 Cookie 名值为字符串交给request_params_to_args按字段定义完成取值、类型转换与验证任何验证失败都会汇入errors最终触发 422 响应。类型转换Cookie 值本质都是字符串FastAPI 依据你声明的类型如str、int自动转换转换或验证失败时与 Query/Path 参数一样返回统一的验证错误结构。从源码结构看Cookie 参数的处理路径与 Query/Header 参数共用同一套request_params_to_args工具函数只是数据源不同Query 来自request.query_paramsCookie 来自request.cookies这也解释了为什么Cookie能完整复用Query的全部验证与元数据参数。7. 测试验证官方为该教程配置了对应的测试 tests/test_tutorial/test_cookie_params/test_tutorial001.py其参数化用例覆盖了三种典型场景请求携带{ads_id: ads_track, session: cookiesession}两个 Cookie 访问/items期望返回200且响应为{ads_id: ads_track}请求只携带{session: cookiesession}无ads_id访问/items由于参数有默认值None期望返回200且响应为{ads_id: None}测试同时断言生成的 OpenAPI 中该参数的位置为in: cookie验证文档元数据正确。测试通过TestClient(mod.app, cookiescookies)以字典形式注入 Cookie这也是本地验证 Cookie 参数最直接的方式。8. 小结声明 Cookie 使用Cookie模式与Query、Path完全一致Annotated[str | None, Cookie()] None或旧风格ads_id: str | None Cookie(defaultNone)Cookie在 fastapi/params.py 中继承共同的Param基类仅以in_ ParamTypes.cookie标识取值来源而从fastapi导入的Query/Path/Cookie等名字实际是 fastapi/param_functions.py 中返回特殊类实例的函数必须显式标注Cookie否则参数会被当作 Query 参数处理见 fastapi/dependencies/utils.py 的分派与断言逻辑运行时 Cookie 值从request.cookies提取并经request_params_to_args完成验证见 fastapi/dependencies/utils.py浏览器 JavaScript 无法随意操纵 Cookie因此/docs界面中点击 Execute 不会真正发送 Cookie集成测试请改用TestClient或外部 HTTP 客户端。【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表