Перейти к содержанию

Экспериментальные возможности

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

Дополнительную информацию об экспериментальных функциях см. в нашей Политике версий .

Обратная связь

Мы приветствуем отзывы об экспериментальных функциях! Откройте проблему в репозитории Pydantic GitHub, чтобы поделиться своими мыслями, запросами или предложениями.

Мы также рекомендуем вам прочитать существующие отзывы и высказать свои мысли по существующим проблемам.

Предупреждения об импорте

Когда вы импортируете экспериментальную функцию из experimental модуля, вы увидите предупреждающее сообщение о том, что эта функция является экспериментальной. Вы можете отключить это предупреждение следующим образом:

import warnings

from pydantic import PydanticExperimentalWarning

warnings.filterwarnings('ignore', category=PydanticExperimentalWarning)

Конвейерный API

В Pydantic v2.8.0 представлен экспериментальный «конвейерный» API, который позволяет выполнять синтаксический анализ (проверку), ограничения и преобразования более типобезопасным способом, чем существующие API. Этот API может быть изменен или удален. Мы ждем отзывов и предложений, прежде чем сделать его постоянной частью Pydantic.

??? API "Документация по API" pydantic.experimental.pipeline

Как правило, API конвейера используется для определения последовательности шагов, которые необходимо применить к входящим данным во время проверки. API конвейера спроектирован так, чтобы быть более типобезопасным и компонуемым, чем существующий API Pydantic.

Каждый шаг конвейера может быть:

  • Шаг проверки, который запускает pydantic проверку предоставленного типа.
  • Шаг преобразования, который изменяет данные
  • Шаг ограничения, который проверяет данные на соответствие условию.
  • Шаг предиката, который проверяет данные на соответствие условию и выдает ошибку, если возвращает значение False

Обратите внимание, что следующий пример пытается быть исчерпывающим за счет сложности: если вы пишете такое количество преобразований в аннотациях типов, вы можете рассмотреть возможность использования модели UserIn и UserOut (пример ниже) или аналогичной, в которой вы выполняете преобразования с помощью идоматических простой код Python. Эти API предназначены для ситуаций, когда экономия кода значительна, а добавленная сложность относительно невелика.

from __future__ import annotations

from datetime import datetime

from typing_extensions import Annotated

from pydantic import BaseModel
from pydantic.experimental.pipeline import validate_as, validate_as_deferred


class User(BaseModel):
    name: Annotated[str, validate_as(str).str_lower()]  # (1)!
    age: Annotated[int, validate_as(int).gt(0)]  # (2)!
    username: Annotated[str, validate_as(str).str_pattern(r'[a-z]+')]  # (3)!
    password: Annotated[
        str,
        validate_as(str)
        .transform(str.lower)
        .predicate(lambda x: x != 'password'),  # (4)!
    ]
    favorite_number: Annotated[  # (5)!
        int,
        (validate_as(int) | validate_as(str).str_strip().validate_as(int)).gt(
            0
        ),
    ]
    friends: Annotated[list[User], validate_as(...).len(0, 100)]  # (6)!
    family: Annotated[  # (7)!
        list[User],
        validate_as_deferred(lambda: list[User]).transform(lambda x: x[1:]),
    ]
    bio: Annotated[
        datetime,
        validate_as(int)
        .transform(lambda x: x / 1_000_000)
        .validate_as(...),  # (8)!
    ]
  1. Строка в нижнем регистре.
  2. Ограничьте целое число больше нуля.
  3. Ограничьте строку так, чтобы она соответствовала шаблону регулярного выражения.
  4. Вы также можете использовать методы преобразования, ограничения и предиката нижнего уровня.
  5. Используйте | или & операторы для объединения шагов (например, логическое ИЛИ или И).
  6. Вызов validate_as(...) с Ellipsis , ... в качестве первого позиционного аргумента подразумевает validate_as(<field type>) . Используйте validate_as(Any) для принятия любого типа.
  7. Для рекурсивных типов вы можете использовать validate_as_deferred для ссылки на сам тип до его определения.
  8. Вы можете вызвать validate_as() до или после других шагов для предварительной или последующей обработки.

Сопоставление с BeforeValidator , AfterValidator и WrapValidator

Метод validate_as — это более безопасный для типов способ определения BeforeValidator , AfterValidator и WrapValidator :

from typing_extensions import Annotated

from pydantic.experimental.pipeline import transform, validate_as

# BeforeValidator
Annotated[int, validate_as(str).str_strip().validate_as(...)]  # (1)!
# AfterValidator
Annotated[int, transform(lambda x: x * 2)]  # (2)!
# WrapValidator
Annotated[
    int,
    validate_as(str)
    .str_strip()
    .validate_as(...)
    .transform(lambda x: x * 2),  # (3)!
]
  1. Удалите пробелы из строки перед анализом ее как целого числа.
  2. Умножьте целое число на 2 после его анализа.
  3. Удалите пробелы из строки, проверьте ее как целое число, а затем умножьте на 2.

Альтернативные модели

Существует множество альтернативных шаблонов, которые можно использовать в зависимости от сценария. В качестве примера рассмотрим упомянутый выше шаблон UserIn и UserOut :

from __future__ import annotations

from pydantic import BaseModel


class UserIn(BaseModel):
    favorite_number: int | str


class UserOut(BaseModel):
    favorite_number: int


def my_api(user: UserIn) -> UserOut:
    favorite_number = user.favorite_number
    if isinstance(favorite_number, str):
        favorite_number = int(user.favorite_number.strip())

    return UserOut(favorite_number=favorite_number)


assert my_api(UserIn(favorite_number=' 1 ')).favorite_number == 1

В этом примере используется простой идиоматический код Python, который может быть легче понять, проверить тип и т. д., чем примеры выше. Подход, который вы выберете, должен действительно зависеть от вашего варианта использования. Вам придется сравнить многословность, производительность, простоту возврата значимых ошибок вашим пользователям и т. д., чтобы выбрать правильный шаблон. Просто будьте осторожны и не злоупотребляйте расширенными шаблонами, такими как API конвейера, только потому, что можете.


本文总阅读量