参数校验
基本的类型验证可以通过指定参数类型来实现。
如果需要更复杂的校验,就需要引入 fastapi 的 Query 模块。例如:
from typing import Optional
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Optional[str] = Query(None, min_length=3, max_length=50, regex="^qr")
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
Query 的第一个参数是默认值,为 None 代表默认值为空,如果为 ... 则表示为必填。min_length、max_length 和 regex 分别代表最小长度、最大长度和正则表达式。
获取列表类型的参数
我们可以导入 typing 模块的 List ,用来接收列表类型的参数,例如:
from typing import List, Optional
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items1/")
async def read_items1(q: List[str] = Query(["foo", "bar"])): # 带默认值的列表
query_items = {"q": q}
return query_items
@app.get("/items2/")
async def read_items2(q: Optional[List[str]] = Query(None)): # 可选列表
query_items = {"q": q}
return query_items
在浏览器中输入 http://localhost:8000/items1/?q=tom&q=jerry 就可以得到:{"q":["tom","jerry"]}
输入 http://localhost:8000/items1/ 则会得到 {"q":["foo","bar"]}
Query 的一些其他参数
元数据相关
你可以为 Query 加入 title 和 description 两个参数来输入一些元数据相关信息,例如:
@app.get("/items/")
async def read_items(
q: Optional[str] = Query(
None,
title="Query string",
description="Query string for the items to search in the database that have a good match",
min_length=3,
)
):
别名
使用 alias 可以指定别名,例如:
@app.get("/items/")
async def read_items(q: Optional[str] = Query(None, alias="item-query")):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
这样我们在 url 中的参数就必须使用 item-query 而不是 q 了。
废弃
如果加入 deprecated=True 就表示该参数已废弃,不接受任何输入。
数值类型的校验
如果是数值类型的参数,可以用如下几个校验方式:
- gt 大于
- ge 大于等于
- lt 小于
- le 小于等于
例如:
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_item(q: int = Query(..., ge=1, le=10)):
query_items = {"q": q}
return query_items
此时如果访问 http://localhost:8000/items/?q=5 就会得到 {"q":5}; 而如果访问 http://localhost:8000/items/?q=11 则会报错 “ensure this value is less than or equal to 10” 。
路径参数的校验
Query 对象是针对通过 url 传入的查询参数的,而 Path 则是针对路径参数,Body 针对从请求体传入的参数。针对路径参数可以这样去校验:
from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
*, # 这里的星号表示后面的参数必须通过关键字参数的方式传入
item_id: int = Path(..., title="The ID of the item to get", gt=0, le=1000),
q: str,
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
各种参数的混合使用
Query、Path 和 Body 参数的混用
代码如下:
from typing import Optional
from fastapi import FastAPI, Path
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,
):
# 这里item_id是路径参数,q是查询参数,item是Body参数
results = {"item_id": item_id}
if q:
results.update({"q": q})
if item:
results.update({"item": item})
return results
Body 中还可以定义多个参数,比如:
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):
# 这里有两个body参数,一个是 item ,一个是 user
results = {"item_id": item_id, "item": item, "user": user}
return results