ARTICLE DETAIL

资讯详情

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

FastAPI 请求示例数据声明实战:examples 与 openapi_examples 完整指南

FastAPI 请求示例数据声明实战:examples 与 openapi_examples 完整指南 FastAPI 请求示例数据声明实战examples 与 openapi_examples 完整指南【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi本篇指南基于 FastAPI 官方文档「Declaring Request Example Data」系统讲解如何为 API 请求数据声明示例examples包括在 Pydantic 模型中通过model_config/json_schema_extra注入示例、在Field()上声明字段级示例、在Path()/Query()/Body()等参数上声明examples以及使用 OpenAPI 专属的openapi_examples参数让 Swagger UI 真正显示多个示例的完整方法。读完你将掌握在/docs界面中为参数和请求体提供可读示例的全部技术手段并理解examples与example在 OpenAPI 3.1.0 演进中的区别与迁移建议。为 Pydantic 模型添加额外的 JSON Schema 数据你可以为应用可能接收的数据声明示例。FastAPI 提供了几种方式第一种是直接在 Pydantic 模型中声明examples“示例”它们会被附加到生成的 JSON Schema 中from fastapi import FastAPI from pydantic import BaseModel app FastAPI() class Item(BaseModel): name: str description: str | None None price: float tax: float | None None model_config { json_schema_extra: { examples: [ { name: Foo, description: A very nice Item, price: 35.4, tax: 3.2, } ] } } app.put(/items/{item_id}) async def update_item(item_id: int, item: Item): results {item_id: item_id, item: item} return results完整示例见 tutorial001_py310.py。这些额外信息会被原样附加到该模型输出的JSON Schema中并在 API 文档中使用。实现上你可以使用 Pydantic 的model_config属性它接受一个dict来设置json_schema_extra其中包含希望在生成的 JSON Schema 中显示的所有额外数据包括examples。提示用同样的技巧你还可以扩展 JSON Schema 并加入任意自定义的附加信息。例如你可以借此为前端界面添加元数据等。注意OpenAPI 3.1.0FastAPI 0.99.0 起采用新增了examples支持它是JSON Schema标准的一部分。此前 OpenAPI 只支持单个示例的关键字example。它虽仍被 OpenAPI 3.1.0 支持但已被弃用deprecated且不属于 JSON Schema 标准。因此建议从example迁移到examples。从源码可以看到FastAPI 的Param基类对example参数标记了弃用警告见 fastapi/params.py传入example会触发FastAPIDeprecationWarning而examples: list[Any] | None None与openapi_examples: dict[str, Example] | None None是两个并列的正式参数见 fastapi/params.py。测试 tests/test_schema_extra_examples.py 中就用pytest.warns(FastAPIDeprecationWarning)验证了Body(example...)的弃用行为。在Field()上声明examples如果在使用 Pydantic 模型时采用了Field()同样可以声明额外的examples粒度细化到每个字段from fastapi import FastAPI from pydantic import BaseModel, Field app FastAPI() class Item(BaseModel): name: str Field(examples[Foo]) description: str | None Field(defaultNone, examples[A very nice Item]) price: float Field(examples[35.4]) tax: float | None Field(defaultNone, examples[3.2]) app.put(/items/{item_id}) async def update_item(item_id: int, item: Item): results {item_id: item_id, item: item} return results完整示例见 tutorial002_py310.py。在 fastapi/params.py 中可以确认这一机制Field()类同样继承自Param体系在examples is not None时会把kwargs[examples] examples传入 Pydantic 字段定义最终由 Pydantic 将其写入该字段的 JSON Schema。在Path()、Query()、Body()等参数上使用examples使用以下参数函数时你也可以声明一组examples作为额外信息附加到它们位于OpenAPI内部的JSON Schema中Path()Query()Header()Cookie()Body()Form()File()Body携带单个examples下面通过Annotated向Body()传入examples其中包含一个Body()所期望数据的示例from typing import Annotated from fastapi import Body, FastAPI from pydantic import BaseModel app FastAPI() class Item(BaseModel): name: str description: str | None None price: float tax: float | None None app.put(/items/{item_id}) async def update_item( item_id: int, item: Annotated[ Item, Body( examples[ { name: Foo, description: A very nice Item, price: 35.4, tax: 3.2, } ], ), ], ): results {item_id: item_id, item: item} return results完整示例见 tutorial003_an_py310.py。示例在文档界面中的呈现使用以上任一方法后/docs界面中的请求体区域会呈现如下效果Body携带多个examples当然也可以传入多个examplesitem: Annotated[ Item, Body( examples[ { name: Foo, description: A very nice Item, price: 35.4, tax: 3.2, }, { name: Bar, price: 35.4, }, { name: Baz, price: thirty five point four, }, ], ), ],完整示例见 tutorial004_an_py310.py。这样做时这些示例会成为这些 Body 数据内部JSON Schema的一部分。不过负责展示文档界面的工具 Swagger UI截至撰写时并不支持展示JSON Schema中数据的多个示例。但请继续往下阅读以了解变通方案。OpenAPI 专属的openapi_examples参数早在JSON Schema支持examples之前OpenAPI 就支持另一个同样叫examples的字段。这些OpenAPI 专属的examples位于 OpenAPI 规范的另一部分——它们是每个*路径操作Path Operation*的细节而非每个 JSON Schema 的组成部分。Swagger UI 很早就支持了这个特殊的examples字段因此你可以用它来在文档界面中显示不同的示例。这个 OpenAPI 专属字段examples的格式是一个dict包含多个示例而非list每个示例都带有额外信息同样会被附加到OpenAPI中。它不在 OpenAPI 中的每个 JSON Schema 内部而在路径操作声明之外。使用openapi_examples参数你可以用openapi_examples参数在 FastAPI 中声明 OpenAPI 专属的examples适用于Path()Query()Header()Cookie()Body()Form()File()该dict的键用于标识每个示例每个值又是一个dict。examples中每个具体的示例dict可以包含summary对示例的简短描述。description长描述可包含 Markdown 文本。value这是实际展示的示例例如一个dict。externalValuevalue的替代项一个指向示例的 URL。不过它可能不像value那样被众多工具广泛支持。使用示例from typing import Annotated from fastapi import Body, FastAPI from pydantic import BaseModel app FastAPI() class Item(BaseModel): name: str description: str | None None price: float tax: float | None None app.put(/items/{item_id}) async def update_item( *, item_id: int, item: Annotated[ Item, Body( openapi_examples{ normal: { summary: A normal example, description: A **normal** item works correctly., value: { name: Foo, description: A very nice Item, price: 35.4, tax: 3.2, }, }, converted: { summary: An example with converted data, description: FastAPI can convert price strings to actual numbers automatically, value: { name: Bar, price: 35.4, }, }, invalid: { summary: Invalid data is rejected with an error, value: { name: Baz, price: thirty five point four, }, }, }, ), ], ): results {item_id: item_id, item: item} return results完整示例见 tutorial005_an_py310.py。源码层面的生成逻辑从源码看openapi_examples的类型是dict[str, Example]其中Example是 OpenAPI 规范中 Example Object 的TypedDict定义见 fastapi/openapi/models.py。在生成 OpenAPI 文档时对于Path()/Query()/Header()/Cookie()等参数fastapi/openapi/utils.py 中会读取field_info.openapi_examples若存在则写入参数对象的parameter[examples]否则回退到已弃用的example字段对于Body()/Form()/File()等请求体fastapi/openapi/utils.py 中的get_openapi_operation_request_body()会把openapi_examples写入content的Media Type Object内的examples键。这正对应 OpenAPI 规范中Parameter Object和Media Type Object各自支持的examples字段。openapi_examples在文档界面中的呈现当openapi_examples添加到Body()时/docs界面会显示可切换的多个示例技术细节examples 与 OpenAPI/JSON Schema 的历史演进提示如果你正在使用FastAPI0.99.0或更高版本可以跳过这些细节。它们对更早的版本OpenAPI 3.1.0 出现之前更有意义可以作为一堂 OpenAPI 与 JSON Schema 的历史课来看。OpenAPI 3.1.0 之前OpenAPI 使用的是较旧且经过改动的JSON Schema版本。JSON Schema 本身没有examples因此 OpenAPI 在自己的修改版中加入了自有的example字段。OpenAPI 还将example与examples字段加入规范的其他部分Parameter Object被 FastAPI 的Path()、Query()、Header()、Cookie()使用Request Body Object 的content字段中的 Media Type Object被 FastAPI 的Body()、File()、Form()使用。注意这个旧的、OpenAPI 专属的examples参数自 FastAPI0.103.0起被更名为openapi_examples。JSON Schema 的examples字段后来JSON Schema 在新版规范中加入了examples字段。而新的 OpenAPI 3.1.0 正是基于最新版 JSON Schema2020-12其中包含这个新的examples字段。于是这个新的examples字段优先于旧的自定义的单数形式example字段——后者如今已弃用。JSON Schema 中这个新的examples字段只是一个list不像 OpenAPI 其他位置上文所述那样是带额外元数据的 Dict。注意即使 OpenAPI 3.1.0 发布后采用了与 JSON Schema 的新式简单集成Swagger UI 一段时间内仍不支持 OpenAPI 3.1.0直到其 5.0.0 版本才开始支持。正因如此FastAPI 0.99.0 之前的版本一直使用 3.1.0 之前的 OpenAPI 版本。Pydantic 与 FastAPI 的examples行为差异在 FastAPI 0.99.0 之前如果在 Pydantic 模型中通过schema_extra或Field(examples[something])添加examples示例会被添加到该 Pydantic 模型的JSON Schema中而这个JSON Schema又包含在 API 的OpenAPI中进而被文档界面使用。但在同一时期如果对Query()、Body()等其他工具使用example或examples这些示例不会被添加到描述该数据的 JSON Schema 中甚至不是 OpenAPI 自有版本的 JSON Schema而是被直接添加到 OpenAPI 中的路径操作声明里位于 OpenAPI 不使用 JSON Schema 的部分。如今由于 FastAPI 0.99.0 及以上使用 OpenAPI 3.1.0基于 JSON Schema 2020-12与 Swagger UI 5.0.0 及以上一切都更加一致示例统一落在 JSON Schema 中。Swagger UI 与 OpenAPI 专属examples的关系由于 Swagger UI 目前截至 2023-08-26不支持多个 JSON Schema 示例用户原本无法在文档中显示多个示例。为解决这一问题FastAPI0.103.0增加了对同一旧的OpenAPI 专属examples字段的声明支持使用新参数openapi_examples。这也是当前在文档 UI 中展示多个带summary/description示例的推荐手段。小结模型级示例在 Pydantic 模型的model_config[json_schema_extra][examples]中声明直接写入模型的 JSON Schema适用于整个请求体的示例数据字段级示例在Field(examples[...])中声明粒度到单个字段参数级 JSON Schema 示例在Path()/Query()/Header()/Cookie()/Body()/Form()/File()的examples[...]中声明同样落入 JSON Schema文档 UI 多示例展示使用openapi_examples{...}FastAPI 0.103.0它是 OpenAPI 专属字段Swagger UI 原生支持切换显示每个示例支持summary、description、value、externalValue。一句话总结升级到 FastAPI 0.99.0 及以上版本一切都会更简单、一致、直观无需了解上述历史细节而要在文档界面看到带描述、可切换的多个示例使用openapi_examples即可。相关示例代码位于 docs_src/schema_extra_example/行为验证可参考 tests/test_schema_extra_examples.py。【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表