Body - Nested Models
可以将属性定义为子类型,例如 python 的 list
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
tags: list = []
@app.put("/items/{item_id}")
async def update_item(*, item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
tags 表示实体列表,尽管没有显式声明每个实体的类型
List fields with subtype
可以通过 python 的 typing 标准库来声明具有子类型的列表,例如
from typing import List
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
tags: List[str] = []
@app.put("/items/{item_id}")
async def update_item(*, item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
Set types
使用 set 类型可以声明一组不重复的实体
from typing import Set
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
tags: Set[str] = set()
@app.put("/items/{item_id}")
async def update_item(*, item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
通过 set,即使接收到一组重复数据,也将会被自动转化为一组没有重复的实体
这些也会被自动加入注解
Nested Models
Pydantic 模型的每一个属性都有其类型,并且这些类型可以是另一个 Pydantic 模型,因此可以声明嵌套的 JSON 对象,并且这些对象可以有特定的属性名称,类型和验证
所有这些都可以被任意嵌套
from typing import Set
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Image(BaseModel):
url: str
name: str
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
tags: Set[str] = []
image: Image = None
@app.put("/items/{item_id}")
async def update_item(*, item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
在上面的例子中,Image 模型作为 Item 模型的一个属性
FastAPI 期望的 request body 类似于
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2,
"tags": ["rock", "metal", "bar"],
"image": {
"url": "http://example.com/baz.jpg",
"name": "The Foo live"
}
}
仅仅使用上述声明以及 FastAPI,将可以获得
- IDE 支持
- 数据自动转换
- 数据验证
- 自动文档
Special types and validation
除了类似于 str,int,float 普通的单一类型,还可以使用继承于 str 的更加复杂的类型
例如,在 Image 模型里面,我们可以用 HttpUrl 类型来代替普通的 str,例如
from typing import Set
from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl
app = FastAPI()
class Image(BaseModel):
url: HttpUrl
name: str
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
tags: Set[str] = []
image: Image = None
@app.put("/items/{item_id}")
async def update_item(*, item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
url 属性将会自动检查是否是合法的 URL,并且在自动文档中标注
Attributes with lists of submodels
Ptdantic 模型同样可以作为 list,set 等的子类型,例如
from typing import List, Set
from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl
app = FastAPI()
class Image(BaseModel):
url: HttpUrl
name: str
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
tags: Set[str] = []
images: List[Image] = None
@app.put("/items/{item_id}")
async def update_item(*, item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
上面的例子将会期待 body
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2,
"tags": [
"rock",
"metal",
"bar"
],
"images": [
{
"url": "http://example.com/baz.jpg",
"name": "The Foo live"
},
{
"url": "http://example.com/dave.jpg",
"name": "The Baz"
}
]
}
Deeply nested models
可以定义任意深度嵌套的模型
from typing import List, Set
from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl
app = FastAPI()
class Image(BaseModel):
url: HttpUrl
name: str
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
tags: Set[str] = []
images: List[Image] = None
class Offer(BaseModel):
name: str
description: str = None
price: float
items: List[Item]
@app.post("/offers/")
async def create_offer(*, offer: Offer):
return offer
Bodies of pure lists
如果希望 JSON body 的顶层值是一个 JSON array,可以如下声明
from typing import List
from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl
app = FastAPI()
class Image(BaseModel):
url: HttpUrl
name: str
@app.post("/images/multiple/")
async def create_multiple_images(*, images: List[Image]):
return images
Bodies of arbitrary dicts
同样可以使用具有某些类型的键和某些类型的值的 dict 来声明 request body
可以被用在如果某些键和值名字不确定的情况,例如
from typing import Dict
from fastapi import FastAPI
app = FastAPI()
@app.post("/index-weights/")
async def create_index_weights(weights: Dict[int, float]):
return weights
在上述例子中,只要是整形的 key 和浮点型的 value 就会被接受
注:JSON 只支持 str 作为键,但是 Pydantic 模型可以对数据进行自动转换。即,即使客户端只支持发送字符串作为键,只要这些键只包含纯整数,Pydantic 就会进行自动转化和验证