十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

FastAPI 请求体(Request Body)完全指南:基于 Pydantic 模型的 JSON 数据声明、校验与参数混用实战

FastAPI 请求体(Request Body)完全指南:基于 Pydantic 模型的 JSON 数据声明、校验与参数混用实战 FastAPI 请求体Request Body完全指南基于 Pydantic 模型的 JSON 数据声明、校验与参数混用实战【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi本文围绕 FastAPI 官方教程「Request Body」韩文翻译版位于 docs/ko/docs/tutorial/body.md展开系统讲解如何用 Pydantic 模型声明请求体、FastAPI 据此完成 JSON 读取、类型转换、数据校验、JSON Schema 生成与自动文档并覆盖请求体与路径参数、查询参数的混用规则。读完本文你将能够用类型注解的方式编写出带完整校验与自动文档的 POST/PUT 接口并结合仓库源码与测试用例理解其底层判定逻辑。请求体与响应体先厘清两个方向的数据在 HTTP API 中数据是分方向流动的请求体Request Body客户端例如浏览器或移动端发送给 API 的数据。响应体Response BodyAPI 返回给客户端的数据。绝大多数情况下API 都需要返回响应体但客户端并不总是需要发送请求体——有时它只请求某个路径最多带上几个查询参数query parameters此时不需要携带任何请求体。需要向 API 发送数据时应优先使用以下 HTTP 方法之一POST最常见PUTDELETEPATCH值得注意的是把数据放进GET请求的请求体中属于规范未定义的行为undefined behavior。虽然 FastAPI 出于极复杂/极端使用场景的考虑仍然支持它但官方明确不推荐由于这种用法被劝阻Swagger UI 之类的交互式文档在使用GET时不会展示请求体文档中间的代理服务器也可能不支持它。声明请求体的工具是Pydantic 模型——FastAPI 会调用 Pydantic 的全部能力与收益这与仓库中 fastapi/dependencies/utils.py 内部对 Pydantic 字段解析、验证的实际实现路径是呼应的。第一步导入 Pydantic 的BaseModel要声明数据模型首先从pydantic导入BaseModel。完整的示例代码位于 docs_src/body/tutorial001_py310.pyfrom fastapi import FastAPI from pydantic import BaseModel class Item(BaseModel): name: str description: str | None None price: float tax: float | None None app FastAPI()示例文件使用了 Python 3.10 的类型注解语法str | None因此在仓库对应的测试文件中通过needs_py310标记来限定 Python 版本环境见 tests/test_tutorial/test_body/test_tutorial001.py。第二步创建你的数据模型将数据模型声明为继承自BaseModel的类模型的所有属性都使用标准 Python 类型class Item(BaseModel): name: str description: str | None None price: float tax: float | None None字段是否必填的规则与声明查询参数时一致模型属性带默认值→ 该字段非必填模型属性没有默认值→ 该字段必填想让字段可选最简单的方式是把默认值设为None。例如上面的Item模型声明的就是一个 JSONobject等价于 Python 的dict形如{ name: Foo, description: An optional description, price: 45.2, tax: 3.5 }由于description和tax都是可选的默认值为None下面这个不包含它们的 JSON 同样是合法的{ name: Foo, price: 45.2 }从 OpenAPI 生成的 schema 中也能印证这一点测试快照显示Item的required列表只包含[name, price]而description与tax被声明为anyOf: [{type: string|number}, {type: null}]的可空类型详见 tests/test_tutorial/test_body/test_tutorial001.py 中test_openapi_schema的断言快照。第三步把它声明为路径操作函数的参数声明方式与之前声明路径参数、查询参数完全一样——把它放进路径操作函数的参数列表中并把参数类型标注为你刚创建的模型app.post(/items/) async def create_item(item: Item): return item只需要这一行类型声明FastAPI 在请求到达/items/时就会完成以下全部工作读取请求体中的 JSON进行必要的类型转换例如把 JSON 中的字符串数字转成模型声明的float校验数据若数据不合法会返回清晰友好的错误明确指出错误数据是什么、发生在哪里字段路径把收到的数据注入参数item因为你在函数中把参数声明为Item类型编辑器会对该对象的所有属性及其类型提供补全等支持为你的模型生成 JSON Schema 定义——只要对项目有意义这份 schema 还可以复用在任何其他地方将这些 schema 并入生成的 OpenAPI schema供自动文档用户界面UIs使用。如何在本地运行与验证使用与 FastAPI 教程一致的运行方式即可在本仓库中直接体验uvicorn docs_src.body.tutorial001_py310:app --reload启动后访问http://127.0.0.1:8000/docs查看自动生成的交互式文档或访问http://127.0.0.1:8000/openapi.json查看完整 OpenAPI schema。由于文档代码文件使用 Python 3.10 语法请确保使用 Python 3.10 及以上版本运行。自动文档模型 JSON Schema 如何进入交互式 API 文档模型的 JSON Schema 会成为生成的 OpenAPI schema 的一部分并在交互式 API 文档中展示同时凡是需要用到该模型的每个路径操作内部API 文档也会展示对应的请求体说明与 schema也就是说「定义一次 Pydantic 模型」同时为你带来了运行时校验、数据类型转换与文档三份收益这正是 FastAPI「基于 Python 类型声明自动生成一切」这一设计的典型体现。编辑器支持类型提示贯穿函数体内部由于你拿到的是一个有真实类型的 Pydantic 模型对象而不是裸dict在函数内部所有位置都能获得类型提示与自动补全同时编辑器还能对错误的类型运算给出静态检查提示。官方文档强调这绝非偶然整个框架正是围绕「让类型信息在编辑器中可用」这一设计目标构建的在设计阶段、任何实现落地之前就经过了充分测试以保障与各家编辑器兼容甚至为此推动了 Pydantic 自身的若干改动。上面截图来自 Visual Studio CodePyCharm 及大多数主流 Python 编辑器都能获得同等支持。小贴士如果使用 PyCharm可以安装 Pydantic PyCharm Plugin为 Pydantic 模型带来自动补全、类型检查、重构、搜索与检查等增强能力。在函数体内使用模型读取属性并加工数据模型对象在函数内部可以直接按属性访问也可以借助 Pydantic 的方法把模型转回字典做进一步处理。参考 docs_src/body/tutorial002_py310.pyapp.post(/items/) async def create_item(item: Item): item_dict item.model_dump() if item.tax is not None: price_with_tax item.price item.tax item_dict.update({price_with_tax: price_with_tax}) return item_dict这里使用了 Pydantic v2 的model_dump()方法把模型实例序列化为字典随后在tax存在的前提下追加计算price_with_tax字段并返回。相应的行为在 tests/test_tutorial/test_body/test_tutorial002.py 中有完整断言请求体中price传50.5字符串或50.5数字都能被正确转换为浮点数并计算出price_with_tax: 50.8不传tax时则不会出现该字段。请求体 路径参数同时声明路径参数与请求体可以在同一个路径操作函数里同时声明app.put(/items/{item_id}) async def update_item(item_id: int, item: Item): return {item_id: item_id, **item.model_dump()}完整代码见 docs_src/body/tutorial003_py310.py。FastAPI 会自动识别与路径参数匹配的函数参数 → 从路径中取值声明为Pydantic 模型类型的函数参数 → 从请求体中取值。测试 tests/test_tutorial/test_body/test_tutorial003.py 验证了PUT /items/123时item_id被解析为整数、请求体被解析为Item模型的完整链路其 OpenAPI 快照也证明item_id出现在parametersin: pathtype: integer而Item出现在requestBody中并被标记为required: true。请求体 路径参数 查询参数三管齐下请求体、路径参数与查询参数三者可以在同一函数中同时声明FastAPI 会逐一识别并把数据从正确的位置取出来。参考 docs_src/body/tutorial004_py310.pyapp.put(/items/{item_id}) async def update_item(item_id: int, item: Item, q: str | None None): result {item_id: item_id, **item.model_dump()} if q: result.update({q: q}) return result函数参数的最终判定规则如下若参数同时出现在路径中 → 作为路径参数处理若参数是单一类型如int、float、str、bool等→ 被解释为查询参数若参数声明为Pydantic 模型类型→ 被解释为请求体。对应的测试 tests/test_tutorial/test_body/test_tutorial004.py 会同时携带路径/items/123、查询串qsomequery和 JSON 请求体发起PUT请求并断言返回结果中三部分数据全部就位其 OpenAPI 快照中q以required: false出现在in: query参数列表里。关于可选性判定还有一个易被忽略的细节官方 note 特别强调FastAPI 判断q是否必填依据的是默认值 None而不是str | None这个类型注解本身。也就是说str | None并不会告诉 FastAPI「该值可选」真正起作用的是默认值 None。但保留类型注解依然有价值——它能让编辑器提供更好的支持并及早发现潜在错误。底层视角FastAPI 如何识别请求体并完成校验从源码看FastAPI 依赖在 fastapi/dependencies/utils.py 中实现的request_body_to_args()函数来执行请求体解析与字段校验的核心逻辑当路径操作函数中存在被识别为 body 的参数时请求体会被读取、按模型字段逐一提取并交给 Pydantic 校验然后把结果组装回参数中request_body_to_args()在文件约第 951 行起实现。这与本文前面总结的「读取 JSON → 类型转换 → 校验 → 注入参数」行为完全对应。仓库中针对本教程的测试用例tests/test_tutorial/test_body/test_tutorial001.py从多个角度印证了请求体校验的细节非常值得阅读price传字符串50.5会被转换并响应 200类型转换缺少必填字段price时返回422错误定位为[body, price]错误类型missingprice传twenty时返回 422错误类型float_parsing并给出「无法将字符串解析为数字」的提示请求体为损坏 JSON 时返回 422错误类型json_invalidJSON decode error携带不匹配的Content-Type如text/plain或发送表单格式form data给期望 JSON 的接口时返回 422 并提示需要合法的字典/对象输入GET /openapi.json则能拿到包含Item、ValidationError、HTTPValidationError三套组件的完整 OpenAPI schema 快照。这说明 422 校验错误的响应结构detail数组中的type、loc、msg、input、ctx等字段是有稳定格式可依赖的客户端可以据此实现友好报错提示。不依赖 Pydantic 时怎么办如果你不想使用 Pydantic 模型FastAPI 也提供了Body参数来直接声明单值请求体。这一路径的用法与多个参数共存的处理方式请参见 Body - Multiple Parameters 一文中的 Singular values in body正文中的单值一节那里会讲解当请求体里只有单个值时如何绕过模型直接声明。在动手组合更复杂的请求体场景前建议先按本教程的顺序完成模型声明、参数混用与错误处理等基础练习。【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表