No project description provided
Project description
serpyco-rs: a serializer for python dataclasses
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']}
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/output data
- Very fast
- Support recursive schemas
Supported field types
There is support for generic types from the standard typing module:
- Decimal
- UUID
- Time
- Date
- DateTime
- Enum
- List
- Dict
- Mapping
- Sequence
- Tuple (fixed size)
- Literal[str, ...]
- Tagged unions (restricted)
Benchmark
macOS Monterey / Apple M1 Pro / 16GB RAM / Python 3.11.0
dump
Library | Median latency (milliseconds) | Operations per second | Relative (latency) |
---|---|---|---|
serpyco_rs | 0.05 | 22188.2 | 1 |
serpyco | 0.05 | 20878.5 | 1.06 |
mashumaro | 0.06 | 15602.7 | 1.42 |
pydantic | 2.66 | 375.6 | 59 |
marshmallow | 1.05 | 951.7 | 23.33 |
load with validate
Library | Median latency (milliseconds) | Operations per second | Relative (latency) |
---|---|---|---|
serpyco_rs | 0.23 | 4400.1 | 1 |
serpyco | 0.28 | 3546.4 | 1.24 |
mashumaro | 0.23 | 4377.7 | 1.01 |
pydantic | 2.01 | 497.3 | 8.86 |
marshmallow | 4.55 | 219.9 | 20.03 |
load (only serpyco and serpyco_rs supported load without validate)
Library | Median latency (milliseconds) | Operations per second | Relative (latency) |
---|---|---|---|
serpyco_rs | 0.07 | 13882.9 | 1 |
serpyco | 0.08 | 12424.5 | 1.12 |
mashumaro | 0.23 | 4382.9 | 3.17 |
pydantic | 2.02 | 494.4 | 28.09 |
marshmallow | 4.59 | 217.5 | 63.8 |
Supported annotations
serpyco-rs
supports changing load/dump behavior with typing.Annotated
.
Currently available:
- Alias
- FiledFormat (CamelCase / NoFormat)
- NoneFormat (OmitNone / KeepNone)
- Min / Max
- MinLength / MaxLength
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}
FiledFormat
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='', schema_path='maximum')]
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='', schema_path='minLength')]
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Hashes for serpyco_rs-0.7.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | f1cef838c7b0a71f5c2109693926d9cf6b8115288991de5b0144d7d4dc3e79ae |
|
MD5 | 8a26db12503baf5ee2ffd3add1cf7720 |
|
BLAKE2b-256 | 48dffa364529ed0d8afe4fb54c268359fe9dca34b692a6565e91c2feb0aba17d |
Hashes for serpyco_rs-0.7.0-cp311-none-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 617f0c200572857bda197dd5b81820f6257df81c5affee08d802102191d5304f |
|
MD5 | 0a34e21fba1879da54ef32c90ecc2d71 |
|
BLAKE2b-256 | 888f2882175bc5b2b569a8ab68467dbf081b1ce446a89582d95c70068c17c2f5 |
Hashes for serpyco_rs-0.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1e3aa1bcc8673b24fb85522d5dacd34b9decc9c8003ee9f63a78487471d26958 |
|
MD5 | da035214db22f7a95bfe53e5b4b6fede |
|
BLAKE2b-256 | 2db571df9738ab9388fecbf2caa3e386fbae8df11463850aaa58f1c0eb1dd1bf |
Hashes for serpyco_rs-0.7.0-cp311-cp311-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b45c48d9eae800e908c593ce6e97d206603ea9776dc1232e0f5be95b1d27aca7 |
|
MD5 | 7b73efdbea6d88e1db7952a053933bc2 |
|
BLAKE2b-256 | 91b738f5a162a59d604ab8f68bf9955cf4a5333034f1551031f431886ff73719 |
Hashes for serpyco_rs-0.7.0-cp310-none-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | ed198128a918c39459a94e75bed4121eaec57e1e248a8a7611bcd12fb6a964f5 |
|
MD5 | 04c08276232a0fae8122b6aa96025bbb |
|
BLAKE2b-256 | 5e37d12f05ccb68e4fb970cf9412839ffa0cba531cad7bea11f7b3e9370e8c1d |
Hashes for serpyco_rs-0.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9340d9edcbeb4c8e852983ec97295ac73266b5da61f690b6e8836f872929a4e6 |
|
MD5 | 496256f71aabdcd6ba027ebbc02f8208 |
|
BLAKE2b-256 | fcf65035599998fa40e4a58c87566828a81c08e084e1d7183d6290f0e1581df0 |
Hashes for serpyco_rs-0.7.0-cp310-cp310-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 979107df19a6c4e7bb040646d584ae8c1a0920345514b416eafbab5afdf90cd4 |
|
MD5 | 21d9c5853f8b3a3e11129a9e4b03f235 |
|
BLAKE2b-256 | 0a2cf72293f3f2abc95dfe56bbdf3796d6e89723444d691c65a9229d98455619 |
Hashes for serpyco_rs-0.7.0-cp39-none-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 067a7b6dd2b4947cf785489cf54afddbd144919012cd7783face2e2696cdd1cd |
|
MD5 | 2c4d34ac171827702ac2d7b2c71f41b9 |
|
BLAKE2b-256 | 0f3c1e17c0b1ff32acb2903d95f2def9ead45f517cf9c951dbb87e2b8ef08236 |
Hashes for serpyco_rs-0.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 25d1523bd27c8fccd73b03141827058c59b5e1d13905988acd7f162f78e7b009 |
|
MD5 | addb29c523c92cba25e656daa455d06b |
|
BLAKE2b-256 | c26797145c9467fced064ce86dcac3f3330a51d52a5e02807e29b5e49af262d5 |
Hashes for serpyco_rs-0.7.0-cp39-cp39-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1997a2d73bb7e1696820f9701bbfe88020f6fcad4493b9c04018edb52b48301b |
|
MD5 | c19696819a5c20e4ce87bef0f463ba87 |
|
BLAKE2b-256 | 7f42df094451d54a639233ffae577e3ee3d4033273e06eaac8f1d1e6d76fbfde |