资讯详情

资讯详情

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一章讲解如何用 Pydantic 的BaseModel把客户端发来的 JSON 数据声明为带类型的路径操作函数参数。读完你将掌握如何定义数据模型、如何让 FastAPI 自动完成 JSON 解析、类型转换、数据校验、编辑器补全与 OpenAPI 文档生成以及请求体与路径参数、查询参数三者同屏共存时的参数判定规则。什么是请求体与响应体在 Web API 语境中一次完整的数据交换包含两个方向的数据请求体Request Body客户端例如浏览器或另一个服务发送给 API 的数据响应体Response BodyAPI 返回给客户端的数据。绝大多数 API 都会发送响应体但客户端并非每次都必须发送请求体。例如按路径 查询参数请求资源时往往不需要携带任何请求体。在 FastAPI 中声明请求体的推荐方式是使用 Pydantic日文版见 docs/ja/docs/tutorial/body.md对应的全部可运行示例代码集中在 docs_src/body 目录。发送请求体应选用哪种 HTTP 方法需要向服务器提交数据时应当优先使用下列方法之一POST最常见PUTDELETEPATCH。关于GET请求携带请求体原文档明确指出这在 HTTP 规范中属于未定义行为FastAPI 出于兼容性仍然支持但仅适用于非常复杂/极端的用例不推荐在日常开发中使用。其后果包括Swagger UI 的交互式文档中不会为GET显示请求体沿途的代理服务器也可能不支持这种写法。第一步从 Pydantic 导入 BaseModel在任意路径操作文件顶部导入BaseModel对应示例 docs_src/body/tutorial001_py310.pyfrom fastapi import FastAPI from pydantic import BaseModel第二步定义数据模型接着声明一个继承BaseModel的类作为数据模型属性使用标准 Python 类型标注示例第 59 行class Item(BaseModel): name: str description: str | None None price: float tax: float | None None这里已经体现了“字段可选性”的规则与查询参数的声明方式一致带默认值的属性是可选的不带默认值的属性是必填的。想要一个字段可选只需把默认值设为None即可。以上面的模型为例下面这个 JSONobject等价于 Python 的dict是合法输入{ name: Foo, description: An optional description, price: 45.2, tax: 3.5 }由于description与tax是可选的省略它们得到None也完全合法{ name: Foo, price: 45.2 }第三步把模型声明为路径操作函数的参数定义好模型后像声明路径参数、查询参数那样在路径操作函数中把参数类型标注为Item即可示例第 16 行from fastapi import FastAPI from pydantic import BaseModel class Item(BaseModel): name: str description: str | None None price: float tax: float | None None app FastAPI() app.post(/items/) async def create_item(item: Item): return item完整代码见 docs_src/body/tutorial001_py310.py。仅凭类型声明FastAPI 自动完成了什么把item: Item写入函数签名之后FastAPI 会在运行时替你完成全部繁琐工作将请求体内容读取为 JSON在必要时做类型转换例如把 JSON 中的字符串50.5转换为float执行数据校验——数据非法时返回清晰、友好的错误明确指出哪个字段、什么内容非法把收到的数据以参数item传入函数——由于已标注为Item类型函数内所有属性和类型都能得到编辑器的补全与检查支持为模型生成 JSON Schema 定义可按需复用到项目的其他位置这些 Schema 会成为最终 OpenAPI Schema 的一部分供自动生成的交互式文档UIs使用。校验失败的真实行为可由仓库测试佐证。在 tests/test_tutorial/test_body/test_tutorial001.py 中仅提交{name: Foo}缺少必填字段price时接口返回 HTTP 422错误体精确指出loc: [body, price]与msg: Field required同一文件 L88-L100 则验证了把price传成字符串twenty会得到type: float_parsing的解析错误。仓库对这条链路的回归测试覆盖非常完整包括空对象、jsonNone、坏 JSON、非 JSON 的Content-Type等各类边界情况。底层原理FastAPI 如何区分 body / query / path 参数“自动完成”背后的判定逻辑集中在 fastapi/dependencies/utils.py 的analyze_param见 fastapi/dependencies/utils.py。当参数既没有显式Annotated/FieldInfo、也没有Depends时源码会按顺序判断第 491505 行参数名出现在路径模板中 → 按路径参数处理params.Path类型是UploadFile/ 可空UploadFile或文件序列 → 按文件处理params.File类型不是标量例如 Pydantic 模型→ 按请求体处理params.Body其余标量类型int、float、str、bool等→ 按查询参数处理params.Query。也就是说请求体的识别本质上是“非标量类型即按 Body 处理”这条默认规则的结果与你声明的模型复杂程度无关。这也是本文后续“请求体 路径参数 查询参数”能混用同一声明的原因。自动生成的 API 文档数据模型派生出的 JSON Schema 会自动进入 OpenAPI 生成的整体 Schema并显示在交互式 API 文档的请求体区域同时每个需要请求体的path operation各自的接口文档中也会包含这份 Schema这与仓库中的 OpenAPI 快照测试一致例如 tests/test_tutorial/test_body/test_tutorial001.py 断言/openapi.json中该接口的requestBody.required为True其 schema 为$ref指向#/components/schemas/Item而Item组件里required恰好是[name, price]description与tax则被生成为anyOf: [type, null]的可空类型。编辑器支持类型补全与错误检查把函数参数标注为 Pydantic 模型后编辑器会在函数体内任意位置给出属性补全与类型提示——如果改用裸dict接收参数就享受不到这些能力针对非法类型操作例如把item.price当作字符串调用字符串方法编辑器同样能给出错误提示需要说明的是这并非巧合整个 FastAPI 框架的设计都以“类型声明即契约”为核心并且在实现前经过大量测试以保障跨编辑器的可用性为此 Pydantic 本身也做过相应改动。前述截图基于 Visual Studio Code 拍摄PyCharm 以及绝大多数主流 Python 编辑器都能获得同等体验PyCharm 用户还可借助 Pydantic 插件进一步增强补全、类型检查、重构、搜索与 inspections。在函数内使用模型对象请求体解析完成后你在函数内可以直接访问模型实例的各个属性。例如下面的示例docs_src/body/tutorial002_py310.py用item.model_dump()把模型转回字典并基于tax是否为空动态追加“含税总价”字段from fastapi import FastAPI from pydantic import BaseModel class Item(BaseModel): name: str description: str | None None price: float tax: float | None None app FastAPI() app.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注意model_dump()是 Pydantic v2 提供的方法对应早期版本的dict()。在 pydantic v2 兼容层方面仓库通过 fastapi/_compat 做了一致性封装业务代码中直接使用即可。请求体 路径参数同时声明路径参数与请求体可以共存。FastAPI 会识别出与路径模板匹配的参数从路径中取声明为 Pydantic 模型的参数从请求体取。示例 docs_src/body/tutorial003_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() app.put(/items/{item_id}) async def update_item(item_id: int, item: Item): return {item_id: item_id, **item.model_dump()}这里PUT /items/123表示“把123号商品更新为请求体中的Item数据”。对应的 OpenAPI 快照测试见 tests/test_tutorial/test_body/test_tutorial003.pyitem_id被生成为required: True的路径参数in: path而Item仍然作为requestBody引用。请求体 路径参数 查询参数三者混用三种来源的参数可以同时出现在一个函数签名里FastAPI 会各自识别并取用正确位置的数据docs_src/body/tutorial004_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() app.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例如请求PUT /items/123?qsomequery携带请求体{name: Foo, price: 50.1}响应将是{item_id: 123, name: Foo, price: 50.1, description: null, tax: null, q: somequery}——该行为由 tests/test_tutorial/test_body/test_tutorial004.py 中的test_put_all断言覆盖。函数参数的判定规则总结若参数同时出现在路径中则作为路径参数若参数是单值标量类型int、float、str、bool等则作为查询参数若参数声明为Pydantic 模型类型则作为请求体。可选性判定默认值与类型标注的区别原文档特别强调了一个易混淆点上例中q: str | None None之所以是可选的不是因为str | None这种可空类型标注而是因为默认值 None。FastAPI 依据默认值是否存在来判断字段是否必填str | None本身并不参与这一判定。不过加上类型标注能让编辑器提供更好的支持、帮助提前发现错误。如果你在.py文件中以函数而非类的方式复用这一段逻辑会看到它与框架在 fastapi/dependencies/utils.py 的实现相互印证默认值为空RequiredParam才会生成必填字段。不想用 Pydantic 怎么办Body 参数如果你不希望使用 Pydantic 模型FastAPI 仍允许你直接把参数声明为Body类型以获取更底层的控制。相关内容属于“请求体中包含多个参数与单一值”的进阶话题请参阅《Body - 多个参数请求体中的单一值》一文日文原文档的对应链接见 docs/ja/docs/tutorial/body-multiple-params.md。如何运行与验证示例将上面的任一示例保存为main.py然后在项目环境内启动开发服务器fastapi dev main.py浏览器访问http://127.0.0.1:8000/docs即可看到自动生成的 Swagger UI含请求体示例与“Try it out”按钮访问http://127.0.0.1:8000/openapi.json可查看完整 OpenAPI 结构。仓库为本章维护了完整的回归测试套件位于 tests/test_tutorial/test_body逐一覆盖 tutorial001tutorial004 的正常请求、缺失字段、类型错误、坏 JSON、非 JSON Content-Type 以及 OpenAPI 快照可作为理解与验证本指南全部结论的第一手依据。小结请求体是绝大多数写操作接口的核心输入通道。在 FastAPI 中你只需要用BaseModel定义带类型与默认值的数据模型 → 把模型类型直接标注在路径操作函数参数上 → 剩余的解码、转换、校验、文档与编辑器支持全部交给框架。当你需要同时接收路径参数、查询参数与请求体时记住三条判定规则路径 标量即查询 模型即请求体并始终用默认值 None而非类型标注来表达“可选”即可写出既类型安全又行为可预期的 API。【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →