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

Моделі параметрів запиту

AI coding agents

Use the official FastAPI skill for your installed version. Install it from your project directory:

uvx library-skills

See Develop with AI.

🌐 Переклад ШІ та людьми

Цей переклад виконано ШІ під керівництвом людей. 🤝

Можливі помилки через неправильне розуміння початкового змісту або неприродні формулювання тощо. 🤖

Ви можете покращити цей переклад, допомігши нам краще спрямовувати AI LLM.

Англійська версія

Якщо у Вас є група параметрів запиту, які пов’язані між собою, Ви можете створити Pydantic-модель для їх оголошення.

Це дозволить Вам повторно використовувати модель у різних місцях, а також оголошувати перевірки та метадані для всіх параметрів одночасно. 😎

Примітка

Ця можливість підтримується, починаючи з версії FastAPI 0.115.0. 🤓

Параметри запиту з Pydantic-моделлю

Оголосіть параметри запиту, які Вам потрібні, у Pydantic-моделі, а потім оголосіть цей параметр як Query:

from typing import Annotated, Literal

from fastapi import FastAPI, Query
from pydantic import BaseModel, Field

app = FastAPI()


class FilterParams(BaseModel):
    limit: int = Field(100, gt=0, le=100)
    offset: int = Field(0, ge=0)
    order_by: Literal["created_at", "updated_at"] = "created_at"
    tags: list[str] = []


@app.get("/items/")
async def read_items(filter_query: Annotated[FilterParams, Query()]):
    return filter_query
🤓 Other versions and variants

Tip

Prefer to use the Annotated version if possible.

from typing import Literal

from fastapi import FastAPI, Query
from pydantic import BaseModel, Field

app = FastAPI()


class FilterParams(BaseModel):
    limit: int = Field(100, gt=0, le=100)
    offset: int = Field(0, ge=0)
    order_by: Literal["created_at", "updated_at"] = "created_at"
    tags: list[str] = []


@app.get("/items/")
async def read_items(filter_query: FilterParams = Query()):
    return filter_query

FastAPI буде витягувати дані для кожного поля з параметрів запиту у запиті та надавати Вам визначену вами Pydantic-модель.

Перевірте документацію

Ви можете побачити параметри запиту в UI документації за /docs:

Заборона зайвих параметрів запиту

У деяких особливих випадках (ймовірно, не дуже поширених) Ви можете захотіти обмежити параметри запиту, які дозволено отримувати.

Ви можете використати конфігурацію моделі Pydantic, щоб заборонити (forbid) будь-які зайві (extra) поля:

from typing import Annotated, Literal

from fastapi import FastAPI, Query
from pydantic import BaseModel, Field

app = FastAPI()


class FilterParams(BaseModel):
    model_config = {"extra": "forbid"}

    limit: int = Field(100, gt=0, le=100)
    offset: int = Field(0, ge=0)
    order_by: Literal["created_at", "updated_at"] = "created_at"
    tags: list[str] = []


@app.get("/items/")
async def read_items(filter_query: Annotated[FilterParams, Query()]):
    return filter_query
🤓 Other versions and variants

Tip

Prefer to use the Annotated version if possible.

from typing import Literal

from fastapi import FastAPI, Query
from pydantic import BaseModel, Field

app = FastAPI()


class FilterParams(BaseModel):
    model_config = {"extra": "forbid"}

    limit: int = Field(100, gt=0, le=100)
    offset: int = Field(0, ge=0)
    order_by: Literal["created_at", "updated_at"] = "created_at"
    tags: list[str] = []


@app.get("/items/")
async def read_items(filter_query: FilterParams = Query()):
    return filter_query

Якщо клієнт спробує надіслати зайві дані у параметрах запиту, він отримає відповідь з помилкою.

Наприклад, якщо клієнт спробує надіслати параметр запиту tool зі значенням plumbus, як у цьому запиті:

https://example.com/items/?limit=10&tool=plumbus

Він отримає відповідь з помилкою, яка повідомить, що параметр запиту tool не дозволено:

