查詢參數和字串驗證¶
FastAPI 允許您為參數宣告額外資訊和驗證。
讓我們以這個應用程式為例
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/")
async def read_items(q: str | None = None):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/")
async def read_items(q: Union[str, None] = None):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
查詢參數 q
的類型為 Union[str, None]
(或 Python 3.10 中的 str | None
),這表示它的類型為 str
,但也可能是 None
,實際上,預設值為 None
,因此 FastAPI 會知道它不是必需的。
注意事項
FastAPI 會因為預設值 = None
而知道 q
的值不是必需的。
Union[str, None]
中的 Union
將允許您的編輯器提供更好的支援並偵測錯誤。
額外驗證¶
我們將強制執行,即使 q
是可選的,只要提供它,其長度不得超過 50 個字元。
匯入 Query
和 Annotated
¶
要做到這一點,首先匯入
- 從
fastapi
匯入Query
- 從
typing
(或 Python 3.9 以下版本中的typing_extensions
)匯入Annotated
在 Python 3.9 或更高版本中,Annotated
是標準函式庫的一部分,因此您可以從 typing
匯入它。
from typing import Annotated
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[str | None, Query(max_length=50)] = None):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
在 Python 3.9 以下的版本中,您從 typing_extensions
匯入 Annotated
。
它將與 FastAPI 一起安裝。
from typing import Union
from fastapi import FastAPI, Query
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[Union[str, None], Query(max_length=50)] = None):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
資訊
FastAPI 在 0.95.0 版中新增了對 Annotated
的支援(並開始推薦它)。
如果您使用的是舊版本,則嘗試使用 Annotated
時會發生錯誤。
在使用 Annotated
之前,請確保您將 FastAPI 版本升級到至少 0.95.1。
在 q
參數的類型中使用 Annotated
¶
記得我之前在Python 類型簡介中告訴過您,Annotated
可以用來向您的參數新增中繼資料嗎?
現在是時候將它與 FastAPI 一起使用了。 🚀
我們有這個類型註釋
q: str | None = None
q: Union[str, None] = None
我們要做的是用 Annotated
包括它,所以它變成
q: Annotated[str | None] = None
q: Annotated[Union[str, None]] = None
這兩個版本的意思相同,q
是一個可以是 str
或 None
的參數,預設情況下,它是 None
。
現在讓我們跳到有趣的部分。 🎉
在 q
參數中,將 Query
加入 Annotated
¶
現在我們有了這個 Annotated
,可以在其中放入更多資訊(在這個例子中是一些額外的驗證),在 Annotated
內加入 Query
,並將參數 max_length
設定為 50
from typing import Annotated
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[str | None, Query(max_length=50)] = None):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
from typing import Union
from fastapi import FastAPI, Query
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[Union[str, None], Query(max_length=50)] = None):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
請注意,預設值仍然是 None
,因此該參數仍然是可選的。
但現在,在 Annotated
中有了 Query(max_length=50)
,我們告訴 FastAPI 我們希望它對這個值進行額外的驗證,我們希望它的最大長度為 50 個字元。 😎
提示
這裡我們使用 Query()
,因為這是一個查詢參數。稍後我們會看到其他像 Path()
、Body()
、Header()
和 Cookie()
,它們也接受與 Query()
相同的參數。
FastAPI 現在將
- 驗證數據,確保最大長度為 50 個字元
- 當數據無效時,向用戶端顯示清晰的錯誤訊息
- 在 OpenAPI schema 的路徑操作中記錄參數(這樣它就會顯示在自動文件 UI 中)
替代方案(舊版):將 Query
作為預設值¶
早期版本的 FastAPI(0.95.0 之前)要求您使用 Query
作為參數的預設值,而不是將其放在 Annotated
中,您很有可能會看到使用它的程式碼,所以我會向您解釋。
提示
對於新的程式碼,以及在任何可能的情況下,請使用上述的 Annotated
。它有多種優點(下文說明),而且沒有缺點。🍰
以下是您如何使用 Query()
作為函式參數的預設值,將參數 max_length
設定為 50
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: str | None = Query(default=None, max_length=50)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
from typing import Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Union[str, None] = Query(default=None, max_length=50)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
由於在這種情況下(不使用 Annotated
)我們必須用 Query()
取代函式中的預設值 None
,我們現在需要使用參數 Query(default=None)
設定預設值,它的作用與定義該預設值相同(至少對於 FastAPI 而言)。
所以
q: Union[str, None] = Query(default=None)
...使參數成為可選的,預設值為 None
,與
q: Union[str, None] = None
以及在 Python 3.10 及更高版本中
q: str | None = Query(default=None)
...使參數成為可選的,預設值為 None
,與
q: str | None = None
相同,但 Query
版本明確地將其宣告為查詢參數。
資訊
請記住,使參數成為可選的最重要部分是
= None
或
= Query(default=None)
部分,因為它會使用 None
作為預設值,這樣使參數非必要。
Union[str, None]
部分允許您的編輯器提供更好的支援,但它並不是告訴 FastAPI 這個參數不是必需的。
然後,我們可以將更多參數傳遞給 Query
。在這種情況下,max_length
參數適用於字串
q: Union[str, None] = Query(default=None, max_length=50)
這將驗證數據,在數據無效時顯示清晰的錯誤訊息,並在 OpenAPI schema 的路徑操作中記錄參數。
將 Query
作為預設值或放在 Annotated
中¶
請記住,當在 Annotated
中使用 Query
時,您不能使用 Query
的 default
參數。
請使用函式參數的實際預設值。否則,它會不一致。
例如,這是不允許的
q: Annotated[str, Query(default="rick")] = "morty"
...因為不清楚預設值應該是 "rick"
還是 "morty"
。
所以,您應該使用(最好是)
q: Annotated[str, Query()] = "rick"
...或者在較舊的程式碼庫中,您會發現
q: str = Query(default="rick")
Annotated
的優點¶
建議使用 Annotated
,而不是在函式參數中使用預設值,這樣做基於多種原因會**更好**。🤓
**函式參數**的**預設值**是**實際的預設值**,這通常來說在 Python 中更直觀。😌
您可以在 FastAPI 之外的**其他地方**呼叫同一個函式,它會**按預期工作**。如果有一個**必要**參數(沒有預設值),您的**編輯器**會透過錯誤訊息讓您知道,如果您在執行時沒有傳遞必要的參數,**Python** 也會發出錯誤訊息。
當您不使用 Annotated
而是使用**(舊的)預設值樣式**時,如果您在 FastAPI 之外的**其他地方**呼叫該函式,您必須**記住**將參數傳遞給函式才能使其正常工作,否則值會與您的預期不同(例如,會是 QueryInfo
或類似的东西,而不是 str
)。而且您的編輯器不會發出錯誤訊息,執行該函式時 Python 也不會發出錯誤訊息,只有在內部操作出錯時才會出現錯誤。
由於 Annotated
可以有多個中繼資料註釋,您現在甚至可以使用其他工具與相同的函式搭配使用,例如 Typer。🚀
新增更多驗證¶
您也可以新增參數 min_length
from typing import Annotated
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Annotated[str | None, Query(min_length=3, max_length=50)] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
from typing import Annotated, Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Annotated[Union[str, None], Query(min_length=3, max_length=50)] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
from typing import Union
from fastapi import FastAPI, Query
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Annotated[Union[str, None], Query(min_length=3, max_length=50)] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
提示
如果可能,建議使用 Annotated
版本。
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: str | None = Query(default=None, min_length=3, max_length=50)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
提示
如果可能,建議使用 Annotated
版本。
from typing import Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Union[str, None] = Query(default=None, min_length=3, max_length=50),
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
新增正規表達式¶
您可以定義參數應該符合的正規表達式 pattern
from typing import Annotated
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Annotated[
str | None, Query(min_length=3, max_length=50, pattern="^fixedquery$")
] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
from typing import Annotated, Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Annotated[
Union[str, None], Query(min_length=3, max_length=50, pattern="^fixedquery$")
] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
from typing import Union
from fastapi import FastAPI, Query
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Annotated[
Union[str, None], Query(min_length=3, max_length=50, pattern="^fixedquery$")
] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
提示
如果可能,建議使用 Annotated
版本。
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: str | None = Query(
default=None, min_length=3, max_length=50, pattern="^fixedquery$"
),
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
提示
如果可能,建議使用 Annotated
版本。
from typing import Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Union[str, None] = Query(
default=None, min_length=3, max_length=50, pattern="^fixedquery$"
),
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
這個特定的正規表達式模式會檢查接收到的參數值
^
:以以下字元開頭,前面沒有字元。fixedquery
:具有確切值fixedquery
。$
:在此結束,在fixedquery
之後沒有任何其他字元。
如果您對所有這些**「正規表達式」**的概念感到困惑,請不要擔心。它們對許多人來說是一個困難的主題。您仍然可以在不需要正規表達式的情況下完成很多工作。
但是,當您需要它們並去學習它們時,請知道您已經可以直接在 **FastAPI** 中使用它們。
Pydantic v1 使用 regex
而不是 pattern
¶
在 Pydantic 版本 2 和 FastAPI 0.100.0 之前,該參數稱為 regex
而不是 pattern
,但現在已棄用。
您可能仍然會看到一些使用它的程式碼
from typing import Annotated
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Annotated[
str | None, Query(min_length=3, max_length=50, regex="^fixedquery$")
] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
但要知道,這已被棄用,應該更新為使用新的參數 pattern
。🤓
預設值¶
您當然可以使用 None
以外的預設值。
假設您想要宣告 q
查詢參數的 min_length
為 3
,並且預設值為 "fixedquery"
from typing import Annotated
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[str, Query(min_length=3)] = "fixedquery"):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
from fastapi import FastAPI, Query
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[str, Query(min_length=3)] = "fixedquery"):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
提示
如果可能,建議使用 Annotated
版本。
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: str = Query(default="fixedquery", min_length=3)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
注意事項
具有任何類型的預設值,包括 None
,都會使參數成為選用(非必要)。
必要參數¶
當我們不需要宣告更多驗證或中繼資料時,我們可以透過不宣告預設值來使 q
查詢參數成為必要參數,例如
q: str
而不是
q: Union[str, None] = None
但我們現在用 Query
宣告它,例如
q: Annotated[Union[str, None], Query(min_length=3)] = None
q: Union[str, None] = Query(default=None, min_length=3)
因此,當您需要在使用 Query
時將值宣告為必要參數時,您可以簡單地不宣告預設值
from typing import Annotated
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[str, Query(min_length=3)]):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
from fastapi import FastAPI, Query
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[str, Query(min_length=3)]):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
提示
如果可能,建議使用 Annotated
版本。
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
提示
請注意,即使在這種情況下,Query()
被用作函式參數的預設值,我們也不會將 default=None
傳遞給 Query()
。
儘管如此,使用 Annotated
版本可能還是比較好。 😉
搭配省略號 (...
) 使用的必要性¶
有另一種方法可以明確宣告一個值是必要的。您可以將預設值設定為字面值 ...
from typing import Annotated
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[str, Query(min_length=3)] = ...):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
from fastapi import FastAPI, Query
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[str, Query(min_length=3)] = ...):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
提示
如果可能,建議使用 Annotated
版本。
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: str = Query(default=..., min_length=3)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
這會讓 FastAPI 知道這個參數是必要的。
必要,可以是 None
¶
您可以宣告一個參數可以接受 None
,但它仍然是必要的。這會強制客戶端傳送一個值,即使該值是 None
。
要做到這一點,您可以宣告 None
是一個有效的類型,但仍然使用 ...
作為預設值。
from typing import Annotated
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[str | None, Query(min_length=3)] = ...):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
from typing import Annotated, Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[Union[str, None], Query(min_length=3)] = ...):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
from typing import Union
from fastapi import FastAPI, Query
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[Union[str, None], Query(min_length=3)] = ...):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
提示
如果可能,建議使用 Annotated
版本。
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: str | None = Query(default=..., min_length=3)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
提示
如果可能,建議使用 Annotated
版本。
from typing import Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Union[str, None] = Query(default=..., min_length=3)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
提示
Pydantic 是 FastAPI 中所有資料驗證和序列化功能的基礎,當您使用沒有預設值的 Optional
或 Union[Something, None]
時,它有一個特殊的行為,您可以在 Pydantic 文件中關於 必要欄位 的部分了解更多資訊。
提示
請記住,在大多數情況下,當某個東西是必要的時候,您可以直接省略預設值,所以您通常不需要使用 ...
。
查詢參數列表 / 多個值¶
當您使用 Query
明確定義查詢參數時,您也可以宣告它接收值的列表,或者換句話說,接收多個值。
例如,要宣告一個可以在 URL 中出現多次的查詢參數 q
,您可以這樣寫:
from typing import Annotated
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[list[str] | None, Query()] = None):
query_items = {"q": q}
return query_items
from typing import Annotated, Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[Union[list[str], None], Query()] = None):
query_items = {"q": q}
return query_items
from typing import List, Union
from fastapi import FastAPI, Query
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[Union[List[str], None], Query()] = None):
query_items = {"q": q}
return query_items
提示
如果可能,建議使用 Annotated
版本。
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: list[str] | None = Query(default=None)):
query_items = {"q": q}
return query_items
提示
如果可能,建議使用 Annotated
版本。
from typing import Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Union[list[str], None] = Query(default=None)):
query_items = {"q": q}
return query_items
提示
如果可能,建議使用 Annotated
版本。
from typing import List, Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Union[List[str], None] = Query(default=None)):
query_items = {"q": q}
return query_items
然後,使用像這樣的 URL:
http://localhost:8000/items/?q=foo&q=bar
您會在您的*路徑操作函式*中,*函式參數* q
中,以 Python list
的形式接收到多個 q
*查詢參數*的值(foo
和 bar
)。
因此,該 URL 的回應將是:
{
"q": [
"foo",
"bar"
]
}
提示
要宣告一個類型為 list
的查詢參數,如上例所示,您需要明確使用 Query
,否則它會被解釋為請求主體。
互動式 API 文件將會相應更新,允許多個值。
帶有預設值的查詢參數列表 / 多個值¶
如果沒有提供任何值,您也可以定義一個預設的 list
值。
from typing import Annotated
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[list[str], Query()] = ["foo", "bar"]):
query_items = {"q": q}
return query_items
from typing import List
from fastapi import FastAPI, Query
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[List[str], Query()] = ["foo", "bar"]):
query_items = {"q": q}
return query_items
提示
如果可能,建議使用 Annotated
版本。
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: list[str] = Query(default=["foo", "bar"])):
query_items = {"q": q}
return query_items
提示
如果可能,建議使用 Annotated
版本。
from typing import List
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: List[str] = Query(default=["foo", "bar"])):
query_items = {"q": q}
return query_items
如果您前往:
http://localhost:8000/items/
q
的預設值將是:["foo", "bar"]
,您的回應將是:
{
"q": [
"foo",
"bar"
]
}
僅使用 list
¶
您也可以直接使用 list
,而不是 List[str]
(或 Python 3.9+ 中的 list[str]
)。
from typing import Annotated
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[list, Query()] = []):
query_items = {"q": q}
return query_items
from fastapi import FastAPI, Query
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[list, Query()] = []):
query_items = {"q": q}
return query_items
提示
如果可能,建議使用 Annotated
版本。
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: list = Query(default=[])):
query_items = {"q": q}
return query_items
注意事項
請記住,在這種情況下,FastAPI 不會檢查列表的內容。
例如,List[int]
會檢查(並記錄)列表的內容是否為整數。但單獨使用 list
則不會。
宣告更多中繼資料¶
您可以新增更多關於參數的資訊。
這些資訊將包含在產生的 OpenAPI 中,並由文件使用者介面和外部工具使用。
注意事項
請記住,不同的工具可能具有不同程度的 OpenAPI 支援。
其中一些可能尚未顯示所有已宣告的額外資訊,但在大多數情況下,缺少的功能已規劃開發。
您可以新增一個 title
(標題)
from typing import Annotated
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Annotated[str | None, Query(title="Query string", min_length=3)] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
from typing import Annotated, Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Annotated[Union[str, None], Query(title="Query string", min_length=3)] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
from typing import Union
from fastapi import FastAPI, Query
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Annotated[Union[str, None], Query(title="Query string", min_length=3)] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
提示
如果可能,建議使用 Annotated
版本。
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: str | None = Query(default=None, title="Query string", min_length=3),
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
提示
如果可能,建議使用 Annotated
版本。
from typing import Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Union[str, None] = Query(default=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 Annotated
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Annotated[
str | None,
Query(
title="Query string",
description="Query string for the items to search in the database that have a good match",
min_length=3,
),
] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
from typing import Annotated, Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Annotated[
Union[str, None],
Query(
title="Query string",
description="Query string for the items to search in the database that have a good match",
min_length=3,
),
] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
from typing import Union
from fastapi import FastAPI, Query
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Annotated[
Union[str, None],
Query(
title="Query string",
description="Query string for the items to search in the database that have a good match",
min_length=3,
),
] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
提示
如果可能,建議使用 Annotated
版本。
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: str | None = Query(
default=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
提示
如果可能,建議使用 Annotated
版本。
from typing import Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Union[str, None] = Query(
default=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
別名參數¶
假設您希望參數為 item-query
。
像這樣
http://127.0.0.1:8000/items/?item-query=foobaritems
但 item-query
不是有效的 Python 變數名稱。
最接近的應該是 item_query
。
但您仍然需要它是 item-query
...
那麼您可以宣告一個 alias
(別名),該別名將用於查找參數值。
from typing import Annotated
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[str | None, Query(alias="item-query")] = None):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
from typing import Annotated, Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[Union[str, None], Query(alias="item-query")] = None):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
from typing import Union
from fastapi import FastAPI, Query
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[Union[str, None], Query(alias="item-query")] = None):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
提示
如果可能,建議使用 Annotated
版本。
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: str | None = Query(default=None, alias="item-query")):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
提示
如果可能,建議使用 Annotated
版本。
from typing import Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Union[str, None] = Query(default=None, alias="item-query")):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
棄用參數¶
現在假設您不再喜歡這個參數了。
您必須將其保留一段時間,因為有客戶正在使用它,但您希望在文件中清楚地將其顯示為已棄用。
然後將參數 deprecated=True
傳遞給 Query
from typing import Annotated
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Annotated[
str | None,
Query(
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,
pattern="^fixedquery$",
deprecated=True,
),
] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
from typing import Annotated, Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Annotated[
Union[str, None],
Query(
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,
pattern="^fixedquery$",
deprecated=True,
),
] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
from typing import Union
from fastapi import FastAPI, Query
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Annotated[
Union[str, None],
Query(
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,
pattern="^fixedquery$",
deprecated=True,
),
] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
提示
如果可能,建議使用 Annotated
版本。
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: str | None = Query(
default=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,
pattern="^fixedquery$",
deprecated=True,
),
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
提示
如果可能,建議使用 Annotated
版本。
from typing import Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Union[str, None] = Query(
default=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,
pattern="^fixedquery$",
deprecated=True,
),
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
文件將會像這樣顯示
從 OpenAPI 中排除參數¶
要從產生的 OpenAPI 綱要(以及自動文件系統)中排除查詢參數,請將 Query
的 include_in_schema
參數設定為 False
from typing import Annotated
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
hidden_query: Annotated[str | None, Query(include_in_schema=False)] = None,
):
if hidden_query:
return {"hidden_query": hidden_query}
else:
return {"hidden_query": "Not found"}
from typing import Annotated, Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
hidden_query: Annotated[Union[str, None], Query(include_in_schema=False)] = None,
):
if hidden_query:
return {"hidden_query": hidden_query}
else:
return {"hidden_query": "Not found"}
from typing import Union
from fastapi import FastAPI, Query
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/")
async def read_items(
hidden_query: Annotated[Union[str, None], Query(include_in_schema=False)] = None,
):
if hidden_query:
return {"hidden_query": hidden_query}
else:
return {"hidden_query": "Not found"}
提示
如果可能,建議使用 Annotated
版本。
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
hidden_query: str | None = Query(default=None, include_in_schema=False),
):
if hidden_query:
return {"hidden_query": hidden_query}
else:
return {"hidden_query": "Not found"}
提示
如果可能,建議使用 Annotated
版本。
from typing import Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
hidden_query: Union[str, None] = Query(default=None, include_in_schema=False),
):
if hidden_query:
return {"hidden_query": hidden_query}
else:
return {"hidden_query": "Not found"}
摘要¶
您可以為參數宣告額外的驗證和中繼資料。
通用驗證和中繼資料
alias(別名)
title(標題)
description(描述)
deprecated(已棄用)
字串特定的驗證
min_length(最小長度)
max_length(最大長度)
pattern(模式)
在這些範例中,您看到了如何宣告 str
(字串)值的驗證。
請參閱後續章節,了解如何宣告其他類型的驗證,例如數字。