Skip to main content

No project description provided

Project description

serpyco-rs: a serializer for python dataclasses

PyPI version Python versions CI status

What is serpyco-rs ?

Serpyco is a serialization library for Python 3.9+ dataclasses that works just by defining your dataclasses:

import dataclasses
import serpyco_rs

@dataclasses.dataclass
class Example:
    name: str
    num: int
    tags: list[str]


serializer = serpyco_rs.Serializer(Example)

result = serializer.dump(Example(name="foo", num=2, tags=["hello", "world"]))
print(result)

>> {'name': 'foo', 'num': 2, 'tags': ['hello', 'world']}

Inspired by serpyco.

serpyco-rs works by analysing the dataclass fields and can recognize many types : list, tuple, Optional... You can also embed other dataclasses in a definition.

The main use-case for serpyco-rs is to serialize objects for an API, but it can be helpful whenever you need to transform objects to/from builtin Python types.

Installation

Use pip to install:

$ pip install serpyco-rs

Features

  • Serialization and deserialization of dataclasses
  • Validation of input data
  • Very fast
  • Support recursive schemas
  • Generate JSON Schema Specification (Draft 2020-12)
  • Support custom encoders/decoders for fields

Supported field types

There is support for generic types from the standard typing module:

  • Decimal
  • UUID
  • Time
  • Date
  • DateTime
  • Enum
  • List
  • Dict
  • Bytes (pass through)
  • TypedDict
  • Mapping
  • Sequence
  • Tuple (fixed size)
  • Literal[str, ...]
  • Tagged unions (restricted)

Benchmarks

Linux

Load

Library Median latency (milliseconds) Operations per second Relative (latency)
serpyco_rs 0.16 6318.1 1
mashumaro 0.45 2244.4 2.81
pydantic 0.57 1753.9 3.56
serpyco 0.82 1228.3 5.17
marshmallow 8.49 117.4 53.35

Dump

Library Median latency (milliseconds) Operations per second Relative (latency)
serpyco_rs 0.07 13798 1
serpyco 0.07 13622 1.02
mashumaro 0.1 10219.5 1.36
pydantic 0.22 4615.5 2.99
marshmallow 2 497 27.69
MacOS macOS Monterey / Apple M1 Pro / 16GB RAM / Python 3.11.0

Load

Library Median latency (milliseconds) Operations per second Relative (latency)
serpyco_rs 0.1 9865.1 1
mashumaro 0.2 4968 2
pydantic 0.34 2866.7 3.42
serpyco 0.69 1444.1 6.87
marshmallow 4.14 241.8 41.05

Dump

Library Median latency (milliseconds) Operations per second Relative (latency)
serpyco_rs 0.04 22602.6 1
serpyco 0.05 21232.9 1.06
mashumaro 0.06 15903.4 1.42
pydantic 0.16 6262.6 3.61
marshmallow 1.04 962 23.5

Supported annotations

serpyco-rs supports changing load/dump behavior with typing.Annotated.

Currently available:

  • Alias
  • FieldFormat (CamelCase / NoFormat)
  • NoneFormat (OmitNone / KeepNone)
  • Discriminator
  • Min / Max
  • MinLength / MaxLength
  • CustomEncoder
  • NoneAsDefaultForOptional (ForceDefaultForOptional)

Alias

Alias is needed to override the field name in the structure used for load / dump.

from dataclasses import dataclass
from typing import Annotated
from serpyco_rs import Serializer
from serpyco_rs.metadata import Alias

@dataclass
class A:
    foo: Annotated[int, Alias('bar')]

ser = Serializer(A)

print(ser.load({'bar': 1}))
>> A(foo=1)

print(ser.dump(A(foo=1)))
>> {'bar': 1}

FieldFormat

Used to have response bodies in camelCase while keeping your python code in snake_case.

from dataclasses import dataclass
from typing import Annotated
from serpyco_rs import Serializer
from serpyco_rs.metadata import CamelCase, NoFormat

@dataclass
class B:
    buz_filed: str

@dataclass
class A:
    foo_filed: int
    bar_filed: Annotated[B, NoFormat]

ser = Serializer(Annotated[A, CamelCase])  # or ser = Serializer(A, camelcase_fields=True)

print(ser.dump(A(foo_filed=1, bar_filed=B(buz_filed='123'))))
>> {'fooFiled': 1, 'barFiled': {'buz_filed': '123'}}

