FastAPI(15)- 声明请求示例数据

2021-09-27 15:48:22 浏览数 (1)

前言

  • FastAPI 可以给 Pydantic Model 或者路径函数声明需要接收的请求示例,而且可以显示在 OpenAPI 文档上
  • 有几种方式,接下来会详细介绍

Pydantic 的 schema_extra

可以使用 Config cass 和 schema_extra 为 Pydantic Model 声明一个示例值

代码语言:javascript复制
from typing import Optional
import uvicorn
from pydantic import BaseModel
from fastapi import FastAPI

app = FastAPI()


class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

    # 内部类,固定写法
    class Config:
        schema_extra = {
            "example": {
                "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


if __name__ == "__main__":
    uvicorn.run(app="13_example:app", host="127.0.0.1", port=8080, reload=True, debug=True)
查看 Swagger API 文档

无论是 Example Value 还是 Schema 都会显示声明的示例值

Field 添加额外的参数

使用 Pydantic 的 Field() 时,可以将任何其他任意参数添加到函数参数中,来声明 JSON Schema 的额外信息

Field 的 extra 参数

默认 Field 是没有 example 参数的,而 **extra 就是关键字参数,表示可以添加其他任意参数,和常见的 **kwargs 是一个作用哦

关键字参数教程

Field 教程

添加额外的参数: example 参数
代码语言:javascript复制
#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠萝测试笔记
# blog:  https://www.cnblogs.com/poloyy/
# time: 2021/9/19 9:40 下午
# file: 12_model.py
"""

from typing import Optional
import uvicorn
from pydantic import BaseModel, Field
from fastapi import FastAPI

app = FastAPI()

class Item(BaseModel):
    # 给每个字段加上了 example 参数
    name: str = Field(..., example="小菠萝")
    description: Optional[str] = Field(None, example="描述")
    price: float = Field(..., example=1.11)
    tax: Optional[float] = Field(None, example=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
一定要命名为 example 吗?
  • 不一定,命名为其他也可以
  • 但是只有添加名为 example 的参数,Swagger API 上的 Example Value 才会显示这里传的参数值(示例值)
重点
  • 因为这里的 example 参数是额外添加的参数,所以不会进行数据验证
  • 比如字段类型声明为 str,example 参数传了数组也不会报错
查看 Swagger API 文档

它是针对每个字段设置的示例值,所以会显示在字段下

OpenAPI 中的 example、examples 参数

当使用 FastAPI 提供的

  • Path()
  • Query()
  • Header()
  • Cookie()
  • Body()
  • Form()
  • File()

可以声明一个 example 或 examples 参数,FastAPI 会自动将 example、examples 的值添加到 OpenAPI 文档中

总结

Pydantic 并没有直接支持 example 参数,而 FastAPI 进行了扩展,直接支持添加 example、examples 参数

使用 Body() ,添加 example 参数

代码语言:javascript复制
#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠萝测试笔记
# blog:  https://www.cnblogs.com/poloyy/
# time: 2021/9/19 9:40 下午
# file: 12_model.py
"""

from typing import Optional
import uvicorn
from pydantic import BaseModel
from fastapi import FastAPI, Body

app = FastAPI()


class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None


@app.put("/items/{item_id}")
async def update_item(
        item_id: int,
        item: Item = Body(
            default=...,
            description="描述",
            # 添加一个 example 参数
            example={
                "name": "body name",
                "description": "body 描述",
                "price": 3.33,
                "tax": 5.55
            },
        ),
):
    results = {"item_id": item_id, "item": item}
    return results


if __name__ == "__main__":
    uvicorn.run(app="13_example:app", host="127.0.0.1", port=8080, reload=True, debug=True)
查看 Swagger API 文档

Schema 并不会显示 example 的值哦

使用 Body() ,添加 examples 参数

examples

本身是一个 dict,每个键标识一个具体的示例,而键对应的值也是一个 dict

每个示例 dict 可以包含

  • summary:简短描述
  • description:可以包含 markdown 文本的长描述
  • value:显示的示例值
  • externalValue:替代值,指向示例的 URL(不怎么用)
实际代码
代码语言:javascript复制
#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠萝测试笔记
# blog:  https://www.cnblogs.com/poloyy/
# time: 2021/9/19 9:40 下午
# file: 12_model.py
"""

from typing import Optional
import uvicorn
from pydantic import BaseModel, Field
from fastapi import FastAPI, Body

app = FastAPI()

class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None


@app.put("/items/{item_id}")
async def update_item(
        *,
        item_id: int,
        item: Item = Body(
            default=...,
        # 三个键,代表三个不一样的示例值
            examples={
                "normal": {
                    "summary": "正常的栗子",
                    "description": "A **normal** item works correctly.",
                    "value": {
                        "name": "Foo",
                        "description": "A very nice Item",
                        "price": 35.4,
                        "tax": 3.2,
                    },
                },
                "converted": {
                    "summary": "会自动转换类型的栗子",
                    "description": "FastAPI can convert price `strings` to actual `numbers` automatically",
                    "value": {
                        "name": "Bar",
                        "price": "35.4",
                    },
                },
                "invalid": {
                    "summary": "校验失败的栗子",
                    "value": {
                        "name": "Baz",
                        "price": "thirty five point four",
                    },
                },
            },
        ),
):
    results = {"item_id": item_id, "item": item}
    return results


if __name__ == "__main__":
    uvicorn.run(app="13_example:app", host="127.0.0.1", port=8080, reload=True, debug=True) 
查看 Swagger API 文档

0 人点赞