Query-Parameter und String-Validierungen¶
FastAPI ermöglicht es Ihnen, zusĂ€tzliche Informationen und Validierungen fĂŒr Ihre Parameter zu deklarieren.
Nehmen wir diese Anwendung als Beispiel:
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
đ€ Other versions and variants
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
Der Query-Parameter q hat den Typ str | None, das bedeutet, dass er vom Typ str sein kann, aber auch None, und tatsĂ€chlich ist der Defaultwert None, sodass FastAPI weiĂ, dass er nicht erforderlich ist.
Hinweis
FastAPI erkennt, dass der Wert von q nicht erforderlich ist, aufgrund des Defaultwertes = None.
Die Verwendung von str | None ermöglicht es Ihrem Editor, Ihnen bessere UnterstĂŒtzung zu bieten und Fehler zu erkennen.
ZusĂ€tzliche Validierung¶
Wir werden sicherstellen, dass, obwohl q optional ist, wann immer es bereitgestellt wird, seine LĂ€nge 50 Zeichen nicht ĂŒberschreitet.
Query und Annotated importieren¶
Um dies zu erreichen, importieren Sie zuerst:
QueryvonfastapiAnnotatedvontyping
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
đ€ Other versions and variants
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(max_length=50)] = None):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
Tip
Prefer to use the Annotated version if possible.
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
Tip
Prefer to use the Annotated version if possible.
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
Info
FastAPI hat UnterstĂŒtzung fĂŒr Annotated hinzugefĂŒgt (und begonnen, es zu empfehlen) in der Version 0.95.0.
Wenn Sie eine Ă€ltere Version haben, wĂŒrden Sie Fehler erhalten, beim Versuch, Annotated zu verwenden.
Stellen Sie sicher, dass Sie die FastAPI-Version aktualisieren, auf mindestens Version 0.95.1, bevor Sie Annotated verwenden.
Verwenden von Annotated im Typ fĂŒr den q-Parameter¶
Erinnern Sie sich, dass ich Ihnen zuvor in Python-Typen-Intro gesagt habe, dass Annotated verwendet werden kann, um Metadaten zu Ihren Parametern hinzuzufĂŒgen?
Jetzt ist es soweit, dies mit FastAPI zu verwenden. đ
Wir hatten diese Typannotation:
q: str | None = None
q: Union[str, None] = None
Was wir tun werden, ist, dies mit Annotated zu wrappen, sodass es zu:
q: Annotated[str | None] = None
q: Annotated[Union[str, None]] = None
Beide dieser Versionen bedeuten dasselbe: q ist ein Parameter, der ein str oder None sein kann, und standardmĂ€Ăig ist er None.
Jetzt springen wir zu den spannenden Dingen. đ
Query zu Annotated im q-Parameter hinzufĂŒgen¶
Da wir nun Annotated haben, in das wir mehr Informationen (in diesem Fall einige zusĂ€tzliche Validierungen) einfĂŒgen können, fĂŒgen Sie Query innerhalb von Annotated hinzu und setzen Sie den Parameter max_length auf 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
đ€ Other versions and variants
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(max_length=50)] = None):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
Tip
Prefer to use the Annotated version if possible.
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
Tip
Prefer to use the Annotated version if possible.
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
Beachten Sie, dass der Defaultwert weiterhin None ist, so dass der Parameter weiterhin optional ist.
Aber jetzt, mit Query(max_length=50) innerhalb von Annotated, sagen wir FastAPI, dass wir eine zusĂ€tzliche Validierung fĂŒr diesen Wert wĂŒnschen, wir wollen, dass er maximal 50 Zeichen hat. đ
Tipp
Hier verwenden wir Query(), weil dies ein Query-Parameter ist. SpÀter werden wir andere wie Path(), Body(), Header(), und Cookie() sehen, die auch dieselben Argumente wie Query() akzeptieren.
FastAPI wird nun:
- Die Daten validieren, um sicherzustellen, dass die LÀnge maximal 50 Zeichen betrÀgt
- Einen klaren Fehler fĂŒr den Client anzeigen, wenn die Daten ungĂŒltig sind
- Den Parameter in der OpenAPI-Schema-Pfadoperation dokumentieren (sodass er in der automatischen Dokumentation angezeigt wird)
Alternative (alt): Query als Defaultwert¶
FrĂŒhere Versionen von FastAPI (vor 0.95.0) erforderten, dass Sie Query als den Defaultwert Ihres Parameters verwendeten, anstatt es innerhalb von Annotated zu platzieren. Es besteht eine hohe Wahrscheinlichkeit, dass Sie Code sehen, der es so verwendet, also werde ich es Ihnen erklĂ€ren.
Tipp
FĂŒr neuen Code und wann immer es möglich ist, verwenden Sie Annotated wie oben erklĂ€rt. Es gibt mehrere Vorteile (unten erlĂ€utert) und keine Nachteile. đ°
So wĂŒrden Sie Query() als den Defaultwert Ihres Funktionsparameters verwenden und den Parameter max_length auf 50 setzen:
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
đ€ Other versions and variants
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 Annotated, Union
from fastapi import FastAPI, Query
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
Tip
Prefer to use the Annotated version if possible.
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
Da wir in diesem Fall (ohne die Verwendung von Annotated) den Defaultwert None in der Funktion durch Query() ersetzen mĂŒssen, mĂŒssen wir nun den Defaultwert mit dem Parameter Query(default=None) setzen, er erfĂŒllt den gleichen Zweck, diesen Defaultwert zu definieren (zumindest fĂŒr FastAPI).
Also:
q: str | None = Query(default=None)
... macht den Parameter optional mit einem Defaultwert von None, genauso wie:
q: str | None = None
Aber die Query-Version deklariert ihn explizit als Query-Parameter.
Dann können wir mehr Parameter an Query ĂŒbergeben. In diesem Fall den max_length-Parameter, der auf Strings angewendet wird:
q: str | None = Query(default=None, max_length=50)
Dies wird die Daten validieren, einen klaren Fehler anzeigen, wenn die Daten nicht gĂŒltig sind, und den Parameter in der OpenAPI-Schema-Pfadoperation dokumentieren.
Query als Defaultwert oder in Annotated¶
Beachten Sie, dass wenn Sie Query innerhalb von Annotated verwenden, Sie den default-Parameter fĂŒr Query nicht verwenden dĂŒrfen.
Setzen Sie stattdessen den tatsÀchlichen Defaultwert des Funktionsparameters. Andernfalls wÀre es inkonsistent.
Zum Beispiel ist das nicht erlaubt:
q: Annotated[str, Query(default="rick")] = "morty"
... denn es ist nicht klar, ob der Defaultwert "rick" oder "morty" sein soll.
Sie wĂŒrden also (bevorzugt) schreiben:
q: Annotated[str, Query()] = "rick"
... oder in Àlteren Codebasen finden Sie:
q: str = Query(default="rick")
VorzĂŒge von Annotated¶
Es wird empfohlen, Annotated zu verwenden, anstelle des Defaultwertes in Funktionsparametern, es ist aus mehreren GrĂŒnden besser. đ€
Der Defaultwert des Funktionsparameters ist der tatsĂ€chliche Defaultwert, das ist in der Regel intuitiver mit Python. đ
Sie könnten diese gleiche Funktion in anderen Stellen ohne FastAPI aufrufen, und es wĂŒrde wie erwartet funktionieren. Wenn es einen erforderlichen Parameter gibt (ohne Defaultwert), wird Ihr Editor Ihnen dies mit einem Fehler mitteilen, auĂerdem wird Python sich beschweren, wenn Sie es ausfĂŒhren, ohne den erforderlichen Parameter zu ĂŒbergeben.
Wenn Sie Annotated nicht verwenden und stattdessen die (alte) Defaultwert-Stilform verwenden, mĂŒssen Sie sich daran erinnern, die Argumente der Funktion zu ĂŒbergeben, wenn Sie diese Funktion ohne FastAPI in anderen Stellen aufrufen. Ansonsten sind die Werte anders als erwartet (z. B. QueryInfo oder etwas Ăhnliches statt str). Ihr Editor kann Ihnen nicht helfen, und Python wird die Funktion ohne Klagen ausfĂŒhren und sich nur beschweren wenn die Operationen innerhalb auf einen Fehler stoĂen.
Da Annotated mehr als eine Metadaten-Annotation haben kann, könnten Sie dieselbe Funktion sogar mit anderen Tools verwenden, wie z. B. Typer. đ
Mehr Validierungen hinzufĂŒgen¶
Sie können auch einen min_length-Parameter hinzufĂŒgen:
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
đ€ Other versions and variants
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
Tip
Prefer to use the Annotated version if possible.
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
Tip
Prefer to use the Annotated version if possible.
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
RegulĂ€re AusdrĂŒcke hinzufĂŒgen¶
Sie können einen regulĂ€ren Ausdruck pattern definieren, mit dem der Parameter ĂŒbereinstimmen muss:
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
đ€ Other versions and variants
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
Tip
Prefer to use the Annotated version if possible.
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
Tip
Prefer to use the Annotated version if possible.
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
Dieses spezielle Suchmuster im regulĂ€ren Ausdruck ĂŒberprĂŒft, dass der erhaltene Parameterwert:
^: mit den nachfolgenden Zeichen beginnt, keine Zeichen davor hat.fixedquery: den exakten Textfixedqueryhat.$: dort endet, keine weiteren Zeichen nachfixedqueryhat.
Wenn Sie sich mit all diesen âregulĂ€rer Ausdruckâ-Ideen verloren fĂŒhlen, keine Sorge. Sie sind ein schwieriges Thema fĂŒr viele Menschen. Sie können noch viele Dinge tun, ohne regulĂ€re AusdrĂŒcke direkt zu benötigen.
Aber nun wissen Sie, dass Sie sie in FastAPI immer dann verwenden können, wenn Sie sie brauchen.
Defaultwerte¶
NatĂŒrlich können Sie Defaultwerte verwenden, die nicht None sind.
Nehmen wir an, Sie möchten, dass der q Query-Parameter eine min_length von 3 hat und einen Defaultwert von "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
đ€ Other versions and variants
Tip
Prefer to use the Annotated version if possible.
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
Hinweis
Ein Defaultwert irgendeines Typs, einschlieĂlich None, macht den Parameter optional (nicht erforderlich).
Erforderliche Parameter¶
Wenn wir keine weiteren Validierungen oder Metadaten deklarieren mĂŒssen, können wir den q Query-Parameter erforderlich machen, indem wir einfach keinen Defaultwert deklarieren, wie:
q: str
statt:
q: str | None = None
Aber jetzt deklarieren wir es mit Query, zum Beispiel so:
q: Annotated[str | None, Query(min_length=3)] = None
Wenn Sie einen Wert als erforderlich deklarieren mĂŒssen, wĂ€hrend Sie Query verwenden, deklarieren Sie einfach keinen Defaultwert:
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
đ€ Other versions and variants
Tip
Prefer to use the Annotated version if possible.
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
Erforderlich, kann None sein¶
Sie können deklarieren, dass ein Parameter None akzeptieren kann, aber trotzdem erforderlich ist. Dadurch mĂŒssten Clients den Wert senden, selbst wenn der Wert None ist.
Um das zu tun, können Sie deklarieren, dass None ein gĂŒltiger Typ ist, einfach indem Sie keinen Defaultwert deklarieren:
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
đ€ Other versions and variants
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
Tip
Prefer to use the Annotated version if possible.
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: str | None = Query(min_length=3)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
Tip
Prefer to use the Annotated version if possible.
from typing import Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Union[str, None] = Query(min_length=3)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
Query-Parameter-Liste / Mehrere Werte¶
Wenn Sie einen Query-Parameter explizit mit Query definieren, können Sie ihn auch so deklarieren, dass er eine Liste von Werten empfÀngt, oder anders gesagt, dass er mehrere Werte empfangen kann.
Um zum Beispiel einen Query-Parameter q zu deklarieren, der mehrmals in der URL vorkommen kann, schreiben Sie:
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
đ€ Other versions and variants
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
Tip
Prefer to use the Annotated version if possible.
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
Tip
Prefer to use the Annotated version if possible.
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
Dann, mit einer URL wie:
http://localhost:8000/items/?q=foo&q=bar
wĂŒrden Sie die mehreren q-Query-Parameter-Werte (foo und bar) in einer Python-list in Ihrer Pfadoperation-Funktion im Funktionsparameter q erhalten.
So wÀre die Response zu dieser URL:
{
"q": [
"foo",
"bar"
]
}
Tipp
Um einen Query-Parameter mit einem Typ list zu deklarieren, wie im obigen Beispiel, mĂŒssen Sie explizit Query verwenden, da er andernfalls als Requestbody interpretiert wĂŒrde.
Die interaktive API-Dokumentation wird entsprechend aktualisiert, um mehrere Werte zu erlauben:

