FastAPI 允許你為參數(shù)聲明額外的信息和校驗(yàn)。
讓我們以下面的應(yīng)用程序?yàn)槔?/p>
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/")
async def read_items(q: Optional[str] = None):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
查詢參數(shù) q 的類型為 str,默認(rèn)值為 None,因此它是可選的。
我們打算添加約束條件:即使 q 是可選的,但只要提供了該參數(shù),則該參數(shù)值不能超過(guò)50個(gè)字符的長(zhǎng)度。
為此,首先從 fastapi 導(dǎo)入 Query:
from typing import Optional
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Optional[str] = Query(None, max_length=50)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
現(xiàn)在,將 Query 用作查詢參數(shù)的默認(rèn)值,并將它的 max_length 參數(shù)設(shè)置為 50:
from typing import Optional
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Optional[str] = Query(None, max_length=50)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
由于我們必須用 Query(None) 替換默認(rèn)值 None,Query 的第一個(gè)參數(shù)同樣也是用于定義默認(rèn)值。
所以:
q: str = Query(None)
...使得參數(shù)可選,等同于:
q: str = None
但是 Query 顯式地將其聲明為查詢參數(shù)。
然后,我們可以將更多的參數(shù)傳遞給 Query。在本例中,適用于字符串的 max_length 參數(shù):
q: str = Query(None, max_length=50)
將會(huì)校驗(yàn)數(shù)據(jù),在數(shù)據(jù)無(wú)效時(shí)展示清晰的錯(cuò)誤信息,并在 OpenAPI 模式的路徑操作中記錄該參??數(shù)。
你還可以添加 min_length 參數(shù):
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)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
你可以定義一個(gè)參數(shù)值必須匹配的正則表達(dá)式:
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="^fixedquery$")
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
這個(gè)指定的正則表達(dá)式通過(guò)以下規(guī)則檢查接收到的參數(shù)值:
如果你對(duì)所有的這些「正則表達(dá)式」概念感到迷茫,請(qǐng)不要擔(dān)心。對(duì)于許多人來(lái)說(shuō)這都是一個(gè)困難的主題。你仍然可以在無(wú)需正則表達(dá)式的情況下做很多事情。
但是,一旦你需要用到并去學(xué)習(xí)它們時(shí),請(qǐng)了解你已經(jīng)可以在 FastAPI 中直接使用它們。
你可以向 Query 的第一個(gè)參數(shù)傳入 None 用作查詢參數(shù)的默認(rèn)值,以同樣的方式你也可以傳遞其他默認(rèn)值。
假設(shè)你想要聲明查詢參數(shù) q,使其 min_length 為 3,并且默認(rèn)值為 fixedquery:
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: str = Query("fixedquery", min_length=3)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
Note
具有默認(rèn)值還會(huì)使該參數(shù)成為可選參數(shù)。
當(dāng)我們不需要聲明額外的校驗(yàn)或元數(shù)據(jù)時(shí),只需不聲明默認(rèn)值就可以使 q 參數(shù)成為必需參數(shù),例如:
q: str
代替:
q: str = None
但是現(xiàn)在我們正在用 Query 聲明它,例如:
q: str = Query(None, min_length=3)
因此,當(dāng)你在使用 Query 且需要聲明一個(gè)值是必需的時(shí),可以將 ... 用作第一個(gè)參數(shù)值:
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: str = Query(..., min_length=3)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
Info
如果你之前沒(méi)見(jiàn)過(guò) ... 這種用法:它是一個(gè)特殊的單獨(dú)值,它是 Python 的一部分并且被稱為「省略號(hào)」。
這將使 FastAPI 知道此查詢參數(shù)是必需的。
當(dāng)你使用 Query 顯式地定義查詢參數(shù)時(shí),你還可以聲明它去接收一組值,或換句話來(lái)說(shuō),接收多個(gè)值。
例如,要聲明一個(gè)可在 URL 中出現(xiàn)多次的查詢參數(shù) q,你可以這樣寫:
from typing import List, Optional
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Optional[List[str]] = Query(None)):
query_items = {"q": q}
return query_items
然后,輸入如下網(wǎng)址:
http://localhost:8000/items/?q=foo&q=bar
你會(huì)在路徑操作函數(shù)的函數(shù)參數(shù) q 中以一個(gè) Python list 的形式接收到查詢參數(shù) q 的多個(gè)值(foo 和 bar)。
因此,該 URL 的響應(yīng)將會(huì)是:
{
"q": [
"foo",
"bar"
]
}
Tip
要聲明類型為 list 的查詢參數(shù),如上例所示,你需要顯式地使用 Query,否則該參數(shù)將被解釋為請(qǐng)求體。
交互式 API 文檔將會(huì)相應(yīng)地進(jìn)行更新,以允許使用多個(gè)值:
你還可以定義在沒(méi)有任何給定值時(shí)的默認(rèn) list 值:
from typing import List
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: List[str] = Query(["foo", "bar"])):
query_items = {"q": q}
return query_items
如果你訪問(wèn):
http://localhost:8000/items/
q 的默認(rèn)值將為:["foo", "bar"],你的響應(yīng)會(huì)是:
{
"q": [
"foo",
"bar"
]
}
你也可以直接使用 list 代替 List [str]:
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: list = Query([])):
query_items = {"q": q}
return query_items
Note
請(qǐng)記住,在這種情況下 FastAPI 將不會(huì)檢查列表的內(nèi)容。
例如,List[int] 將檢查(并記錄到文檔)列表的內(nèi)容必須是整數(shù)。但是單獨(dú)的 list 不會(huì)。
你可以添加更多有關(guān)該參數(shù)的信息。
這些信息將包含在生成的 OpenAPI 模式中,并由文檔用戶界面和外部工具所使用。
Note
請(qǐng)記住,不同的工具對(duì) OpenAPI 的支持程度可能不同。
其中一些可能不會(huì)展示所有已聲明的額外信息,盡管在大多數(shù)情況下,缺少的這部分功能已經(jīng)計(jì)劃進(jìn)行開(kāi)發(fā)。
你可以添加 title:
from typing import Optional
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Optional[str] = Query(None, title="Query string", min_length=3)
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
以及 description:
from typing import Optional
from fastapi import FastAPI, Query
app = FastAPI()
@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,
)
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
假設(shè)你想要查詢參數(shù)為 item-query。
像下面這樣:
http://127.0.0.1:8000/items/?item-query=foobaritems
但是 item-query 不是一個(gè)有效的 Python 變量名稱。
最接近的有效名稱是 item_query。
但是你仍然要求它在 URL 中必須是 item-query...
這時(shí)你可以用 alias 參數(shù)聲明一個(gè)別名,該別名將用于在 URL 中查找查詢參數(shù)值:
from typing import Optional
from fastapi import FastAPI, Query
app = FastAPI()
@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
現(xiàn)在假設(shè)你不再喜歡此參數(shù)。
你不得不將其保留一段時(shí)間,因?yàn)橛行┛蛻舳苏谑褂盟?,但你希望文檔清楚地將其展示為已棄用。
那么將參數(shù) deprecated=True 傳入 Query:
from typing import Optional
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Optional[str] = Query(
None,
alias="item-query",
title="Query string",
description="Query string for the items to search in the database that have a good match",
min_length=3,
max_length=50,
regex="^fixedquery$",
deprecated=True,
)
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
文檔將會(huì)像下面這樣展示它:
你可以為查詢參數(shù)聲明額外的校驗(yàn)和元數(shù)據(jù)。
通用的校驗(yàn)和元數(shù)據(jù):
特定于字符串的校驗(yàn):
在這些示例中,你了解了如何聲明對(duì) str 值的校驗(yàn)。
請(qǐng)參閱下一章節(jié),以了解如何聲明對(duì)其他類型例如數(shù)值的校驗(yàn)。
更多建議: