Aller au contenu

!!! avertissement "🚧 Work in Progress" Cette page est un work in progress.

JSON

Analyse Json

??? api "Documentation API" pydantic.main.BaseModel.model_validate_json pydantic.type_adapter.TypeAdapter.validate_json pydantic_core.from_json

Pydantic fournit une analyse JSON intégrée, qui permet d'obtenir:

  • Améliorations significatives des performances sans le coût d'utilisation d'une bibliothèque tierce
  • Prise en charge des erreurs personnalisées
  • Prise en charge de spécifications strict

Voici un exemple d'analyse JSON intégrée de Pydantic via la méthode model_validate_json, montrant la prise en charge de spécifications strict lors de l'analyse des données JSON qui ne correspondent pas aux annotations de type du modèle:

from datetime import date
from typing import Tuple

from pydantic import BaseModel, ConfigDict, ValidationError


class Event(BaseModel):
    model_config = ConfigDict(strict=True)

    when: date
    where: Tuple[int, int]


json_data = '{"when": "1987-01-28", "where": [51, -1]}'
print(Event.model_validate_json(json_data))  # (1)!
#> when=datetime.date(1987, 1, 28) where=(51, -1)

try:
    Event.model_validate({'when': '1987-01-28', 'where': [51, -1]})  # (2)!
except ValidationError as e:
    print(e)
    """
    2 validation errors for Event
    when
      Input should be a valid date [type=date_type, input_value='1987-01-28', input_type=str]
    where
      Input should be a valid tuple [type=tuple_type, input_value=[51, -1], input_type=list]
    """
  1. JSON n'a pas de types date ou de tuple, mais Pydantic sait que cela autorise respectivement les chaînes et les tableaux comme entrées lors de l'analyse directe de JSON.
  2. Si vous transmettez les mêmes valeurs à la méthode model_validate, Pydantic générera une erreur de validation car la configuration strict est activée.

Dans la version 2.5.0 et supérieure, Pydantic utilise jiter , un analyseur JSON rapide et itérable, pour analyser les données JSON. L'utilisation jiter par rapport à serde entraîne de modestes améliorations de performances qui s'amélioreront encore à l'avenir.

L'analyseur jiter JSON est presque entièrement compatible avec l'analyseur serde JSON, avec une amélioration notable étant que jiter prend en charge la désérialisation des valeurs inf et NaN . À l'avenir, jiter est destiné à permettre aux erreurs de validation de prise en charge d'inclure l'emplacement dans l'entrée JSON d'origine qui contenait la valeur non valide.

Analyse JSON partielle

À partir de la version 2.7.0 , l'analyseur JSON de Pydantic offre la prise en charge de l'analyse JSON partielle, qui est exposée via pydantic_core.from_json. Voici un exemple de cette fonctionnalité en action:

from pydantic_core import from_json

partial_json_data = '["aa", "bb", "c'  # (1)!

try:
    result = from_json(partial_json_data, allow_partial=False)
except ValueError as e:
    print(e)  # (2)!
    #> EOF while parsing a string at line 1 column 15

result = from_json(partial_json_data, allow_partial=True)
print(result)  # (3)!
#> ['aa', 'bb']
  1. La liste JSON est incomplète - il manque une fermeture "]
  2. Lorsque allow_partial est défini sur False (valeur par défaut), une erreur d'analyse se produit.
  3. Lorsque allow_partial est défini sur True , une partie de l'entrée est désérialisée avec succès.

Cela fonctionne également pour désérialiser des dictionnaires partiels. Par exemple:

from pydantic_core import from_json

partial_dog_json = '{"breed": "lab", "name": "fluffy", "friends": ["buddy", "spot", "rufus"], "age'
dog_dict = from_json(partial_dog_json, allow_partial=True)
print(dog_dict)
#> {'breed': 'lab', 'name': 'fluffy', 'friends': ['buddy', 'spot', 'rufus']}

!!! Astuce "Validation des sorties LLM " Cette fonctionnalité est particulièrement utile pour valider les sorties LLM . Nous avons rédigé quelques articles de blog sur ce sujet, que vous pouvez trouver ici .

Dans les futures versions de Pydantic, nous prévoyons d'étendre la prise en charge de cette fonctionnalité via les autres fonctions de validation JSON de Pydantic (pydantic.main.BaseModel.model_validate_json et pydantic.type_adapter.TypeAdapter.validate_json) ou la configuration du modèle. Restez à l'écoute 🚀!

