
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. Чем подробнее вы опишете структуру и правила для своих данных, тем меньше будет неожиданных ошибок и тем проще станет поддержка вашего приложения. Валидация — это не просто формальность, а важный инструмент для повышения качества и безопасности вашего кода.