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)
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
serializer = Serializer(A, omit_none=True) # or Serializer(Annotated[A, OmitNone])
print(serializer.dump(A(required_val=None, optional_val=None)))
>>> {'required_val': None}
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.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | e958f6222dbb14051c911a92264176044390038564facbccbf0c7c45f0f4baf6 |
|
MD5 | 063be8a67fc7023789d8f72161e13198 |
|
BLAKE2b-256 | 361c7576cb5054ed3bf6ce0a9652dab55ef57c1eb9f316c90e7c8b9ba35c3d0c |
Hashes for serpyco_rs-0.4.0-cp311-none-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | c7ed265932bdbc2d08d5d01bea4936f4462d840f9dabb7f1a12623afc7cd40f9 |
|
MD5 | 17d7602f2075a1b14c271439dfcd17a0 |
|
BLAKE2b-256 | faed7d39e77edfe630a9293ef1b6bbfe169928116c16dd6c0876cb6a78073969 |
Hashes for serpyco_rs-0.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | dc37bee41cdd03e48dbb5fca39ed0a7ddd27f515024cb949724199ade70c4371 |
|
MD5 | e8879d32815cc76490ff762ce52a7508 |
|
BLAKE2b-256 | d33b1039c8ee72c94aab4c68994c202fb2e9bc158a164f145659d0fd7aecb216 |
Hashes for serpyco_rs-0.4.0-cp311-cp311-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | fd194b3b8f5dc23600ecaf98d4309c72917c4320ae522f0b21276d19dbb1ef0a |
|
MD5 | 6e3a0c8b3444a3e6194c1148b42584a1 |
|
BLAKE2b-256 | 6f2b8ac7dbd9bf06b557c370d491061cd40d7f40c4b1fa9f87d5910a69c244cf |
Hashes for serpyco_rs-0.4.0-cp310-none-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8795fdc1e12e44300b6addeab57449fe4bdfe44fe3d7d4d0087c8514d19b3049 |
|
MD5 | 3ead2459f4390bbf376c03a251ce4200 |
|
BLAKE2b-256 | 5e02d6d2cbfd5c788ca93a7d8247e7d05677faeeadb3a591557c3dfd2dcb37e7 |
Hashes for serpyco_rs-0.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 38c926abf8f1dcf6918ca94481ccfcdc76c2ee4e3c0d6ddd1e3dd52c102e5715 |
|
MD5 | a008d9f7e22d8944d7f6b1fe13f4ea26 |
|
BLAKE2b-256 | 45f4cb0a132c565abc21367f3842a39da3f6c37fe4c59dfe434fcaa4ec739e62 |
Hashes for serpyco_rs-0.4.0-cp310-cp310-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 64dd81180438b312e23688b47d7bd894955fff9d5e769fce93b8557cfbe84770 |
|
MD5 | 83f0853dd4f235a3cf03f3761fc316af |
|
BLAKE2b-256 | 17a05af8581d81c29523af58dcaa382f10c5f252fda741ba69638595951b1502 |
Hashes for serpyco_rs-0.4.0-cp39-none-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 19d52c0639d688169f505fcc04f941a80d1b06f5dea91ca147a458563b123f03 |
|
MD5 | ff22fc66550747c87799f920b9ee3de9 |
|
BLAKE2b-256 | 0c1d9071e2be51aabcb60ab87ded9cb3ce8b50c012c65efda3b1ea1186b35a1b |
Hashes for serpyco_rs-0.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3c6dc37fe59b4d56c0852d8234f2922a2f370d711ce000da80a5b839ee3f66ab |
|
MD5 | 085646a81aed385f028e3ba913364044 |
|
BLAKE2b-256 | 19fe53238a4972e4b28d56b6468f617cc43ee459bd4dfc84ed93b1559c6bdeaa |
Hashes for serpyco_rs-0.4.0-cp39-cp39-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 35e80987b438c9e68138f0b67ee068144470b8745864cee0fac20b8c1bdf585d |
|
MD5 | 93675895b95f7c1a84bf330e281e8ba4 |
|
BLAKE2b-256 | 37f73b2ccc5b6e4223482ef1d7f6e90d8e4d822429002b8dc2e874a094e33d71 |