Zum Inhalt

Query-Parameter

Wenn Sie in ihrer Funktion Parameter deklarieren, die nicht Teil der Pfad-Parameter sind, dann werden diese automatisch als „Query“-Parameter interpretiert.

from fastapi import FastAPI

app = FastAPI()

fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]


@app.get("/items/")
async def read_item(skip: int = 0, limit: int = 10):
    return fake_items_db[skip : skip + limit]

Query-Parameter (Deutsch: Abfrage-Parameter) sind die Schlüssel-Wert-Paare, die nach dem ? in einer URL aufgelistet sind, getrennt durch &-Zeichen.

Zum Beispiel sind in der URL:

http://127.0.0.1:8000/items/?skip=0&limit=10

... die Query-Parameter:

  • skip: mit dem Wert 0
  • limit: mit dem Wert 10

Da sie Teil der URL sind, sind sie „naturgemäß“ Strings.

Aber wenn Sie sie mit Python-Typen deklarieren (im obigen Beispiel als int), werden sie zu diesem Typ konvertiert, und gegen diesen validiert.

Die gleichen Prozesse, die für Pfad-Parameter stattfinden, werden auch auf Query-Parameter angewendet:

  • Editor Unterstützung (natürlich)
  • „Parsen“ der Daten
  • Datenvalidierung
  • Automatische Dokumentation

Defaultwerte

Da Query-Parameter nicht ein festgelegter Teil des Pfades sind, können sie optional sein und Defaultwerte haben.

Im obigen Beispiel haben sie die Defaultwerte skip=0 und limit=10.

Wenn Sie also zur URL:

http://127.0.0.1:8000/items/

gehen, so ist das das gleiche wie die URL:

http://127.0.0.1:8000/items/?skip=0&limit=10

Aber wenn Sie zum Beispiel zu:

http://127.0.0.1:8000/items/?skip=20

gehen, werden die Parameter-Werte Ihrer Funktion sein:

  • skip=20: da Sie das in der URL gesetzt haben
  • limit=10: weil das der Defaultwert ist

Optionale Parameter

Auf die gleiche Weise können Sie optionale Query-Parameter deklarieren, indem Sie deren Defaultwert auf None setzen:

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_item(item_id: str, q: str | None = None):
    if q:
        return {"item_id": item_id, "q": q}
    return {"item_id": item_id}
🤓 Other versions and variants
from typing import Union

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_item(item_id: str, q: Union[str, None] = None):
    if q:
        return {"item_id": item_id, "q": q}
    return {"item_id": item_id}

In diesem Fall wird der Funktionsparameter q optional, und standardmäßig None sein.

Check

Beachten Sie auch, dass FastAPI intelligent genug ist, um zu erkennen, dass item_id ein Pfad-Parameter ist und q keiner, daher muss letzteres ein Query-Parameter sein.

Query-Parameter Typkonvertierung

Sie können auch bool-Typen deklarieren und sie werden konvertiert:

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_item(item_id: str, q: str | None = None, short: bool = False):
    item = {"item_id": item_id}
    if q:
        item.update({"q": q})
    if not short:
        item.update(
            {"description": "This is an amazing item that has a long description"}
        )
    return item
🤓 Other versions and variants
from typing import Union

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_item(item_id: str, q: Union[str, None] = None, short: bool = False):
    item = {"item_id": item_id}
    if q:
        item.update({"q": q})
    if not short:
        item.update(
            {"description": "This is an amazing item that has a long description"}
        )
    return item

Wenn Sie nun zu:

http://127.0.0.1:8000/items/foo?short=1

oder

http://127.0.0.1:8000/items/foo?short=True

oder

http://127.0.0.1:8000/items/foo?short=true

oder

http://127.0.0.1:8000/items/foo?short=on

oder

http://127.0.0.1:8000/items/foo?short=yes

gehen, oder zu irgendeiner anderen Variante der Groß-/Kleinschreibung (Alles groß, Anfangsbuchstabe groß, usw.), dann wird Ihre Funktion den Parameter short mit dem bool-Wert True sehen, ansonsten mit dem Wert False.

Mehrere Pfad- und Query-Parameter

Sie können mehrere Pfad-Parameter und Query-Parameter gleichzeitig deklarieren, FastAPI weiß, was welches ist.

Und Sie müssen sie auch nicht in einer spezifischen Reihenfolge deklarieren.

Parameter werden anhand ihres Namens erkannt:

from fastapi import FastAPI

app = FastAPI()


@app.get("/users/{user_id}/items/{item_id}")
async def read_user_item(
    user_id: int, item_id: str, q: str | None = None, short: bool = False
):
    item = {"item_id": item_id, "owner_id": user_id}
    if q:
        item.update({"q": q})
    if not short:
        item.update(
            {"description": "This is an amazing item that has a long description"}
        )
    return item
🤓 Other versions and variants
from typing import Union

from fastapi import FastAPI

app = FastAPI()


@app.get("/users/{user_id}/items/{item_id}")
async def read_user_item(
    user_id: int, item_id: str, q: Union[str, None] = None, short: bool = False
):
    item = {"item_id": item_id, "owner_id": user_id}
    if q:
        item.update({"q": q})
    if not short:
        item.update(
            {"description": "This is an amazing item that has a long description"}
        )
    return item

Erforderliche Query-Parameter

Wenn Sie einen Defaultwert für Nicht-Pfad-Parameter deklarieren (Bis jetzt haben wir nur Query-Parameter gesehen), dann ist der Parameter nicht erforderlich.

Wenn Sie keinen spezifischen Wert haben wollen, sondern der Parameter einfach optional sein soll, dann setzen Sie den Defaultwert auf None.

Aber wenn Sie wollen, dass ein Query-Parameter erforderlich ist, vergeben Sie einfach keinen Defaultwert:

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_user_item(item_id: str, needy: str):
    item = {"item_id": item_id, "needy": needy}
    return item

Hier ist needy ein erforderlicher Query-Parameter vom Typ str.

Wenn Sie in Ihrem Browser eine URL wie:

http://127.0.0.1:8000/items/foo-item

... öffnen, ohne den benötigten Parameter needy, dann erhalten Sie einen Fehler wie den folgenden:

{
  "detail": [
    {
      "type": "missing",
      "loc": [
        "query",
        "needy"
      ],
      "msg": "Field required",
      "input": null,
      "url": "https://errors.pydantic.dev/2.1/v/missing"
    }
  ]
}

Da needy ein erforderlicher Parameter ist, müssen Sie ihn in der URL setzen:

http://127.0.0.1:8000/items/foo-item?needy=sooooneedy

... Das funktioniert:

{
    "item_id": "foo-item",
    "needy": "sooooneedy"
}

Und natürlich können Sie einige Parameter als erforderlich, einige mit Defaultwert, und einige als vollständig optional definieren:

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_user_item(
    item_id: str, needy: str, skip: int = 0, limit: int | None = None
):
    item = {"item_id": item_id, "needy": needy, "skip": skip, "limit": limit}
    return item
🤓 Other versions and variants
from typing import Union

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_user_item(
    item_id: str, needy: str, skip: int = 0, limit: Union[int, None] = None
):
    item = {"item_id": item_id, "needy": needy, "skip": skip, "limit": limit}
    return item

In diesem Fall gibt es drei Query-Parameter:

  • needy, ein erforderlicher str.
  • skip, ein int mit einem Defaultwert 0.
  • limit, ein optionales int.

Tipp

Sie können auch Enums verwenden, auf die gleiche Weise wie mit Pfad-Parametern.