Skip to main content

Simple Python dataclass serialization package with no dependencies

Project description

StupidSimple Dataclasses Codec

PyPI version Python versions License: MIT Tests codecov

This native Python package allows to easily convert dataclasses into and from a serialized form. By default supports json.

Installation

pip install dataclasses-codec

Usage

The package provides functions to easily convert dataclasses into and from a serialized form. It uses by default the json_codec instance the package provides.

from dataclasses import dataclass
from dataclasses_codec import encode, decode, to_json, from_json

@dataclass
class MyDataclass:
    first_name: str
    last_name: str

obj = MyDataclass("John", "Doe")

# Serializable Python dictionary. JSON by default.
encoded = encode(obj)
print(encoded)
# Output: {"first_name": "John", "last_name": 'Doe'}

decoded = decode(MyDataclass, encoded)
print(decoded)
# Output: MyDataclass(first_name="John", last_name="Doe")

# Native JSON handling

raw_json = to_json(obj)
print(raw_json)
# Output: '{"first_name": "John", "last_name": "Doe"}'

restored = from_json(MyDataclass, raw_json)
print(restored)
# Output: MyDataclass(first_name="John", last_name="Doe")

JSON codec

The JSON codec is a first class citizen of the package. It allows to easily convert dataclasses into and from JSON strings.

Serialization can be customized by using the json_field value. It supports native conversion of:

  • Types already supported by the native json module.
  • date
  • datetime
  • timedelta
  • Decimal
  • UUID
  • Path

Dataclasses can be nested to form complex objects. It supports list, tuple, dict and Union types.

json_field extends the native dataclass field decorator to support custom serialization and deserialization.

from dataclasses import dataclass
from dataclasses_codec import json_codec, JSONOptional, JSON_MISSING
from dataclasses_codec.codecs.json import json_field
import datetime as dt

# Still a dataclass, so we can use its features like slots, frozen, etc.
@dataclass(slots=True)
class MyMetadataDataclass:
    created_at: dt.datetime = field( # Dataclasses fields can be used as usual
        default_factory=lambda: dt.datetime.now()
    )
    updated_at: dt.datetime = json_field( # Json field also supports dataclasses field features.
        default_factory=lambda: dt.datetime.now(),
        serializer=lambda d: d.isoformat(), # Custom serializer to isoformat
        deserializer=lambda s: dt.datetime.fromisoformat(s)
    )
    enabled: bool | JSONOptional = JSON_MISSING # Explicitly mark a field as optional
    description: str | None = None # None is intentionally serialized as null


@dataclass
class MyDataclass:
    first_name: str
    last_name: str
    age: int
    metadata: MyMetadataDataclass = json_field(
        json_name="meta"
    )

obj = MyDataclass("John", "Doe", 30, MyMetadataDataclass(dt.datetime.now(), dt.datetime.now()))

raw_json = json_codec.to_json(obj)
print(raw_json)
# Output: '{"first_name": "John", "last_name": "Doe", "age": 30, "meta": {"created_at": "2025-10-25T11:53:35.918899", "updated_at": "2025-10-25T11:53:35.918902", "description": null}}'

JSON Mixins

The package provides JSON mixins to add the serialization and deserialization capabilities to a dataclass.

By default, the JSON codec is used. See: dataclasses_codec.codecs.json for more details.

from dataclasses import dataclass
from dataclasses_codec import JSONSerializable, JSONDeserializable

@dataclass
class MyDataclass(JSONSerializable, JSONDeserializable):
    first_name: str
    last_name: str
    age: int

obj = MyDataclass("John", "Doe", 30)

encoded = obj.to_dict(to_camel_case=True)
print(encoded)
# Output: {'firstName': 'John', 'lastName': 'Doe', 'age': 30}

restored = MyDataclass.from_dict(encoded, to_snake_case=True)
print(restored)
# Output: MyDataclass(first_name="John", last_name="Doe", age=30)

Extensibility

The package allows to extend the functionality of the codecs by implementing the Codec interface.

Each implementation should use is_dataclass to check if the object is a dataclass.

from dataclasses import dataclass, is_dataclass
from dataclasses_codec import Codec, encode
from dataclasses_codec.errors import CodecError

class MyCodec(Codec):
    def encode(self, obj, **kwargs):
        if not is_dataclass(obj):
            raise CodecError(f"obj is not a dataclass, found: '{obj}'")
        return obj
    def decode(self, cls, data, **kwargs):
        # Implement the decoding logic here
        raise CodecError("Decoding is not implemented for this codec")

@dataclass
class MyDataclass:
    first_name: str
    last_name: str
    age: int

obj = MyDataclass("John", "Doe", 30)

encoded = encode(obj, codec=MyCodec())
print(encoded)
# Output: {'first_name': 'John', 'last_name': 'Doe', 'age': 30}

Development

Running the tests

python -m unittest

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

dataclasses_codec-1.1.0.tar.gz (11.9 kB view details)

Uploaded Source

Built Distribution

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

dataclasses_codec-1.1.0-py3-none-any.whl (8.6 kB view details)

Uploaded Python 3

File details

Details for the file dataclasses_codec-1.1.0.tar.gz.

File metadata

  • Download URL: dataclasses_codec-1.1.0.tar.gz
  • Upload date:
  • Size: 11.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for dataclasses_codec-1.1.0.tar.gz
Algorithm Hash digest
SHA256 86d82d40456d49977f99c51a443a461ea22582fe7b605628e8d15d8e54185e82
MD5 0e52027a832088acd97b631705f64a43
BLAKE2b-256 97f967394ff26b6f0acc3bd67c217e9d3e3009d9112b1c535ef6ba3d58844144

See more details on using hashes here.

Provenance

The following attestation bundles were made for dataclasses_codec-1.1.0.tar.gz:

Publisher: publish.yml on stupid-simple/dataclasses-codec

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dataclasses_codec-1.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for dataclasses_codec-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8c91251464802479e8963c0b9b5ed99ea989757250165ca1b265bd2ab9f21a62
MD5 7079c2c9eafd8e48606dc01e35a4a738
BLAKE2b-256 697434e050582f6786a8cfbc3814c13358d972bab97826c8517d126ad23985e5

See more details on using hashes here.

Provenance

The following attestation bundles were made for dataclasses_codec-1.1.0-py3-none-any.whl:

Publisher: publish.yml on stupid-simple/dataclasses-codec

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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