Валидация параметров запроса FastAPI

FastAPI позволяет объявлять дополнительные правила валидации и метаданные для параметров запроса, такие как ограничения длины строки, сопоставление с регулярным выражением и т. д. С помощьюQueryиAnnotated, вы можете улучшить валидацию параметров, не изменяя логику функции.


Базовая валидация

В следующем примере используются параметры запросаqДобавить ограничение максимальной длины:

Пример

from typing import Annotated
from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    # Используйте Annotated + Query для добавления валидации
    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

Пояснение к коду:

ЧастьОписание
Annotated[str | None, ...]Аннотации типов, смыслqМожет быть строкой или None
Query(max_length=50)Правила валидации,qМаксимальная длина — 50 символов
= NoneЗначение по умолчанию, делающее параметр необязательным

FastAPI рекомендует использоватьAnnotatedОбъявлять ... способом, а не использоватьQueryв качестве значения. Потому чтоAnnotatedВ этом подходе значением по умолчанию функции является значение по умолчанию, что более интуитивно и лучше поддерживается редакторами и инструментами проверки типов.


Добавление валидации

Вы можете добавить несколько правил валидации:

Пример

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

Параметры валидации строки:

ПараметрTypeОписание
min_lengthintМинимальная длина
max_lengthintМаксимальная длина
patternstrСопоставление с регулярным выражением

Регулярное выражение^fixedquery$Значение:

  • ^-- Должно начинаться со следующих символов
  • fixedquery-- Значение должно точно совпадатьfixedquery
  • $-- Заканчивается здесь; другие символы не могут следовать.

Валидация со значениями по умолчанию

Вы можете задать и значение по умолчанию, и правила валидации для параметра запроса:

Пример

from typing import Annotated
from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    # Значение по умолчанию — "fixedquery", а минимальная длина — 3
    q: Annotated[str, Query(min_length=3)] = "fixedquery",
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

Значение по умолчанию любого типа (включая не-Noneзначение) сделает параметр необязательным. Без значения по умолчанию и безQuery(default=...)параметры обязательны.


Обязательный параметр

ИспользованиеQuery, если вы не объявляете значение по умолчанию, параметр является обязательным:

Пример

from typing import Annotated
from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    # Нет значения = None, поэтому q — обязательный параметр.
    q: Annotated[str, Query(min_length=3)],
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    results.update({"q": q})
    return results

Обязательный, но может быть None

Иногда нужно, чтобы клиент передал значение, но значение может бытьNone:

Пример

from typing import Annotated
from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    # Клиент должен предоставить параметр q, но значение может быть None
    q: Annotated[str | None, Query(min_length=3)],
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

Список параметров запроса / несколько значений

ИспользованиеQueryВы можете объявить параметры запроса, которые принимают несколько значений:

Пример

from typing import Annotated
from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    # q может появляться в URL несколько раз, и значения будут собраны в список
    q: Annotated[list[str] | None, Query()] = Отсутствует,
):
    query_items = {"q": q}
    return query_items

Перейдите по адресуhttp://127.0.0.1:8000/items/?q=foo&q=bar, возвращает:

{"q": ["foo", "bar"]}

Чтобы объявить тип какlistпараметры запроса, необходимо явно использоватьQuery(), иначе FastAPI интерпретирует это как тело запроса.


Объявление метаданных

QueryОн также поддерживает добавление метаданных к параметрам; эта информация будет отображаться в документации API:

Пример

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="Строка запроса, используемая для фильтрации товаров",  # Описание параметра
        min_length=3,
        max_length=50,
        alias="item-query",    # Псевдоним для имени параметра в URL
        deprecated=True,       # Пометить как устаревший
    )] = Отсутствует,
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

Описание параметра метаданных:

ПараметрОписаниеСценарий использования
aliasПсевдоним для имени параметра в URLИмя параметра содержит дефис (например,item-query), когда оно не является допустимым именем переменной Python
titleЗаголовок параметраОтображать заголовок параметра в документации
descriptionОписание параметраОтображать подробное описание параметра в документации
deprecatedПомечен как устаревшийПараметр по-прежнему можно использовать, но в документации он будет помечен как "deprecated".
include_in_schemaОтображать ли в документации APIУстановить какFalseСкрываемые параметры

Исключить параметры из OpenAPI

Если параметр запроса не должен отображаться в документации API:

Пример

from typing import Annotated
from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    # hidden_query не будет отображаться в документации API, но его всё ещё можно использовать
    hidden_query: Annotated[str | None, Query(include_in_schema=False)] = Отсутствует,
):
    if hidden_query:
        return {"hidden_query": hidden_query}
    return {"items": [{"item_id": "Foo"}]}

Итог

Ключевые моменты проверки параметров запроса:

  • ИспользованиеAnnotated + QueryОбъявление правил валидации (рекомендуемый подход)
  • Валидация строк:min_length、max_length、pattern
  • Без значения по умолчанию = обязательный параметр; со значением по умолчанию = необязательный параметр
  • aliasИспользуется для имён параметров в URL, которые не являются допустимыми именами переменных Python.
  • deprecated=TrueПометка устаревших параметров
  • Использованиеlist[str]Получение нескольких query-параметров с одним и тем же именем
Другие расширения