Коробка с питоном
539 subscribers
45 photos
119 links
Заметки от Python-разработчика: сниппеты, обзоры пакетов, новости и другая полезная информация.

Автор: @kiriharu
Download Telegram
У меня тут небольшая хотелка возникла, я захотел исходя из описаний полей в Pydantic модели генерировать запрос на выборку с фильтрацией из БД.

Оказывается, кто-то уже сделал похожее для Django. Выглядит неплохо, но всё же саму генерацию запроса я бы вынес в отдельный класс :)

#django #pydantic #eng #статья
А я к вам с новостями.

FastAPI в версии 0.100.0-beta1 поддерживает Pydantic v2 в бета-режиме. Да-да, это тот самый Pydantic, внутренности которого написаны на Rust. Гайд по миграции можно почитать здесь, а релиз тут.

#fastapi #pydantic
Зачем нужно делать кастомную базовую Pydantic модель?

Сейчас некоторые со мной не согласятся, но я часто рекомендую делать базовую pydantic модель и наследовать все модели от неё.

Наличие такой глобальной модели позволяет настраивать поведение всех моделей в приложении. Рассмотрю несколько кейсов, когда это может понадобится.

1) Контроль над входными данными.
Например, мы хотим округлять все поля которые называются price до трех знаков после запятой. Сделать это можно так:

class CustomBaseModel(BaseModel):
@root_validator()
def round_price(cls, data: dict) -> dict:
prices = {k: round(v, 3) for k, v in data.items() if k == "price"}
return {**data, **prices}

Валидаторы дают возможность изменять входящие данные, но это стоит использовать с осторожностью.

P.S.: В коментах подметили, что такой подход неявный, и я с этим согласен. Ничего не мешает для таких целей сделать ещё одну базовую модель (PriceRoundBaseModel), наследуясь от нашей базовой СustomBaseModel и использовать её там, где такое поведение необходимо.

2) Кастомый энкодер/декодер json.
Пакет json из стандартной библиотеки очень медленный. При необходимости ускорить сервис этот пакет в первую очередь пытаются заменить на что-то побыстрее.
Это происходит из-за того, что операций по (дe)сериализации json в приложении может быть много, и смена библиотеки, в этом случае, дает ощутимый прирост к общей скорости.

В pydantic есть 2 опции в конфиге, которые позволяют изменять поведение энкодера и декодера. Выглядит это так:

def orjson_dumps(v, *, default):
# orjson.dumps возвращает байты, поэтому нам надо их декодить, чтобы соответствовать сигнатуре json.dumps
return orjson.dumps(v, default=default).decode()

class CustomBaseModel(BaseModel):
class Config:
json_loads = orjson.loads
json_dumps = orjson_dumps

#pydantic