Сегодня разберем тот случай, когда бизнес приходит с очередной задачей, звучащей так: «Нам нужно, чтобы награды для пользователей можно было гибко менять, подстраивать, проверять и, главное, не ломать всё при каждом чихе».
Pydantic — это библиотека для Python, которая превращает данные в нормальные структуры и валидирует их. В отличие от обычных dataclass’ов, он понимает, что данные редко бывают идеальными, и может ловить их на месте.
Например, вот классический кейс:
-
Пользователь совершил действие.
-
На сервер улетает JSON: «я убил дракона, дай мне 100 золотых».
-
Вы проверяете данные, создаете награду, отправляете пользователю.
Идея в том, чтобы не проверять такие данные вручную через if
‘ы, а построить модель, которая сама все расскажет. И бонусом — чтобы вся логика не развалилась при следующем обновлении.
Простой пример: валидируем данные награды.
кОfrom pydantic import BaseModel, Field class Reward(BaseModel): type: str amount: int = Field(..., gt=0, description="Количество награды (должно быть больше нуля)") reward = Reward(type="gold", amount=100) print(reward)
Код проверяет, что amount
больше нуля, а так же генерирует документацию для полей (например, description
). Если данные некорректны, бросает исключение.
Пример ситуации
Описываем типы наград
Будет три базовых типа наград:
-
Золото.
-
Очки опыта.
-
Скидки.
Каждый тип имеет свои уникальные параметры. Схема Pydantic для этого:
from typing import Union from pydantic import BaseModel, Field class GoldReward(BaseModel): type: str = Field("gold", const=True) amount: int = Field(..., gt=0, description="Количество золота") class XPReward(BaseModel): type: str = Field("xp", const=True) points: int = Field(..., gt=0, description="Очки опыта") class DiscountReward(BaseModel): type: str = Field("discount", const=True) percentage: float = Field(..., gt=0, lt=100, description="Скидка в процентах") Reward = Union[GoldReward, XPReward, DiscountReward]
Проверяем данные
Допустим, система присылает JSON с наградой. Pydantic превращает его в объект Python.
reward_data = {"type": "gold", "amount": 150} # Валидируем и преобразуем try: reward = Reward.parse_obj(reward_data) print(reward) except ValidationError as e: print(f"Ошибка валидации: {e}")
Динамическая адаптация наград
Теперь сделаем адаптер, который меняет награду в зависимости от условий. Например:
-
VIP‑пользователи получают удвоенное золото.
-
Скидки выше 50% требуют дополнительного подтверждения.
class User(BaseModel): id: int is_vip: bool = False class RewardAdapter: def __init__(self, reward: Reward, user: User): self.reward = reward self.user = user def adapt(self): if isinstance(self.reward, GoldReward) and self.user.is_vip: self.reward.amount *= 2 elif isinstance(self.reward, DiscountReward) and self.reward.percentage > 50: print("Внимание: скидка требует одобрения!") return self.reward
Пример использования:
user = User(id=42, is_vip=True) reward_data = {"type": "gold", "amount": 100} reward = Reward.parse_obj(reward_data) adapter = RewardAdapter(reward, user) adapted_reward = adapter.adapt() print(adapted_reward)
Добавляем новые типы наград
Что если завтра появляется новый тип награды? Например, «бонусный доступ» к платным функциям. Достаточно просто добавить еще одну модель.
class AccessReward(BaseModel): type: str = Field("access", const=True) feature: str = Field(..., description="Название функции") Reward = Union[GoldReward, XPReward, DiscountReward, AccessReward]
Покрываем тестами
Тесты спасают от сюрпризов. Покажу простой тест на VIP‑адаптацию:
def test_vip_gold_reward(): user = User(id=1, is_vip=True) reward = GoldReward(type="gold", amount=100) adapter = RewardAdapter(reward, user) adapted = adapter.adapt() assert adapted.amount == 200
Прочая информация
1. А как с безопасностью данных?
Pydantic позволяет строго ограничивать входные данные. Например:
-
Указываем диапазоны (
gt=0
,lt=100
). -
Используем
const=True
, чтобы запрещать некорректные типы.
2. Можно ли использовать Pydantic с FastAPI?
Да! FastAPI поддерживает Pydantic для описания запросов и ответов.
3. А если бизнес‑логика станет сложнее?
Добавляйте адаптеры для каждого нового условия. Pydantic позволяет строить вложенные схемы и обрабатывать их в адаптерах.
С прочими возможностями pydantic можно ознакомиться здесь.
17 декабря в рамках курса «Reinforcement Learning» пройдет открытый урок «Алгоритмы с подкреплением в стохастических играх». Узнать подробности и записаться можно по ссылке.
ссылка на оригинал статьи https://habr.com/ru/articles/864178/
Добавить комментарий