多个参数
混用Path、Query和请求体参数
from fastapi import FastAPI, Path
from typing import Optional
from pydantic import BaseModel
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 = Path(..., title = "The ID of the item to get", ge=0, le=1000),
q: Optional[str] = None,
item: Optional[Item] = None
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
if item:
results.update({"item": item})
return results
多个请求体参数
上例中,路径操作预期JSON请求体中的Item
包含如下属性:
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
但也可以声明多个请求体参数,例如item
和user
:
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
class User(BaseModel):
username : str
full_name : Optional[str] = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item, user: User):
results = {"item_id": item_id, "item": item, "user": user}
return results
本例中,FastAPI能够识别函数中有多个请求体参数,因此,它把参数名作为请求体的键,并返回如下请求体:
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
},
"user": {
"username": "dave",
"full_name": "Dave Grohl"
}
}
fastapi会自动转换请求中的数据,因此item
和user
参数会接收指定的内容。
请求体中的单值
除了Query
和Path
可以为查询参数与路径参数定义更多数据之外,fastapi还提供了类似的Body
函数。例如,扩展上述模型,除了item
和user
之外,还要在同一请求体中,添加另一个键importance
,如果直接声明该参数,因为importance
是单值,fastapi会把它识别为查询参数,此时,就需要使用Body
让fastapi把它当做请求体的键。
from typing import Optional
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
class User(BaseModel):
username: str
full_name: Optional[str] = None
@appput("/items/{item_id}"):
async def update_item(item_id: int ,item: Item, user: User, importance: int = Body(...)):
results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
return results
此时,fastapi返回如下请求体:
{
"item": {
"name": "Foo",
"description": "The Pretender",
"price": 42.0,
"tax": 3.2
},
"user": {
"username": "dave",
"full_name": "Dave Grohl"
},
"importance": 5
}
多个请求体参数和查询参数
除了请求体参数外,还可以声明更多查询参数,默认情况下,单值会被解释为查询参数,因此不必显示添加Query
,只需要添加一下代码:
q: str = None
代码如下:
from typing import Optional
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
class User(BaseModel):
username: str
full_name: Optional[str] = None
@app.put("/items/{item_id}")
async def update_item(
*,
item_id: int,
item: Intem,
user: User,
importance: int = Body(..., gt=0),
q: Optional[str] = None
):
results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
if q:
results.update({"q": q})
return results
嵌套单个请求体参数
假设只有一个使用pydantic
模型Item
的请求体参数item
,默认情况下,fastapi会直接调用请求体,但是,如果希望JSON中包含item
键,且模型内容都在该键之下,就要参照声明更多请求体参数的方式,使用Body
的embed
参数:
item: Item = Body(..., embed=True)
代码如下:
from typing import Optional
from fastapi import Body, FastAPI
from pydantic import BaseModel
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(..., embed=True)):
results = {"item_id": item_id, "item": item}
return result
本例中,fastapi预期如下请求体:
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
}
字段
与在路径操作函数中使用Query
、Path
、Body
声明校验与元数据的方式一样,可以使用Pydantic的Field
在Pydantic模型内部声明校验和元数据。
声明模型属性
使用Field
定义模型属性:
from typing import Optional
from fastapi import Body, FastAPI
from pydantic import BaseModel, Field
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = Field(
None, title="The description of the item", max_length=300
)
price: float = Field(..., gt=0, description="The price must be greater than zero")
tax: Optional[float] = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item = Body(..., embed=True)):
results = {"item_id": item_id, "item": item}
return results
嵌套模型
List字段
模型属性可以定义为子类型
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[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字段
声明包含list
、dict
、tuple
等类型参数的类型:
from typing import List, Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
desciption: Optional[str] = None
price: float
tax: Optional[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类型
标签(tags)不能重复,每个标签字符串都应该是唯一的,python提供了专门保存一组唯一元素的数据类型,集合(set),导入Set
,并把tags
声明为由str
组成的set
:
from typing import Optional, Set
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[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}
freturn results
收到的请求中包含重复数据时,会被转换为只包含唯一元素的集合,而且,每次输出数据时,即使源数据中有重复项,输出的也是值包含唯一元素的集合,并且还会在文档中进行相应地注释/存档。
嵌套模型
pydantic模型的每个属性都有自己的类型,而且,这些属性的类型也可以是pydantic模型,因此,pydantic模型可以声明拥有特定属性名、类型和校验的深度嵌套JSON对象,所以这些对象,都可以嵌套。
定义子模型:
from typing import Optional, Set
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Image(BaseModel):
url: str
name: str
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Set[str] = []
image: Optional[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
FastAPI返回如下请求体:
{
"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"
}
}
特殊类型与校验
除了str
、int
、float
等普通单值类型外,还可以使用从str继承的复杂单值类型。
例如:把Image
模型的url
字段声明为Pydantic的HttpUrl
,而不是str。
from typing import Optional, 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: Optional[str] = None
price: float
tax: Optional[float] = None
tags: Set[str] = set()
image: Optional[Image] = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return result
包含子模型列表的属性
list
、set
的子类型也可以是Pydantic模型。
from typing import List, Optional, Set
from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl
app = FastAPI()
class Image(BaseModel):
url: HttpUrl
name: str
class Image(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Set[str] = set()
image: Optional[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
JSON请求体以如下方式转、校验并存档:
{
"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"
}
]
}
深度嵌套模型
from typing import List, Optional, 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: Optional[str] = None
price: float
tax: Optional[float] = None
tags: Set[str] = set()
images: Optional[List[Image]] = None
class Offer(BaseModel):
name: str
description: Optional[str] = None
price: float
items: List[Item]
@app.post("/offers/")
async def create_offer(offer: Offer):
return offer
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具