Skip to main content

Serialization library on top of dataclasses.

Project description

pyserde

image image Build Status Build status Coverage Status

Yet another serialization library on top of dataclasses.

TL;DR

Put additional @serialize and @deserialize decorator in your ordinary dataclass.

@deserialize
@serialize
@dataclass
class Foo:
    i: int
    s: str
    f: float
    b: bool

Now you can convert an object to JSON,

>>> to_json(Foo(i=10, s='foo', f=100.0, b=True))
{"i": 10, "s": "foo", "f": 100.0, "b": true}

Converted back from JSON to the object quite easily!

>>> from_json(Foo, '{"i": 10, "s": "foo", "f": 100.0, "b": true}')
Foo(i=10, s='foo', f=100.0, b=True)

pyserde supports other data formats (YAML, Toml, MsgPack) and offers many more features!

Benchmark

  • macOS 10.14 Mojave
  • Intel 2.3GHz 8-core Intel Core i9
  • DDR4 32GB RAM

Serialize and deserialize a struct into and from json 10,000 times.

Serialize Deserialize

Serialize the struct into tuple and dictionary.

astuple asdict
  • raw: Serialize and deserialize manually. Fastest in theory.
  • dataclass: Serialize using dataclass's asdict.
  • pyserde: This library.
  • dacite: Simple creation of data classes from dictionaries.
  • mashumaro: Fast and well tested serialization framework on top of dataclasses.
  • marshallow: A lightweight library for converting complex objects to and from simple datatypes.
  • attrs: Python Classes Without Boilerplate.
  • cattrs: Complex custom class converters for attrs.

To run benchmark in your environment:

git clone git@github.com:yukinarit/pyserde.git
cd pyserde/bench
pipenv install
pipenv run python bench.py --full

You can check the benchmark code for more information.

Getting started

Install pyserde from PyPI. pyserde requires Python>=3.6.

pip install pyserde

Put additional @serialize and @deserialize decorator in your ordinary dataclass. Be careful that module name is serde, not pyserde. If you are new to dataclass, I would recommend to read dataclasses documentation first.

from serde import serialize, deserialize
from dataclasses import dataclass

@deserialize
@serialize
@dataclass
class Foo:
    i: int
    s: str
    f: float
    b: bool

pyserde generates methods necessary for serialization by @serialize and methods necessary for deserialization by @deserialize when a class is loaded into python interpreter. Generation occurs exactly only once (This is more like how decorator work, not pyserde) and there is no overhead when you actually use the generated methods. Now your class is serializable and deserializable in the data formats supported by pyserde.

Next, import pyserde helper methods. For JSON:

from serde.json import from_json, to_json

Similarly, you can use other data formats.

from serde.yaml import from_yaml, to_yaml
from serde.toml import from_toml, to_toml
from serde.msgpack import from_msgpack to_msgpack

Use to_json to serialize the object into JSON.

f = Foo(i=10, s='foo', f=100.0, b=True)
print(to_json(f))

Pass Foo class and JSON string in from_json to deserialize into Object.

s = '{"i": 10, "s": "foo", "f": 100.0, "b": true}'
print(from_json(Foo, s))

That's it! pyserde offers many more features. If you're interested, please read the rest of the documentation.

Supported types

You can write pretty complex class like this:

@deserialize
@serialize
@dataclass
class bar:
    i: int

@deserialize
@serialize
class Foo:
    i: int
    l: List[str]
    t: Tuple[int, float, str, bool]
    d: Dict[str, List[Tuple[str, int]]]
    o: Optional[str]
    nested: Bar

Supported data formats

JSON

from serde.json import from_json, to_json
print(to_json(f))
print(from_json(Foo, s))

Yaml

from serde.yaml import from_yaml, to_yaml
print(to_yaml(f))
print(from_yaml(Foo, s))

Toml

from serde.toml import from_toml, to_toml
print(to_toml(f))
print(from_toml(Foo, s))

MsgPack

from serde.msgpack import from_msgpack, to_msgpack
print(to_msgpack(f))
print(from_msgpack(Foo, s))

Case Conversion

Converting snake_case fields into supported case styles e.g. camelCase and kebab-case.

@serialize(rename_all = 'camelcase')
@dataclass
class Foo:
    int_field: int
    str_field: str

f = Foo(int_field=10, str_field='foo')
print(to_json(f))

Here, the output is all camelCase.

'{"intField": 10, "strField": "foo"}'

Rename Field

In case you want to use a keyword as field such as class, you can use serde_rename field attribute.

@serialize
@dataclass
class Foo:
    class_name: str = field(metadata={'serde_rename': 'class'})

print(to_json(Foo(class_name='Foo')))

Output json is having class instead of class_name.

{"class": "Foo"}

For complete example, please see ./examples/rename.py

Skip

You can skip serialization for a certain field, you can use serde_skip.

@serialize
@dataclass
class Resource:
    name: str
    hash: str
    metadata: Dict[str, str] = field(default_factory=dict, metadata={'serde_skip': True})

resources = [
    Resource("Stack Overflow", "hash1"),
    Resource("GitHub", "hash2", metadata={"headquarters": "San Francisco"}) ]
print(to_json(resources))

Here, metadata is not present in output json.

[{"name": "Stack Overflow", "hash": "hash1"}, {"name": "GitHub", "hash": "hash2"}]

For complete example, please see ./examples/skip.py

Conditional Skip

If you conditionally skip some fields, you can pass function or lambda in serde_skip_if.

@serialize
@dataclass
class World:
    player: str
    buddy: str = field(default='', metadata={'serde_skip_if': lambda v: v == 'Pikachu'})

world = World('satoshi', 'Pikachu')
print(to_json(world))

world = World('green', 'Charmander')
print(to_json(world))

As you can see below, field is skipped in serialization if buddy is "Pikachu".

{"player": "satoshi"}
{"player": "green", "buddy": "Charmander"}

For complete example, please see ./examples/skip.py

LICENSE

MIT

Project details


Release history Release notifications | RSS feed

This version

0.1.2

Download files

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

Source Distribution

pyserde-0.1.2.tar.gz (24.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyserde-0.1.2-py3-none-any.whl (29.1 kB view details)

Uploaded Python 3

File details

Details for the file pyserde-0.1.2.tar.gz.

File metadata

  • Download URL: pyserde-0.1.2.tar.gz
  • Upload date:
  • Size: 24.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.23.0 setuptools/46.4.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.3

File hashes

Hashes for pyserde-0.1.2.tar.gz
Algorithm Hash digest
SHA256 9183c4993aaa55673251ac0fe66dba3aa838825b49e12923d2fc717cce320ac6
MD5 3cd5bb91f1e3e42658722dd099a96cc3
BLAKE2b-256 7a38f56259c603edf299a9bc9594afc535bb228b2a43f63a6838403f0baaff77

See more details on using hashes here.

File details

Details for the file pyserde-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: pyserde-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 29.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.23.0 setuptools/46.4.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.3

File hashes

Hashes for pyserde-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 5d3131231655511b74b68b7f2a9f543cd431defdff14f6bfdec3b51d16d29ed4
MD5 b65c488bcb7a06a50e79b53ebdf289bf
BLAKE2b-256 a9b1c3c9677fa90a2e760d3e27bf3569c2c1ee9cd0f4179815682b68aeb4d5c3

See more details on using hashes here.

Supported by

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