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

Ответ

Pydantic — это библиотека для валидации, парсинга и сериализации данных в Python, основанная на аннотациях типов. Она гарантирует, что данные соответствуют заданной структуре (модели).

Основное назначение:

  1. Валидация данных: Проверка типов, форматов (email, URL) и ограничений (например, min_length).
  2. Парсинг и приведение типов (coercion): Автоматическое преобразование входных данных в нужные типы Python (например, строки "123" в int).
  3. Сериализация: Преобразование моделей Pydantic в словари или JSON.
  4. Управление настройками: Загрузка конфигурации приложения из переменных окружения.

Поддерживаемые типы данных:

Pydantic работает с большинством стандартных типов Python:

  • Примитивные типы: int, float, str, bool, bytes.
  • Сложные типы: List, Dict, Tuple, Set, Enum.
  • Типы из стандартной библиотеки: datetime, date, UUID, Path.
  • Вложенные модели: Поля могут быть другими моделями Pydantic.
  • Опциональные типы: Optional[T] или Union[T, None].

Пример валидации и парсинга

from pydantic import BaseModel, ValidationError, Field
from typing import List

class User(BaseModel):
    id: int
    name: str = Field(..., min_length=2)
    tags: List[str] = []

# 1. Успешная валидация с приведением типов
# 'id' будет преобразован из строки в int
data_valid = {"id": "123", "name": "Alice", "tags": ["admin", "dev"]}
user = User(**data_valid)
print(user.model_dump_json(indent=2))
# Вывод:
# {
#   "id": 123,
#   "name": "Alice",
#   "tags": [
#     "admin",
#     "dev"
#   ]
# }

# 2. Ошибка валидации
data_invalid = {"id": "abc", "name": "B"} # id - не число, name - слишком короткое
try:
    User(**data_invalid)
except ValidationError as e:
    print(e)
# Вывод:
# 2 validation errors for User
# id
#   Input should be a valid integer, unable to parse string as an integer [type=int_parsing, ...]
# name
#   String should have at least 2 characters [type=string_too_short, ...]

Ответ 18+ 🔞

Ну, слушай, смотри, есть такая штука — Pydantic. Это, блядь, не просто библиотека, а целый ёперный театр для данных в Python. Основано всё на этих, как их, аннотациях типов. Суть в чём? Чтобы твои данные не были каким-то левым говном, а соответствовали строгой структуре, которую ты сам и задашь.

Зачем оно вообще надо, это чудо?

  1. Валидация, ёпта! Проверяет, что данные — это то, что ты ожидаешь. Число ли там, строка ли, почта ли правильная, или длина не короче двух символов. Не даст всякой хуйне пролезть.
  2. Парсинг и приведение типов. Это когда он сам, хитрая жопа, превращает строку "123" в нормальное число 123. Удобно же, блядь!
  3. Сериализация. Сделал из данных красивую модель — легко превратил её обратно в словарь или в JSON, чтобы куда-то отправить.
  4. Настройки приложения. Чтоб не хардкодить пароли и айпишники, а грузить их из переменных окружения. Безопасно, нахуй.

С чем оно работает?

Да практически со всем, что в голову взбредёт:

  • Обычные типы: int, float, str, bool, bytes.
  • Сложные штуки: List, Dict, Tuple, Set, Enum.
  • Из стандартной библиотеки: datetime, date, UUID, Path.
  • Вложенные модели. Можно друг в друга вкладывать, как матрёшку.
  • Опциональные поля. Optional[T] — может быть значение, а может и не быть. Похуй.

Пример, чтобы вообще всё стало ясно

Смотри, вот тебе живой пример, как эта магия работает и как она может наорать, если что-то не так.

from pydantic import BaseModel, ValidationError, Field
from typing import List

class User(BaseModel):
    id: int
    name: str = Field(..., min_length=2)  # Точки тут — это "обязательно". И имя не короче двух букв!
    tags: List[str] = []

# 1. Всё ок, валидация прошла, типы привелись
# Обрати внимание, 'id' был строкой, а стал числом! Автоматом, блядь!
data_valid = {"id": "123", "name": "Alice", "tags": ["admin", "dev"]}
user = User(**data_valid)
print(user.model_dump_json(indent=2))
# Напечатает красивый JSON:
# {
#   "id": 123,
#   "name": "Alice",
#   "tags": [
#     "admin",
#     "dev"
#   ]
# }

# 2. А вот тут пиздец наступит
data_invalid = {"id": "abc", "name": "B"} # 'id' — не число, 'name' — одна буква, ёбана!
try:
    User(**data_invalid)
except ValidationError as e:
    print(e)
# И он тебе подробно, по пунктам, объяснит, в чём ты мудак:
# 2 validation errors for User
# id
#   Input should be a valid integer, unable to parse string as an integer [type=int_parsing, ...]
# name
#   String should have at least 2 characters [type=string_too_short, ...]

Вот и вся история. Библиотека — огонь. Данные держит в ежовых рукавицах, а тебе спокойно жить позволяет. Главное — правила задать правильно.