Skip to main content

Serialize with type annotations

Project description

type-serialize

PyPI PyPI - Python Version GitHub

Serialize with type annotations

Features

  • Supported in Python 3.8 and later.
  • Serialize classes without additional code.
  • Deserialization using type annotations.
  • Compress serialization results: bz2, gzip, lzma, zlib
  • No dependencies

Overview

To pass a custom object to the json.dumps and json.loads functions, there is the following method.

Both methods require additional code and have some problems.

  • Problem of not checking symbols when manipulating strings.
  • When adding/deleting/editing a property, all related codes must be changed together.
  • Painful typecasting (as the biggest problem).

As a way to hide these problems with a library and use serialization and deserialization, I chose type annotations. (Although the library is complicated; haha...) There are some additional advantages to using this.

  • Static type checking using mypy.
  • Autocomplete in IDE like PyCharm.

Things to know

  • All public fields are serialized.
  • Methods are not serialized.
  • Private fields that start with an underscore (_) are not serialized.
  • Members specified with the @property decorator are not serialized.
  • When deserializing, all fields must be type-annotated.
  • A value of None is ignored by the serialization target.
  • When deserializing, the __init__ function must have NO required arguments.
  • Implement __serialize__ to override the serialization method.
  • Implement __deserialize__ to override the deserialization method.

Installation

pip install type-serialize

If you want to add numpy, orjson, msgpack, pyyaml support:

pip install type-serialize[full]

Usage

Serializable python object

from dataclasses import dataclass
from type_serialize import deserialize, serialize


@dataclass
class Sample:
    field1: str
    field2: int


data = Sample(field1="a", field2=100)
obj = serialize(data)
assert isinstance(obj, dict)
assert obj["field1"] == "a"
assert obj["field2"] == 100
print(obj)

result = deserialize(obj, Sample)
assert isinstance(result, Sample)
assert data == result
print(result)

Override serialize and deserialize

from dataclasses import dataclass
from type_serialize import deserialize, serialize


@dataclass
class Sample:
    value: int

    def __serialize__(self):
        return {"a": self.value}

    def __deserialize__(self, data) -> None:
        self.value = data["a"]

    def __init__(self, value=100):
        self.value = value


test = Sample(value=200)
obj = serialize(test)
assert isinstance(obj, dict)
assert obj["a"] == 200
print(obj)

result = deserialize(obj, Sample)
assert isinstance(result, Sample)
assert test == result
print(result)

JSON dumps/loads

from dataclasses import dataclass
from type_serialize.json import dumps, loads

@dataclass
class Sample:
    field1: str
    field2: int


data = Sample(field1="a", field2=100)
json_data = dumps(data)
print(json_data)

result = loads(json_data, Sample)
print(result)

MsgPack dumps/loads

from dataclasses import dataclass
from type_serialize.msgpack import dumps, loads

@dataclass
class Sample:
    field1: str
    field2: int


data = Sample(field1="a", field2=100)
json_data = dumps(data)
print(json_data)

result = loads(json_data, Sample)
print(result)

Binary encode/decode

from dataclasses import dataclass
from datetime import datetime
from typing import Any, List, Optional

from type_serialize import decode, encode


@dataclass
class Sample:
    field1: str
    field2: Optional[str] = None
    field3: Optional[List[int]] = None
    field4: Optional[Any] = None
    field5: Optional[datetime] = None


data = Sample(
    field1="a",
    field3=[0, 1, 2],
    field4={"k": 100},
    field5=datetime.now(),
)

raw = encode(data)
assert isinstance(raw, bytes)
assert len(raw) > 0
print(raw)

result = decode(raw, Sample)
assert isinstance(result, Sample)
assert data == result
print(result)

The encoding format can be adjusted with the coding argument.

from type_serialize import ByteCoding, decode, encode

data = ...
print(encode(data, coding=ByteCoding.MsgpackGzip))

encoded_data = ...
print(decode(encoded_data, coding=ByteCoding.OrjsonZlib))

orjson support

If orjson is installed, it is automatically detected and used.

To turn off this option, set the TYPE_SERIALIZE_DISABLE_ORJSON_INSTALL environment variable to 1.

License

See the LICENSE file for details. In summary, type-serialize is licensed under the MIT license.

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

type_serialize-1.3.0-py3-none-any.whl (26.7 kB view hashes)

Uploaded Python 3

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