Query-Parameter-Liste / Mehrere Werte mit Defaults¶
Sie können auch eine Default-list von Werten definieren, wenn keine bereitgestellt werden:
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
đ€ Other versions and variants
Tip
Prefer to use the Annotated version if possible.
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
Wenn Sie zu:
http://localhost:8000/items/
gehen, wird der Default fĂŒr q sein: ["foo", "bar"], und Ihre Response wird sein:
{
"q": [
"foo",
"bar"
]
}
Nur list verwenden¶
Sie können auch list direkt verwenden, anstelle von 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
đ€ Other versions and variants
Tip
Prefer to use the Annotated version if possible.
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
Hinweis
Beachten Sie, dass FastAPI in diesem Fall den Inhalt der Liste nicht ĂŒberprĂŒft.
Zum Beispiel wĂŒrde list[int] ĂŒberprĂŒfen (und dokumentieren), dass der Inhalt der Liste Ganzzahlen sind. Aber list alleine wĂŒrde das nicht.
Mehr Metadaten deklarieren¶
Sie können mehr Informationen ĂŒber den Parameter hinzufĂŒgen.
Diese Informationen werden in das generierte OpenAPI aufgenommen und von den DokumentationsoberflÀchen und externen Tools verwendet.
Hinweis
Beachten Sie, dass verschiedene Tools möglicherweise unterschiedliche UnterstĂŒtzungslevels fĂŒr OpenAPI haben.
Einige davon könnten noch nicht alle zusÀtzlichen Informationen anzuzeigen, die Sie erklÀrten, obwohl in den meisten FÀllen die fehlende FunktionalitÀt bereits in der Entwicklung geplant ist.
Sie können einen title hinzufĂŒgen:
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
đ€ Other versions and variants
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
Tip
Prefer to use the Annotated version if possible.
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
Tip
Prefer to use the Annotated version if possible.
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
Und eine 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
đ€ Other versions and variants
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
Tip
Prefer to use the Annotated version if possible.
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
Tip
Prefer to use the Annotated version if possible.
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
Alias-Parameter¶
Stellen Sie sich vor, Sie möchten, dass der Parameter item-query ist.
Wie in:
http://127.0.0.1:8000/items/?item-query=foobaritems
Aber item-query ist kein gĂŒltiger Name fĂŒr eine Variable in Python.
Der am Àhnlichsten wÀre item_query.
Aber Sie benötigen dennoch, dass er genau item-query ist ...
Dann können Sie ein alias deklarieren, und dieser Alias wird verwendet, um den Parameterwert zu finden:
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
đ€ Other versions and variants
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
Tip
Prefer to use the Annotated version if possible.
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
Tip
Prefer to use the Annotated version if possible.
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
Parameter als deprecatet ausweisen¶
Nehmen wir an, Ihnen gefÀllt dieser Parameter nicht mehr.
Sie mĂŒssen ihn eine Weile dort belassen, da es Clients gibt, die ihn verwenden, aber Sie möchten, dass die Dokumentation ihn klar als deprecatet anzeigt.
Dann ĂŒbergeben Sie den Parameter deprecated=True an 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
đ€ Other versions and variants
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
Tip
Prefer to use the Annotated version if possible.
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
Tip
Prefer to use the Annotated version if possible.
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
Die Dokumentation wird es so anzeigen:

