FastAPI + Pydantic: валидация данных
2025-07-07

FastAPI + Pydantic: валидация данных

Читайте также:

Pydantic — это библиотека для валидации и сериализации данных на Python, которая лежит в основе FastAPI. Благодаря Pydantic, FastAPI обеспечивает строгую проверку входных и выходных данных, автоматическую генерацию документации и удобную работу с типами данных. Это позволяет разработчикам сосредоточиться на бизнес-логике, не тратя время на ручную обработку ошибок и проверку формата данных.

В этой статье мы подробно рассмотрим, как использовать Pydantic для валидации данных в FastAPI, приведём практические примеры, разберём типичные ошибки и дадим советы по лучшим практикам.

1. Почему Pydantic?

Pydantic стал стандартом де-факто для валидации данных в современных Python-проектах благодаря следующим преимуществам:

  • Строгая типизация — все данные валидируются согласно аннотациям типов Python. Это снижает количество ошибок на этапе выполнения и делает код более предсказуемым.
  • Автоматическая генерация схем — FastAPI использует Pydantic для создания OpenAPI схем и документации, что облегчает интеграцию с фронтендом и мобильными приложениями.
  • Удобство — минимум кода для описания даже сложных структур данных. Модели легко читаются и поддерживаются.
  • Гибкость — поддержка вложенных моделей, списков, валидации по кастомным правилам, а также возможность расширять стандартные механизмы.

2. Базовый пример: валидация входных данных

Рассмотрим простой пример, где мы ожидаем от пользователя данные для регистрации. Вся структура и ограничения описываются через Pydantic-модель:

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class User(BaseModel):
    username: str
    age: int
    email: str

@app.post("/users/")
def create_user(user: User):
    return user

Пояснения:

  • Класс User наследуется от BaseModel и определяет структуру ожидаемых данных. Все поля обязательны, и их типы строго проверяются.
  • Когда клиент отправляет POST-запрос на /users/, FastAPI автоматически преобразует JSON в объект User и валидирует его. Если, например, поле age будет строкой, а не числом, или если не будет передан email, сервер вернёт ошибку 422 с подробным описанием проблемы.
  • Такой подход избавляет от необходимости вручную проверять каждое поле и писать обработку ошибок — всё это делает Pydantic.

3. Валидация с помощью дополнительных параметров

Pydantic позволяет не только указывать типы, но и задавать дополнительные ограничения для каждого поля. Это делается с помощью функции Field и специальных типов:

from pydantic import BaseModel, Field, EmailStr

class User(BaseModel):
    username: str = Field(..., min_length=3, max_length=50)
    age: int = Field(..., ge=18, le=120)
    email: EmailStr

Пояснения:

  • username должен быть строкой длиной от 3 до 50 символов. Если длина не соответствует, клиент получит ошибку с пояснением.
  • age — целое число от 18 до 120. Это удобно для проверки возраста пользователей, чтобы, например, не допустить регистрацию несовершеннолетних.
  • email — специальный тип EmailStr из Pydantic, который автоматически проверяет, что строка соответствует формату email-адреса.
  • Все ограничения и типы автоматически отображаются в Swagger UI, что облегчает тестирование и интеграцию.

4. Вложенные модели и списки

В реальных приложениях часто требуется описывать более сложные структуры данных, например, список адресов пользователя. Pydantic позволяет легко реализовать вложенные модели и списки:

from typing import List
from pydantic import BaseModel

class Address(BaseModel):
    city: str
    street: str

class User(BaseModel):
    username: str
    addresses: List[Address]

Пояснения:

  • Модель Address описывает отдельный адрес с двумя строковыми полями.
  • В модели User поле addresses — это список объектов Address. FastAPI и Pydantic автоматически проверят, что каждый элемент списка соответствует описанной структуре.
  • Такой подход позволяет строить сложные иерархии данных, не теряя в читаемости и надёжности.

5. Кастомная валидация через методы и декораторы

Иногда стандартных ограничений недостаточно, и требуется реализовать собственные правила проверки. Для этого в Pydantic используются декораторы @validator:

from pydantic import BaseModel, validator

class User(BaseModel):
    username: str
    age: int

    @validator('age')
    def age_must_be_adult(cls, v):
        if v < 18:
            raise ValueError('Пользователь должен быть совершеннолетним')
        return v

Пояснения:

  • Метод с декоратором @validator('age') будет вызван для проверки значения поля age.
  • Если возраст меньше 18, выбрасывается исключение с понятным сообщением. FastAPI преобразует это в ошибку 422 с этим текстом.
  • Кастомные валидаторы можно использовать для проверки уникальности, сложных зависимостей между полями, форматов и т.д.

6. Валидация query и path параметров

FastAPI позволяет валидировать не только тело запроса, но и параметры пути (path) и строки запроса (query). Это удобно для фильтрации, пагинации и других задач:

from fastapi import Query, Path, FastAPI

app = FastAPI()

@app.get("/items/{item_id}")
def read_item(item_id: int = Path(..., ge=1), q: str = Query(None, min_length=3)):
    return {"item_id": item_id, "q": q}

Пояснения:

  • item_id — параметр пути, который должен быть целым числом не меньше 1. Если передать 0 или отрицательное число, будет возвращена ошибка.
  • q — необязательный query-параметр, который должен быть строкой длиной не менее 3 символов, если он передан.
  • Все ограничения также отображаются в документации и автоматически применяются при каждом запросе.

7. Типичные ошибки и советы

  • Ошибка 422 — самая частая ошибка при работе с FastAPI и Pydantic. Она возникает, если данные не соответствуют описанной модели: отсутствует обязательное поле, неверный тип, не выполнено ограничение.
  • Используйте специальные типы из Pydantic (EmailStr, conint, constr, HttpUrl и др.) для более строгой и наглядной валидации.
  • Для сложных правил используйте декоратор @validator и методы класса.
  • Swagger UI (автоматическая документация) всегда отражает актуальные ограничения и структуру моделей, что облегчает тестирование и работу с API.
  • Не бойтесь делать модели подробными — это упростит поддержку и развитие проекта.

8. Полезные ссылки

Заключение

Pydantic и FastAPI делают процесс валидации данных простым, надёжным и прозрачным. Используйте типы, ограничения и кастомные валидаторы для построения безопасных и удобных API. Чем подробнее вы опишете структуру и правила для своих данных, тем меньше будет неожиданных ошибок и тем проще станет поддержка вашего приложения. Валидация — это не просто формальность, а важный инструмент для повышения качества и безопасности вашего кода.