Lewati ke isi

!!! peringatan "🚧 Pekerjaan Sedang Berlangsung" Halaman ini sedang dalam proses.

JSON

Penguraian JSON

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

Pydantic menyediakan penguraian JSON bawaan, yang membantu mencapai:

  • Peningkatan kinerja yang signifikan tanpa biaya menggunakan perpustakaan pihak ketiga
  • Dukungan untuk kesalahan khusus
  • Dukungan untuk spesifikasi strict

Berikut ini contoh penguraian JSON bawaan Pydantic melalui metode model_validate_json, yang menampilkan dukungan untuk spesifikasi strict saat mengurai data JSON yang tidak cocok dengan anotasi jenis model:

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 tidak memiliki tipe date atau tupel, tetapi Pydantic mengetahuinya sehingga memungkinkan string dan array sebagai input masing-masing saat menguraikan JSON secara langsung.
  2. Jika Anda meneruskan nilai yang sama ke metode model_validate, Pydantic akan memunculkan kesalahan validasi karena konfigurasi strict diaktifkan.

Di v2.5.0 dan yang lebih baru, Pydantic menggunakan jiter , parser JSON yang cepat dan dapat diubah, untuk mengurai data JSON. Menggunakan jiter dibandingkan dengan serde menghasilkan sedikit peningkatan kinerja yang akan menjadi lebih baik lagi di masa mendatang.

Parser jiter JSON hampir seluruhnya kompatibel dengan parser JSON serde , dengan satu peningkatan nyata adalah jiter mendukung deserialisasi nilai inf dan NaN . Di masa depan, jiter dimaksudkan untuk mengaktifkan kesalahan validasi dukungan untuk menyertakan lokasi di input JSON asli yang berisi nilai tidak valid.

Penguraian JSON Parsial

Mulai v2.7.0 , parser JSON Pydantic menawarkan dukungan untuk parsing JSON parsial, yang diekspos melalui pydantic_core.from_json. Berikut ini contoh cara kerja fitur ini:

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. Daftar JSON tidak lengkap - tidak ada penutupnya "]
  2. allow_partial diatur ke False (default), terjadi kesalahan penguraian.
  3. allow_partial disetel ke True , sebagian input berhasil dideserialisasi.

Ini juga berfungsi untuk deserialisasi kamus parsial. Misalnya:

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']}

!!! tip "Memvalidasi Keluaran LLM " Fitur ini sangat bermanfaat untuk memvalidasi keluaran LLM . Kami telah menulis beberapa postingan blog tentang topik ini, yang dapat Anda temukan di sini .

Di versi Pydantic mendatang, kami berharap dapat memperluas dukungan untuk fitur ini melalui fungsi validasi JSON Pydantic lainnya (pydantic.main.BaseModel.model_validate_json dan pydantic.type_adapter.TypeAdapter.validate_json) atau konfigurasi model. Pantau terus 🚀!

Untuk saat ini, Anda dapat menggunakan pydantic_core.from_json dikombinasikan dengan pydantic.main.BaseModel.model_validate untuk mencapai hasil yang sama. Berikut ini contohnya:

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'])

!!! tip Agar penguraian sebagian JSON berfungsi dengan andal, semua bidang pada model harus memiliki nilai default.

Lihat contoh berikut untuk melihat lebih mendalam tentang cara menggunakan nilai default dengan penguraian JSON parsial:

Menggunakan nilai default dengan penguraian JSON parsial

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)

String Caching

Mulai dari v2.7.0 , parser JSON Pydantic menawarkan dukungan untuk mengonfigurasi cara string Python di-cache selama penguraian dan validasi JSON (ketika string Python dibuat dari string Rust selama validasi Python, misalnya setelah strip_whitespace=True ). Pengaturan cache_strings diekspos melalui model config dan pydantic_core.from_json.

Pengaturan cache_strings dapat mengambil salah satu dari nilai berikut:

  • True atau 'all' (default): menyimpan semua string dalam cache
  • 'keys' : kunci kamus khusus cache, ini hanya berlaku saat digunakan dengan pydantic_core.from_json atau saat mengurai JSON menggunakan Json
  • False atau 'none' : tidak ada cache

Menggunakan fitur cache string menghasilkan peningkatan kinerja, namun sedikit meningkatkan penggunaan memori.

Rincian Caching String

  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.

Serialisasi JSON

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

Untuk informasi selengkapnya tentang serialisasi JSON, lihat halaman Konsep Serialisasi .


本文总阅读量