print(ser.load({'fooFiled': 1, 'barFiled': {'buz_filed': '123'}}))
>> A(foo_filed=1, bar_filed=B(buz_filed='123'))

NoneFormat

Via OmitNone we can drop None values for non required fields in the serialized dicts

from dataclasses import dataclass
from serpyco_rs import Serializer

@dataclass
class A:
    required_val: bool | None
    optional_val: bool | None = None

ser = Serializer(A, omit_none=True) # or Serializer(Annotated[A, OmitNone])

print(ser.dump(A(required_val=None, optional_val=None)))
>>> {'required_val': None}

Tagged unions

Supports tagged joins with discriminator field.

All classes in the union must be dataclasses or attrs with discriminator field Literal[str].

The discriminator field is always mandatory.

from typing import Annotated, Literal
from dataclasses import dataclass
from serpyco_rs import Serializer
from serpyco_rs.metadata import Discriminator

@dataclass
class Foo:
    type: Literal['foo']
    value: int

@dataclass(kw_only=True)
class Bar:
    type: Literal['bar'] = 'bar'
    value: str

ser = Serializer(list[Annotated[Foo | Bar, Discriminator('type')]])

print(ser.load([{'type': 'foo', 'value': 1}, {'type': 'bar', 'value': 'buz'}]))
>>> [Foo(type='foo', value=1), Bar(type='bar', value='buz')]

Min / Max

Supported for int / float / Decimal types and only for validation on load.

from typing import Annotated
from serpyco_rs import Serializer
from serpyco_rs.metadata import Min, Max

ser = Serializer(Annotated[int, Min(1), Max(10)])

ser.load(123)
>> SchemaValidationError: [ErrorItem(message='123 is greater than the maximum of 10', instance_path='')]

MinLength / MaxLength

MinLength / MaxLength can be used to restrict the length of loaded strings.

from typing import Annotated
from serpyco_rs import Serializer
from serpyco_rs.metadata import MinLength

ser = Serializer(Annotated[str, MinLength(5)])

ser.load("1234")
>> SchemaValidationError: [ErrorItem(message='"1234" is shorter than 5 characters', instance_path='')]

NoneAsDefaultForOptional

ForceDefaultForOptional / KeepDefaultForOptional can be used to set None as default value for optional (nullable) fields.

from dataclasses import dataclass
from serpyco_rs import Serializer


@dataclass
class Foo:
    val: int                 # not nullable + required
    val1: int | None         # nullable + required
    val2: int | None = None  # nullable + not required

ser_force_default = Serializer(Foo, force_default_for_optional=True)  # or Serializer(Annotated[Foo, ForceDefaultForOptional])
ser = Serializer(Foo)

# all fields except val are optional and nullable
assert ser_force_default.load({'val': 1}) == Foo(val=1, val1=None, val2=None) 

# val1 field is required and nullable and val1 should be present in the dict
ser.load({'val': 1})
>> SchemaValidationError: [ErrorItem(message='"val1" is a required property', instance_path='')]

Custom encoders for fields

You can provide CustomEncoder with serialize and deserialize functions, or serialize_with and deserialize_with annotations.

from typing import Annotated
from dataclasses import dataclass
from serpyco_rs import Serializer
from serpyco_rs.metadata import CustomEncoder

@dataclass
class Foo:
    val: Annotated[str, CustomEncoder[str, str](serialize=str.upper, deserialize=str.lower)]

ser = Serializer(Foo)
val = ser.dump(Foo(val='bar'))
>> {'val': 'BAR'}
assert ser.load(val) == Foo(val='bar') 

Note: CustomEncoder has no effect to validation and JSON Schema generation.

Bytes fields

serpyco-rs can loads bytes fields as is (without base64 encoding and validation).

from dataclasses import dataclass
from serpyco_rs import Serializer

@dataclass
class Foo:
    val: bytes

ser = Serializer(Foo)
ser.load({'val': b'123'}) == Foo(val=b'123')

Getting JSON Schema

serpyco-rs can generate JSON Schema for your dataclasses (Draft 2020-12).

from dataclasses import dataclass
from serpyco_rs import Serializer

@dataclass
class A:
    """Description of A"""
    foo: int
    bar: str

ser = Serializer(A)