Pour l'instant, vous pouvez utiliser pydantic_core.from_json en combinaison avec pydantic.main.BaseModel.model_validate pour obtenir le même résultat. Voici un exemple:

from pydantic_core import from_json

from pydantic import BaseModel


class Dog(BaseModel):
    breed: str
    name: str
    friends: list


partial_dog_json = '{"breed": "lab", "name": "fluffy", "friends": ["buddy", "spot", "rufus"], "age'
dog = Dog.model_validate(from_json(partial_dog_json, allow_partial=True))
print(repr(dog))
#> Dog(breed='lab', name='fluffy', friends=['buddy', 'spot', 'rufus'])

!!! Astuce Pour que l'analyse JSON partielle fonctionne de manière fiable, tous les champs du modèle doivent avoir des valeurs par défaut.

Consultez l'exemple suivant pour un aperçu plus approfondi de la façon d'utiliser les valeurs par défaut avec l'analyse JSON partielle:

Utilisation des valeurs par défaut avec analyse JSON partielle

from typing import Any, Optional, Tuple

import pydantic_core
from typing_extensions import Annotated

from pydantic import BaseModel, ValidationError, WrapValidator


def default_on_error(v, handler) -> Any:
    """
    Raise a PydanticUseDefault exception if the value is missing.

    This is useful for avoiding errors from partial
    JSON preventing successful validation.
    """
    try:
        return handler(v)
    except ValidationError as exc:
        # there might be other types of errors resulting from partial JSON parsing
        # that you allow here, feel free to customize as needed
        if all(e['type'] == 'missing' for e in exc.errors()):
            raise pydantic_core.PydanticUseDefault()
        else:
            raise


class NestedModel(BaseModel):
    x: int
    y: str


class MyModel(BaseModel):
    foo: Optional[str] = None
    bar: Annotated[
        Optional[Tuple[str, int]], WrapValidator(default_on_error)
    ] = None
    nested: Annotated[
        Optional[NestedModel], WrapValidator(default_on_error)
    ] = None


m = MyModel.model_validate(
    pydantic_core.from_json('{"foo": "x", "bar": ["world",', allow_partial=True)
)
print(repr(m))
#> MyModel(foo='x', bar=None, nested=None)


m = MyModel.model_validate(
    pydantic_core.from_json(
        '{"foo": "x", "bar": ["world", 1], "nested": {"x":', allow_partial=True
    )
)
print(repr(m))
#> MyModel(foo='x', bar=('world', 1), nested=None)

Chaînes de mise en cache

À partir de la version 2.7.0 , l'analyseur JSON de Pydantic offre une prise en charge pour configurer la manière dont les chaînes Python sont mises en cache lors de l'analyse et de la validation JSON (lorsque les chaînes Python sont construites à partir de chaînes Rust lors de la validation Python, par exemple après strip_whitespace=True ). Le paramètre cache_strings est exposé via model config et pydantic_core.from_json.

Le paramètre cache_strings peut prendre l'une des valeurs suivantes:

  • True ou 'all' (valeur par défaut): met en cache toutes les chaînes
  • 'keys': cache uniquement les clés du dictionnaire, cela s'applique uniquement lorsqu'il est utilisé avec pydantic_core.from_json ou lors de l'analyse de JSON à l'aide de Json
  • False ou 'none' : pas de mise en cache

L'utilisation de la fonctionnalité de mise en cache de chaînes entraîne des améliorations de performances, mais augmente légèrement l'utilisation de la mémoire.

Détails de la mise en cache des chaînes

  1. Strings are cached using a fully associative cache with a size of 16,384.
  2. Only strings where len(string) < 64 are cached.
  3. There is some overhead to looking up the cache, which is normally worth it to avoid constructing strings. However, if you know there will be very few repeated strings in your data, you might get a performance boost by disabling this setting with cache_strings=False.

Sérialisation JSON

??? API "Documentation API" pydantic.main.BaseModel.model_dump_json
pydantic.type_adapter.TypeAdapter.dump_json
pydantic_core.to_json

Pour plus d'informations sur la sérialisation JSON, consultez la page Concepts de sérialisation .


本文总阅读量