7.FastAPI嵌套请求体

7.FastAPI嵌套请求体

在FastAPI中, Pydantic支持任意深度的嵌套模型,同时支持校验和文档。

7.1List字段

7.1.1使用 Python list 定义字段类型

代码如下:

from fastapi import FastAPI
​
app = FastAPI()
​
@app.post(path='/sort')
async def sort(lst: list):
    lst.sort()
    return lst

执行请求:

curl -H "Content-Type: application/json" -X POST -d "[10,2,3,9,8,5,6,7,1,4]" http://127.0.0.1:8000/sort
[1,2,3,4,5,6,7,8,9,10]

7.1.2使用 Python 标准库 的typing模块中的List

在上面的代码中,使用了Python的list类型定义参数的类型,但这样做无法指定元素的类型,也就是说,参数可以时任意类型的列表;如果使用Python 标准库的typing模块中的List,则可以指定List的子类型来限制元素的类型;代码如下:

from fastapi import FastAPI
from typing import List
​
app = FastAPI()
​
​
@app.post(path='/sort')
async def sort(lst: List[str]):
    lst.sort()
    return lst

代码中,将lst的类型设置为typing模块的List类型,并限制子类型为str,执行请求:

curl -H "Content-Type: application/json" -X POST -d "[10,2,3,9,8,5,6,7,1,4]" http://127.0.0.1:8000/sort
["1","10","2","3","4","5","6","7","8","9"]

可以看到:返回的列表为字符串列表,并且是按照字符串的排序规则进行排序的。

上面的规则同样适用于set、tuple、dict等,在此不再一一举例。

7.2嵌套模型

Pydantic 模型的每个属性都可以声明类型,类型本身也可以是另外一个 Pydantic 模型,所以,可以声明拥有特定属性名称、类型和校验的深度嵌套的 JSON 对象。

代码示例:

from fastapi import FastAPI
from pydantic import BaseModel
​
app = FastAPI()
​
class Cuboid(BaseModel):
    length: int
    width: int
    high: int
​
class Box(BaseModel):
    sn: int
    name: str
    cubiod: Cuboid
​
@app.post(path='/box')
async def sort(box: Box):
    return {'box': box, 'volume': box.cubiod.length * box.cubiod.width * box.cubiod.high}

执行请求:

curl -H "Content-Type: application/json" -X POST -d "{\"sn\":1, \"name\":\"box1\", \"cubiod\":{\"length\": 10,\"width\": 10,\"high\": 10}}" http://127.0.0.1:8000/box
{
    "box":{
        "sn":1,
        "name":"box1",
        "cubiod":{
            "length":10,
            "width":10,
            "high":10
        }
    },
    "volume":1000
}

在上面的代码中,模型Cuboid是模型Box的子模型。

7.3子模型列表

代码示例:

from fastapi import FastAPI
from pydantic import BaseModel
from typing import List
from statistics import mean
​
app = FastAPI()
​
class Cuboid(BaseModel):
    length: int
    width: int
    high: int
​
class Box(BaseModel):
    sn: int
    name: str
    cubiods: List[Cuboid]
​
@app.post(path='/box')
async def sort(box: Box):
    volumes = []
    for cubiod in box.cubiods:
        volumes.append(cubiod.length * cubiod.width * cubiod.high)
    return {
        'box': box,
        'min_volume': min(volumes),
        'max_volume': max(volumes),
        'sum_volume': sum(volumes),
        'avg_volume': mean(volumes)
    }

执行请求:

curl -H "Content-Type: application/json" -X POST -d "{\"sn\":1, \"name\":\"boxes1\", \"cubiods\":[{\"length\": 10,\"width\": 10,\"high\": 10}, {\"length\": 9,\"width\": 9,\"high\": 9}, {\"length\": 8,\"width\": 8,\"high\": 8}]}" http://127.0.0.1:8000/box
{
    "box":{
        "sn":1,
        "name":"boxes1",
        "cubiods":[
            {
                "length":10,
                "width":10,
                "high":10
            },{
                "length":9,
                "width":9,
                "high":9
            },
                "length":8,
                "width":8,
                "high":8
            }
        ]
    },
    "min_volume":512,
    "max_volume":1000,
    "sum_volume":2241,
    "avg_volume":747
}

7.4任意 dict 请求体

在FastAPI中,可以将请求体声明为使用某类型的键和某类型值的 dict,也就是说,不需要事先确定字段名称,当需要接收未知键的dict时,非常有用。

需要注意: JSON 仅支持将 str 作为键,所以当需要使用int等非str类型作为键时,Pydantic 具有自动转换数据的功能。也就是说,即使API 客户端只能将字符串作为键发送,只要这些字符串内容仅包含整数,Pydantic 就会对其进行int转换并校验。

代码示例:

from fastapi import FastAPI
from typing import Dict
​
app = FastAPI()
​
@app.post(path='/dictionary')
async def dictionary(d: Dict[int, str]):
    return {'key': list(d.keys()), 'value': list(d.values())}   

执行请求:

curl -H "Content-Type: application/json" -X POST -d "{\"1\":\"First\"}" http://127.0.0.1:8000/dictionary
{"key":[1],"value":["First"]}

通过上面的代码,可以看到,路由接收以int为键,以str为值的字典,客户端请求时,传入的键类型为str,但该str是可以转换为int类型的字符串。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Janeb1018

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值