$30 off During Our Annual Pro Sale. View Details »

Валидация и сериализация в 2023 году

Валидация и сериализация в 2023 году

Небольшая преза на тему pydantic, и его скоростного конкурента msgspec и небольшое их сравнение по скорости.

Denis Anikin

August 15, 2023
Tweet

More Decks by Denis Anikin

Other Decks in Programming

Transcript

  1. #
    Денис Аникин
    https://xfenix.ru
    Валидация и
    сериализация в
    2023 году

    View Slide

  2. Денис Аникин
    2
    Что я делаю
    — работаю в Райфе
    — teamlead в 3 командах
    — community lead в Python Community
    — fullstack: typescript, python, devops
    https://xfenix.ru

    View Slide

  3. Блин, чувак реально
    сделал доклад о
    pydantic…

    View Slide

  4. View Slide

  5. Pydantic
    5

    View Slide

  6. View Slide

  7. Pydantic
    7
    О плюсах
    —Очень популярная
    —Легкая, удобная
    —На скорость особых жалоб не было, но…
    —Ядро на расте (теперь) — х5 к скорости

    View Slide

  8. Pydantic
    8
    Как выглядит, если кто не видел
    class SomeUser(BaseModel):
    client_fio: str
    client_gender: tuple[int, ...]
    phone_of_mama: int
    card_balance: decimal.Decimal
    probability_of_fail: float
    ready_to_move_on: bool
    traits: tuple[
    typing.Literal["immortality", "omniprecense", "omnipower", "superspeed"], ...
    ]
    music_he_hates: frozenset[
    typing.Literal["kallyanni_rap", "hookah_pop", "rock", "jazz", "folk"]
    ]

    View Slide

  9. Некоторым не
    нравится переход на
    версию 2
    9

    View Slide

  10. Strict vs Lax
    10

    View Slide

  11. Странное в pydantic
    11

    View Slide

  12. 12
    Dataclasses
    from pydantic.dataclasses import dataclass
    @dataclass
    class User:
    id: int
    name: str = 'John Doe'
    signup_ts: datetime = None
    user = User(id='42', signup_ts='2032-06-21T12:00')
    print(user)
    """
    User(id=42, name='John Doe', signup_ts=datetime.datetime(2032, 6, 21, 12, 0))
    """

    View Slide

  13. 13
    Validate_call
    from pydantic import ValidationError, validate_call
    @validate_call
    def repeat(s: str, count: int, *, separator: bytes = b'') -> bytes:
    ...
    try:
    c = repeat('hello', 'wrong')
    except ValidationError as exc:
    print(exc)
    """
    1 validation error for repeat
    1
    Input should be a valid integer, unable to parse string as an integer [type=int_parsing,
    input_value='wrong', input_type=str]
    """

    View Slide

  14. View Slide

  15. 15
    BaseSettings
    class Settings(BaseSettings):
    auth_key: str = Field(validation_alias='my_auth_key')
    redis_dsn: RedisDsn = Field(
    'redis://user:pass@localhost:6379/1',
    validation_alias=AliasChoices('service_redis_dsn', 'redis_url'),
    )

    View Slide

  16. Если прошли мимо
    хайпа, гляньте, не
    пожалеете
    16

    View Slide

  17. Не то чтобы нам чего-
    то не хватало, но…
    17

    View Slide

  18. MsgSpec
    18

    View Slide

  19. View Slide

  20. MsgSpec
    20
    Что там интересного
    —Zero-cost schema validation
    —Speedy Struct type for representing structured data
    —High performance encoders/decoders for common protocols. The JSON and
    MessagePack implementations regularly benchmark as the fastest options for Python

    View Slide

  21. 21
    Скорость энкодеров/декодеров

    View Slide

  22. 22
    Валидация

    View Slide

  23. 23
    Память на парсинг 65 мегабайт json

    View Slide

  24. 24
    Рантайм работа с классами

    View Slide

  25. Интересное по рантайм работе
    25
    —Быстро импортируются
    —Создание инстанса оглушительно быстрое (в 50 раз быстрее pydantic)
    —Сравнение от 6 до 500 раз быстрее других альтернатив
    —Сравнение больше, меньше и т.п. быстрее от 10 до 70 раз

    View Slide

  26. View Slide

  27. 27
    Трюки со сборщиком

    View Slide

  28. View Slide

  29. Поговорим о фишках
    библиотеки
    29

    View Slide

  30. 30
    Можно использовать как json декодер
    import msgspec
    # once
    msgspec.json.decode(b'{"hello":"world"}')
    # multiple
    decoder = msgspec.json.Decoder()
    decoder.decode(b'{"hello":"world"}')

    View Slide

  31. 31
    Typed декодер!
    import msgspec
    class User(msgspec.Struct):
    name: str
    groups: set[str] = set()
    email: str | None = None
    msgspec.json.decode(
    b'{"name": "alice", "groups": ["admin", "engineering"]}',
    type=User
    )
    msgspec.json.decode(
    b'{"name": "bill", "groups": ["devops", 123]}',
    type=User
    )
    """
    Traceback (most recent call last):
    File "", line 1, in
    msgspec.ValidationError: Expected `str`, got `int` - at `$.groups[1]`
    """

    View Slide

  32. Lax режим тоже есть
    32

    View Slide

  33. 33
    Struct — основная вещь
    import msgspec
    from typing import Set, Optional
    class User(msgspec.Struct):
    """A struct describing a user"""
    name : str
    email : Optional[str] = None
    groups : Set[str] = set()

    View Slide

  34. 34
    Пример декодинга
    >>> class User2(msgspec.Struct):
    ... name: str
    ... groups: set[str] = set()
    ... email: str | None = None
    ... phone : str | None = None
    ...
    >>> new_dec = msgspec.json.Decoder(User2)
    >>> new_dec.decode('{"name": "kek", "groups": ["a", "b"], "email": "[email protected]", "phone": "+76661313"}')
    User2(name='kek', groups={'a', 'b'}, email='[email protected]', phone='+76661313')

    View Slide

  35. Отдельной строкой:
    адекватный парсинг
    datetime с iso8601
    35

    View Slide

  36. В основном все, что
    есть в pydantic, но +
    сразу decoder/encoder
    36

    View Slide

  37. Есть «ограничения»,
    чем-то похожие на
    strict типы pydantic
    37

    View Slide

  38. Они используют
    typing.Annotated
    38

    View Slide

  39. Есть поддержка toml,
    yaml, msgpack
    39

    View Slide

  40. https://github.com/xfenix/python-kebab-2023/

    View Slide

  41. Зачем нам эта
    информация?
    41

    View Slide

  42. View Slide

  43. View Slide

  44. View Slide

  45. View Slide

  46. #
    Спасибо!
    Подписывайтесь на гитхабе!
    Денис Аникин
    https://xfenix.ru/
    https://github.com/xfenix/

    View Slide