print(ser.get_json_schema())
>> {
    '$schema': 'https://json-schema.org/draft/2020-12/schema', 
    '$ref': '#/components/schemas/A[no_format,keep_nones]', 
    'components': {
        'schemas': {
            'A[no_format,keep_nones]': {
                'properties': {
                    'foo': {'type': 'integer'}, 
                    'bar': {'type': 'string'}
                }, 
                'required': ['foo', 'bar'], 
                'type': 'object', 
                'description': 'Description of A'
            }
        }
    }
}

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

serpyco_rs-1.1.1.tar.gz (60.1 kB view details)

Uploaded Source

Built Distributions

serpyco_rs-1.1.1-cp312-none-win_amd64.whl (309.3 kB view details)

Uploaded CPython 3.12 Windows x86-64

serpyco_rs-1.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (857.7 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.17+ x86-64

serpyco_rs-1.1.1-cp312-cp312-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl (891.6 kB view details)

Uploaded CPython 3.12 macOS 10.9+ universal2 (ARM64, x86-64) macOS 10.9+ x86-64 macOS 11.0+ ARM64

serpyco_rs-1.1.1-cp311-none-win_amd64.whl (305.4 kB view details)

Uploaded CPython 3.11 Windows x86-64

serpyco_rs-1.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (861.0 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64

serpyco_rs-1.1.1-cp311-cp311-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl (901.8 kB view details)

Uploaded CPython 3.11 macOS 10.9+ universal2 (ARM64, x86-64) macOS 10.9+ x86-64 macOS 11.0+ ARM64

serpyco_rs-1.1.1-cp310-none-win_amd64.whl (305.4 kB view details)

Uploaded CPython 3.10 Windows x86-64

serpyco_rs-1.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (861.0 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

serpyco_rs-1.1.1-cp310-cp310-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl (901.8 kB view details)

Uploaded CPython 3.10 macOS 10.9+ universal2 (ARM64, x86-64) macOS 10.9+ x86-64 macOS 11.0+ ARM64

serpyco_rs-1.1.1-cp39-none-win_amd64.whl (304.9 kB view details)

Uploaded CPython 3.9 Windows x86-64

serpyco_rs-1.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (860.9 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64

serpyco_rs-1.1.1-cp39-cp39-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl (901.2 kB view details)

Uploaded CPython 3.9 macOS 10.9+ universal2 (ARM64, x86-64) macOS 10.9+ x86-64 macOS 11.0+ ARM64

File details

Details for the file serpyco_rs-1.1.1.tar.gz.

File metadata

  • Download URL: serpyco_rs-1.1.1.tar.gz
  • Upload date:
  • Size: 60.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.3.1

File hashes

Hashes for serpyco_rs-1.1.1.tar.gz
Algorithm Hash digest
SHA256 6b7a9ac165cbdd84be1c653d13b7df1328f415e231de29829bf9587ac7e42582
MD5 814c979d4351daa59d4112773196ee4b
BLAKE2b-256 b2c42f19da8563965157424f7224f152fd25413b2a0eef51a966586243691014

See more details on using hashes here.

File details

Details for the file serpyco_rs-1.1.1-cp312-none-win_amd64.whl.

File metadata

File hashes

Hashes for serpyco_rs-1.1.1-cp312-none-win_amd64.whl
Algorithm Hash digest
SHA256 1f2008e53593e19f0026071a8eb9b7750f6413bca656db096eda6be91f8ad095
MD5 d7b4e3725b783c74bfc0e21a37581f25
BLAKE2b-256 38e335dfce57053e730600519a90868fef36458549f79a286a80aba234a5a03b

See more details on using hashes here.

File details

Details for the file serpyco_rs-1.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for serpyco_rs-1.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 1a9a62c7d4a15701edb537adbd842768b51ba80220e5bda61d0f3c5b08bdb442
MD5 0c5ad8839a031a810baf04551e1a8a7e
BLAKE2b-256 1c7b47951cf31bc9d7a3f7470e21fca0cff730f1fe4b769592bb2d0105310187

See more details on using hashes here.

File details

Details for the file serpyco_rs-1.1.1-cp312-cp312-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for serpyco_rs-1.1.1-cp312-cp312-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 ec52b6508416ae648e6d2eea6b15bb096ed62d93dd8222af4df98b0b921ce46b
MD5 d7bcea4e725a4de233972c69868e6e66
BLAKE2b-256 5e4ef3c7540e9a220848fa0cc2a6effbaee41c1ef59c9b195f27033a0856909d

See more details on using hashes here.

File details

Details for the file serpyco_rs-1.1.1-cp311-none-win_amd64.whl.

File metadata

File hashes

Hashes for serpyco_rs-1.1.1-cp311-none-win_amd64.whl
Algorithm Hash digest
SHA256 8999674d2eda55f161576d5d280862c06d3a221702d47e5ae0b42b32a655662d
MD5 e5391f9860dbcfa8cdffc403e0628b0e
BLAKE2b-256 f0817094c026105518cd79651280f611ed8acfef3939a0361fb2de6c4d6ada81

See more details on using hashes here.

File details

Details for the file serpyco_rs-1.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for serpyco_rs-1.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 934aa444dfeb8bf882195413dd75bf606beb6e774f8c251b08fc7393ca4b932a
MD5 6106a397271e9cf30a06879a32a0664f
BLAKE2b-256 41ebd97628b700dc269ffe0d91bf5808c6e62f00c04f519f955d98ffbaffaf42

See more details on using hashes here.

File details

Details for the file serpyco_rs-1.1.1-cp311-cp311-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for serpyco_rs-1.1.1-cp311-cp311-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 ff49f32de1e2face53900dcc693c44d28fe170426fca2f1b49ab0b1d7186cfe8
MD5 1d75a085facfc9f0020c64e6ab8822d6
BLAKE2b-256 be19daca50366507d32f51c098bc7c5c2fcceeed862e846b4aeb20c43c27db10

See more details on using hashes here.

File details

Details for the file serpyco_rs-1.1.1-cp310-none-win_amd64.whl.

File metadata

File hashes

Hashes for serpyco_rs-1.1.1-cp310-none-win_amd64.whl
Algorithm Hash digest
SHA256 f95b6afe2ac93ca13c5919b3c406d1b3518953811999deeb2031366dce8bc050
MD5 73e2ae165863b82ff130fe717df7a968
BLAKE2b-256 5363fb4b621d553fa5ba7daffa8a716813aadc71e4ad6ef20a86ab2c0e81a5f0

See more details on using hashes here.

File details

Details for the file serpyco_rs-1.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for serpyco_rs-1.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 31d2d7789929853ff05f0abc2be49549ba89316405739f2814ce0003cee83642
MD5 0c08f990e24ed4d89286cf2d3f5b610a
BLAKE2b-256 d1d2a92b995eb0f94af94b9e0c5db11cca606e992876d925ea70fdef55d13c7d

See more details on using hashes here.

File details

Details for the file serpyco_rs-1.1.1-cp310-cp310-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for serpyco_rs-1.1.1-cp310-cp310-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 25ca9cd0fdba762ea70af0fb20869c11b8eb53fb059df1efbae531ea2926b427
MD5 37ed7e9babc5c29738b8fe019a54f30d
BLAKE2b-256 4f315831f6e0ecf72e28aef962c37fd7f7aa82ba270bb48eba634be807b2b5a0

See more details on using hashes here.

File details

Details for the file serpyco_rs-1.1.1-cp39-none-win_amd64.whl.

File metadata

File hashes

Hashes for serpyco_rs-1.1.1-cp39-none-win_amd64.whl
Algorithm Hash digest
SHA256 30625ba99b365a3b627e827d56c55879fc8133c7e6b1c5c337baeaef6cf32f7e
MD5 7f14c7fd3dfaf6e5858438f13e376e55
BLAKE2b-256 ee1c54aaecd84ead6f4a13e8780768bf84a7122d7429873c1e87de548838a69a

See more details on using hashes here.

File details

Details for the file serpyco_rs-1.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for serpyco_rs-1.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 fb00e72d0e1645e8aff871304581ced8be75653960bad38b1d1e605b5e625af7
MD5 ad338c0968c5f81cae54eb5b1c3570de
BLAKE2b-256 44d40b006b20f470499a3b1922ddd4bd7dbebf484a7d2274c29e7ea8359b92f9

See more details on using hashes here.

File details

Details for the file serpyco_rs-1.1.1-cp39-cp39-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for serpyco_rs-1.1.1-cp39-cp39-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 73c96bdb8435d5bdd510b6be8b7c941c15b076736d2bca9419f1009dd047d07e
MD5 fc3487a512cdef22ba045baee8106493
BLAKE2b-256 9ba100913d0fb93288929496dd0ff707699d0e3b9e3e6dfed0724cf78d8c0c61

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page