Перейти до змісту

Query Параметри

Коли Ви оголошуєте інші параметри функції, які не є частиною параметрів шляху, вони автоматично інтерпретуються як "query" параметри.

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 параметри — це набір пар ключ-значення, що йдуть після символу ? в URL, розділені символами &.

Наприклад, в URL:

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

...query параметрами є:

  • skip: зі значенням 0
  • limit: зі значенням 10

Оскільки вони є частиною URL, вони "за замовчуванням" є рядками.

Але коли Ви оголошуєте їх із типами Python (у наведеному прикладі як int), вони перетворюються на цей тип і проходять перевірку відповідності.

Увесь той самий процес, який застосовується до параметрів шляху, також застосовується до query параметрів:

  • Підтримка в редакторі (автодоповнення, перевірка помилок)
  • "Парсинг" даних
  • Валідація даних
  • Автоматична документація

Значення за замовчуванням

Оскільки query параметри не є фіксованою частиною шляху, вони можуть бути необов’язковими та мати значення за замовчуванням.

У наведеному вище прикладі вони мають значення за замовчуванням: skip=0 і limit=10.

Отже, результат переходу за URL:

http://127.0.0.1:8000/items/
буде таким самим, як і перехід за посиланням:

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

Але якщо Ви перейдете, наприклад, за посиланням:

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

Значення параметрів у вашій функції будуть такими:

  • skip=20: оскільки Ви вказали його в URL
  • limit=10: оскільки це значення за замовчуванням

Необов'язкові параметри

Аналогічно, Ви можете оголосити необов’язкові query параметри, встановивши для них значення за замовчуванням None:

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}

У цьому випадку параметр функції q буде необов’язковим і за замовчуванням матиме значення None.

Примітка

Також зверніть увагу, що FastAPI достатньо розумний, щоб визначити, що параметр шляху item_id є параметром шляху, а q — ні, отже, це query параметр.

Перетворення типу Query параметра

Ви також можете оголошувати параметри типу bool, і вони будуть автоматично конвертовані:

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

У цьому випадку, якщо Ви звернетесь до:

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

або

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

або

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

або

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

або

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

або будь-який інший варіант написання (великі літери, перша літера велика тощо), ваша функція побачить параметр short зі значенням True з типом даних bool. В іншому випадку – False.

Кілька path і query параметрів

Ви можете одночасно оголошувати кілька path і query параметрів, і FastAPI автоматично визначить, який з них до чого належить.

Не потрібно дотримуватись певного порядку їх оголошення.

Вони визначаються за назвою:

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

Обов’язкові Query параметри

Якщо Ви оголошуєте значення за замовчуванням для параметрів, які не є path-параметрами (у цьому розділі ми бачили поки що лише path параметри), тоді вони стають необов’язковими.

Якщо Ви не хочете вказувати конкретні значення, але хочете зробити параметр опціональним, задайте None як значення за замовчуванням.

Але якщо Ви хочете зробити query параметр обов’язковим, просто не вказуйте для нього значення за замовчуванням:

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

Тут needy – обов’язковий query параметр типу str.

Якщо Ви відкриєте у браузері URL-адресу:

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

...без додавання обов’язкового параметра needy, Ви побачите помилку:

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

Оскільки needy є обов’язковим параметром, вам потрібно вказати його в URL:

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

...цей запит поверне:

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

Звичайно, Ви можете визначити деякі параметри як обов’язкові, інші зі значенням за замовчуванням, а ще деякі — повністю опціональні:

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

У цьому випадку є 3 query параметри:

  • needy, обов’язковий str.
  • skip, int зі значенням за замовчуванням 0.
  • limit, опціональний int.

Підказка

Ви також можете використовувати Enum-и, так само як і з Path Parameters.