{
    "detail": [
        {
            "type": "extra_forbidden",
            "loc": ["query", "tool"],
            "msg": "Extra inputs are not permitted",
            "input": "plumbus"
        }
    ]
}

Поєднання моделей параметрів

Ви можете оголосити кілька моделей параметрів запиту та поєднати їх з окремими параметрами запиту або залежностями.

from typing import Annotated

from fastapi import FastAPI, Query
from pydantic import BaseModel, Field

app = FastAPI()


class Pagination(BaseModel):
    limit: int = Field(10, ge=1)
    offset: int = Field(0, ge=0)


class Filters(BaseModel):
    tags: list[str] = []


@app.get("/items/")
def read_items(
    pagination: Annotated[Pagination, Query()],
    filters: Annotated[Filters, Query()],
    search: str | None = None,
):
    return {"pagination": pagination, "filters": filters, "search": search}
🤓 Other versions and variants

Tip

Prefer to use the Annotated version if possible.

from fastapi import FastAPI, Query
from pydantic import BaseModel, Field

app = FastAPI()


class Pagination(BaseModel):
    limit: int = Field(10, ge=1)
    offset: int = Field(0, ge=0)


class Filters(BaseModel):
    tags: list[str] = []


@app.get("/items/")
def read_items(
    pagination: Pagination = Query(),
    filters: Filters = Query(),
    search: str | None = None,
):
    return {"pagination": pagination, "filters": filters, "search": search}

Параметри запиту залишаються на одному рівні.

https://example.com/items/?limit=5&offset=10&tags=red&tags=blue&search=shirt

У строці запиту немає ключів pagination або filters. Кожна модель перевіряє параметри запиту незалежно, зі своїми значеннями за замовчуванням, валідаторами полів і валідаторами моделі. Те саме стосується моделей або окремих параметрів, оголошених у залежностях.

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

Конфігурація extra кожної моделі застосовується до всіх параметрів запиту, зокрема оголошених в інших моделях або залежностях. З extra="forbid" будь-який параметр поза цією моделлю відхиляється. З extra="allow" ці параметри включаються як додаткові дані моделі.

Це також працює для моделей Header і Cookie.

Необов’язкові моделі параметрів запиту

Оголосіть модель параметрів запиту з | None і значенням за замовчуванням None, щоб зробити групу необов’язковою.

from datetime import date
from typing import Annotated

from fastapi import FastAPI, Query
from pydantic import BaseModel

app = FastAPI()


class DateRange(BaseModel):
    start: date
    end: date


@app.get("/items/")
async def read_items(
    limit: int = 10,
    date_range: Annotated[DateRange | None, Query()] = None,
):
    return {"limit": limit, "date_range": date_range}
🤓 Other versions and variants

Tip

Prefer to use the Annotated version if possible.

from datetime import date

from fastapi import FastAPI, Query
from pydantic import BaseModel

app = FastAPI()


class DateRange(BaseModel):
    start: date
    end: date


@app.get("/items/")
async def read_items(
    limit: int = 10,
    date_range: DateRange | None = Query(default=None),
):
    return {"limit": limit, "date_range": date_range}

Якщо не надіслано ні start, ні end, значення date_range буде None. Якщо надіслано будь-який із них, FastAPI перевіряє модель і вимагає обидва поля.

Використання | None без значення за замовчуванням залишає параметр обов’язковим.

Додаткові параметри обробляються відповідно до конфігурації extra моделі. Ігноровані додаткові параметри не роблять модель присутньою.

OpenAPI перелічує поля групи окремо та позначає їх як необов’язкові.

Ви також можете оголосити необов’язкові моделі параметрів заголовків і моделі параметрів кукі.

Підсумок

Ви можете використовувати Pydantic-моделі для оголошення параметрів запиту у FastAPI. 😎

Порада

Спойлер: Ви також можете використовувати Pydantic-моделі для оголошення кукі та заголовків, але про це Ви дізнаєтеся пізніше в цьому навчальному посібнику. 🤫