Aller au contenu

Fonctionnalités expérimentales

Dans cette section, vous trouverez de la documentation sur les nouvelles fonctionnalités expérimentales de Pydantic. Ces fonctionnalités sont susceptibles d'être modifiées ou supprimées, et nous recherchons des commentaires et des suggestions avant d'en faire une partie permanente de Pydantic.

Consultez notre politique de version pour plus d’informations sur les fonctionnalités expérimentales.

Retour

Nous apprécions les commentaires sur les fonctionnalités expérimentales! Veuillez ouvrir un problème sur le référentiel Pydantic GitHub pour partager vos réflexions, demandes ou suggestions.

Nous vous encourageons également à lire les commentaires existants et à ajouter vos réflexions aux problèmes existants.

Avertissements lors de l'importation

Lorsque vous importez une fonctionnalité expérimentale à partir du module experimental , vous verrez un message d'avertissement indiquant que la fonctionnalité est expérimentale. Vous pouvez désactiver cet avertissement comme suit:

import warnings

from pydantic import PydanticExperimentalWarning

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

API de pipelines

Pydantic v2.8.0 a introduit une API expérimentale «pipeline» qui permet de composer l'analyse (validation), les contraintes et les transformations d'une manière plus sûre que les API existantes. Cette API est susceptible d'être modifiée ou supprimée, nous recherchons des commentaires et des suggestions avant d'en faire une partie permanente de Pydantic.

??? API "Documentation API" pydantic.experimental.pipeline

Généralement, l'API du pipeline est utilisée pour définir une séquence d'étapes à appliquer aux données entrantes lors de la validation. L'API du pipeline est conçue pour être plus sécurisée et composable que l'API Pydantic existante.

Chaque étape du pipeline peut être:

  • Une étape de validation qui exécute la validation pydantic sur le type fourni
  • Une étape de transformation qui modifie les données
  • Une étape de contrainte qui vérifie les données par rapport à une condition
  • Une étape de prédicat qui vérifie les données par rapport à une condition et génère une erreur si elle renvoie False

Notez que l'exemple suivant tente d'être exhaustif au prix de la complexité: si vous vous retrouvez à écrire autant de transformations dans des annotations de type, vous souhaiterez peut-être envisager d'avoir un modèle UserIn et UserOut (exemple ci-dessous) ou similaire où vous effectuez les transformations via idomatic. code Python simple. Ces API sont destinées aux situations où les économies de code sont importantes et la complexité supplémentaire est relativement faible.

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. Minuscule une chaîne.
  2. Contraindre un entier à être supérieur à zéro.
  3. Contraindre une chaîne pour qu'elle corresponde à un modèle d'expression régulière.
  4. Vous pouvez également utiliser les méthodes de transformation, de contrainte et de prédicat de niveau inférieur.
  5. Utilisez le | ou & opérateurs pour combiner des étapes (comme un OU ou un ET logique).
  6. Appeler validate_as(...) avec Ellipsis , ... comme premier argument de position implique validate_as(<field type>) . Utilisez validate_as(Any) pour accepter n’importe quel type.
  7. Pour les types récursifs, vous pouvez utiliser validate_as_deferred pour référencer le type lui-même avant qu'il ne soit défini.
  8. Vous pouvez appeler validate_as() avant ou après d'autres étapes pour effectuer un pré ou un post-traitement.

Mappage de BeforeValidator , AfterValidator et WrapValidator

La méthode validate_as est un moyen plus sûr de définir BeforeValidator , AfterValidator et 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. Supprimez les espaces d’une chaîne avant de l’analyser comme un entier.
  2. Multipliez un entier par 2 après l'avoir analysé.
  3. Supprimez les espaces d'une chaîne, validez-la comme un entier, puis multipliez-la par 2.

Modèles alternatifs

Il existe de nombreux modèles alternatifs à utiliser en fonction du scénario. À titre d'exemple, considérons le modèle UserIn et UserOut mentionné ci-dessus:

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

Cet exemple utilise du code Python idiomatique simple qui peut être plus facile à comprendre, à vérifier le type, etc. que les exemples ci-dessus. L'approche que vous choisissez doit vraiment dépendre de votre cas d'utilisation. Vous devrez comparer la verbosité, les performances, la facilité de renvoyer des erreurs significatives à vos utilisateurs, etc. pour choisir le bon modèle. Faites simplement attention à ne pas abuser des modèles avancés tels que l'API de pipeline simplement parce que vous le pouvez.


本文总阅读量