Parameter von OpenAPI ausschlieĂen¶
Um einen Query-Parameter aus dem generierten OpenAPI-Schema auszuschlieĂen (und somit aus den automatischen Dokumentationssystemen), setzen Sie den Parameter include_in_schema von Query auf 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"}
đ€ Other versions and variants
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"}
Tip
Prefer to use the Annotated version if possible.
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"}
Tip
Prefer to use the Annotated version if possible.
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"}
Benutzerdefinierte Validierung¶
Es kann FĂ€lle geben, in denen Sie eine benutzerdefinierte Validierung durchfĂŒhren mĂŒssen, die nicht mit den oben gezeigten Parametern durchgefĂŒhrt werden kann.
In diesen FÀllen können Sie eine benutzerdefinierte Validierungsfunktion verwenden, die nach der normalen Validierung angewendet wird (z. B. nach der Validierung, dass der Wert ein str ist).
Sie können dies mit Pydantic's AfterValidator innerhalb von Annotated erreichen.
Tipp
Pydantic unterstĂŒtzt auch BeforeValidator und andere. đ€
Zum Beispiel ĂŒberprĂŒft dieser benutzerdefinierte Validator, ob die Artikel-ID mit isbn- fĂŒr eine ISBN-Buchnummer oder mit imdb- fĂŒr eine IMDB-Film-URL-ID beginnt:
import random
from typing import Annotated
from fastapi import FastAPI
from pydantic import AfterValidator
app = FastAPI()
data = {
"isbn-9781529046137": "The Hitchhiker's Guide to the Galaxy",
"imdb-tt0371724": "The Hitchhiker's Guide to the Galaxy",
"isbn-9781439512982": "Isaac Asimov: The Complete Stories, Vol. 2",
}
def check_valid_id(id: str):
if not id.startswith(("isbn-", "imdb-")):
raise ValueError('Invalid ID format, it must start with "isbn-" or "imdb-"')
return id
@app.get("/items/")
async def read_items(
id: Annotated[str | None, AfterValidator(check_valid_id)] = None,
):
if id:
item = data.get(id)
else:
id, item = random.choice(list(data.items()))
return {"id": id, "name": item}
đ€ Other versions and variants
import random
from typing import Annotated, Union
from fastapi import FastAPI
from pydantic import AfterValidator
app = FastAPI()
data = {
"isbn-9781529046137": "The Hitchhiker's Guide to the Galaxy",
"imdb-tt0371724": "The Hitchhiker's Guide to the Galaxy",
"isbn-9781439512982": "Isaac Asimov: The Complete Stories, Vol. 2",
}
def check_valid_id(id: str):
if not id.startswith(("isbn-", "imdb-")):
raise ValueError('Invalid ID format, it must start with "isbn-" or "imdb-"')
return id
@app.get("/items/")
async def read_items(
id: Annotated[Union[str, None], AfterValidator(check_valid_id)] = None,
):
if id:
item = data.get(id)
else:
id, item = random.choice(list(data.items()))
return {"id": id, "name": item}
Info
Dies ist verfĂŒgbar seit Pydantic Version 2 oder höher. đ
Tipp
Wenn Sie irgendeine Art von Validierung durchfĂŒhren mĂŒssen, die eine Kommunikation mit einer externen Komponente erfordert, wie z. B. einer Datenbank oder einer anderen API, sollten Sie stattdessen FastAPI-AbhĂ€ngigkeiten verwenden. Sie werden diese spĂ€ter kennenlernen.
Diese benutzerdefinierten Validatoren sind fĂŒr Dinge gedacht, die einfach mit denselben Daten ĂŒberprĂŒft werden können, die im Request bereitgestellt werden.
Dieses Codebeispiel verstehen¶
Der wichtige Punkt ist einfach die Verwendung von AfterValidator mit einer Funktion innerhalb von Annotated. FĂŒhlen Sie sich frei, diesen Teil zu ĂŒberspringen. đ€ž
Aber wenn Sie neugierig auf dieses spezielle Codebeispiel sind und immer noch Spaà haben, hier sind einige zusÀtzliche Details.
Zeichenkette mit value.startswith()¶
Haben Sie bemerkt? Eine Zeichenkette mit value.startswith() kann ein Tuple ĂŒbernehmen, und es wird jeden Wert im Tuple ĂŒberprĂŒfen:
# Code above omitted đ
def check_valid_id(id: str):
if not id.startswith(("isbn-", "imdb-")):
raise ValueError('Invalid ID format, it must start with "isbn-" or "imdb-"')
return id
# Code below omitted đ
đ Full file preview
import random
from typing import Annotated
from fastapi import FastAPI
from pydantic import AfterValidator
app = FastAPI()
data = {
"isbn-9781529046137": "The Hitchhiker's Guide to the Galaxy",
"imdb-tt0371724": "The Hitchhiker's Guide to the Galaxy",
"isbn-9781439512982": "Isaac Asimov: The Complete Stories, Vol. 2",
}
def check_valid_id(id: str):
if not id.startswith(("isbn-", "imdb-")):
raise ValueError('Invalid ID format, it must start with "isbn-" or "imdb-"')
return id
@app.get("/items/")
async def read_items(
id: Annotated[str | None, AfterValidator(check_valid_id)] = None,
):
if id:
item = data.get(id)
else:
id, item = random.choice(list(data.items()))
return {"id": id, "name": item}
đ€ Other versions and variants
import random
from typing import Annotated, Union
from fastapi import FastAPI
from pydantic import AfterValidator
app = FastAPI()
data = {
"isbn-9781529046137": "The Hitchhiker's Guide to the Galaxy",
"imdb-tt0371724": "The Hitchhiker's Guide to the Galaxy",
"isbn-9781439512982": "Isaac Asimov: The Complete Stories, Vol. 2",
}
def check_valid_id(id: str):
if not id.startswith(("isbn-", "imdb-")):
raise ValueError('Invalid ID format, it must start with "isbn-" or "imdb-"')
return id
@app.get("/items/")
async def read_items(
id: Annotated[Union[str, None], AfterValidator(check_valid_id)] = None,
):
if id:
item = data.get(id)
else:
id, item = random.choice(list(data.items()))
return {"id": id, "name": item}
Ein zufĂ€lliges Item¶
Mit data.items() erhalten wir ein iterierbares Objekt mit Tupeln, die SchlĂŒssel und Wert fĂŒr jedes Dictionary-Element enthalten.
Wir konvertieren dieses iterierbare Objekt mit list(data.items()) in eine richtige list.
Dann können wir mit random.choice() einen zufÀlligen Wert aus der Liste erhalten, also bekommen wir ein Tuple mit (id, name). Es wird etwas wie ("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy") sein.
Dann weisen wir diese beiden Werte des Tupels den Variablen id und name zu.
Wenn der Benutzer also keine Artikel-ID bereitgestellt hat, erhÀlt er trotzdem einen zufÀlligen Vorschlag.
... wir tun all dies in einer einzelnen einfachen Zeile. đ€Ż Lieben Sie nicht auch Python? đ
# Code above omitted đ
@app.get("/items/")
async def read_items(
id: Annotated[str | None, AfterValidator(check_valid_id)] = None,
):
if id:
item = data.get(id)
else:
id, item = random.choice(list(data.items()))
return {"id": id, "name": item}
đ Full file preview
import random
from typing import Annotated
from fastapi import FastAPI
from pydantic import AfterValidator
app = FastAPI()
data = {
"isbn-9781529046137": "The Hitchhiker's Guide to the Galaxy",
"imdb-tt0371724": "The Hitchhiker's Guide to the Galaxy",
"isbn-9781439512982": "Isaac Asimov: The Complete Stories, Vol. 2",
}
def check_valid_id(id: str):
if not id.startswith(("isbn-", "imdb-")):
raise ValueError('Invalid ID format, it must start with "isbn-" or "imdb-"')
return id
@app.get("/items/")
async def read_items(
id: Annotated[str | None, AfterValidator(check_valid_id)] = None,
):
if id:
item = data.get(id)
else:
id, item = random.choice(list(data.items()))
return {"id": id, "name": item}
đ€ Other versions and variants
import random
from typing import Annotated, Union
from fastapi import FastAPI
from pydantic import AfterValidator
app = FastAPI()
data = {
"isbn-9781529046137": "The Hitchhiker's Guide to the Galaxy",
"imdb-tt0371724": "The Hitchhiker's Guide to the Galaxy",
"isbn-9781439512982": "Isaac Asimov: The Complete Stories, Vol. 2",
}
def check_valid_id(id: str):
if not id.startswith(("isbn-", "imdb-")):
raise ValueError('Invalid ID format, it must start with "isbn-" or "imdb-"')
return id
@app.get("/items/")
async def read_items(
id: Annotated[Union[str, None], AfterValidator(check_valid_id)] = None,
):
if id:
item = data.get(id)
else:
id, item = random.choice(list(data.items()))
return {"id": id, "name": item}
Zusammenfassung¶
Sie können zusĂ€tzliche Validierungen und Metadaten fĂŒr Ihre Parameter deklarieren.
Allgemeine Validierungen und Metadaten:
aliastitledescriptiondeprecated
Validierungen, die spezifisch fĂŒr Strings sind:
min_lengthmax_lengthpattern
Benutzerdefinierte Validierungen mit AfterValidator.
In diesen Beispielen haben Sie gesehen, wie Sie Validierungen fĂŒr str-Werte deklarieren.
Sehen Sie sich die nĂ€chsten Kapitel an, um zu erfahren, wie Sie Validierungen fĂŒr andere Typen, wie z. B. Zahlen, deklarieren.