# StupidSimple Dataclasses Codec
[](https://pypi.org/project/dataclasses-codec/)
[](https://pypi.org/project/dataclasses-codec/)
[](https://opensource.org/licenses/MIT)
[](https://github.com/stupid-simple/dataclasses-codec/actions/workflows/test.yml)
[](https://codecov.io/gh/stupid-simple/dataclasses-codec)
This native Python package allows to easily convert dataclasses into and from a serialized form. By default supports json.
## Installation
```bash
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.
```python
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
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 `date` and `datetime` fields. Dataclasses can be nested to form complex objects.
`json_field` extends the native dataclass `field` decorator to support custom serialization and deserialization.
```python
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
updated_at: dt.datetime = json_field(
serializer=lambda d: d.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.
```python
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.
```python
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
```bash
python -m unittest
```
Raw data
{
"_id": null,
"home_page": null,
"name": "dataclasses-codec",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "codec, dataclass, decoder, encoder, json, serialization",
"author": null,
"author_email": "i-segura <github@m.isu101.com>",
"download_url": "https://files.pythonhosted.org/packages/00/44/36ab7ec8ad4806d8b1686c17899c718c247c07eb9eca1202b5a45bf38275/dataclasses_codec-1.0.0.tar.gz",
"platform": null,
"description": "# StupidSimple Dataclasses Codec\n\n[](https://pypi.org/project/dataclasses-codec/)\n[](https://pypi.org/project/dataclasses-codec/)\n[](https://opensource.org/licenses/MIT)\n[](https://github.com/stupid-simple/dataclasses-codec/actions/workflows/test.yml)\n[](https://codecov.io/gh/stupid-simple/dataclasses-codec)\n\nThis native Python package allows to easily convert dataclasses into and from a serialized form. By default supports json.\n\n## Installation\n\n```bash\npip install dataclasses-codec\n```\n\n## Usage\n\nThe package provides functions to easily convert dataclasses into and from a serialized form. It uses by default the `json_codec` instance the package provides.\n\n```python\nfrom dataclasses import dataclass\nfrom dataclasses_codec import encode, decode, to_json, from_json\n\n@dataclass\nclass MyDataclass:\n first_name: str\n last_name: str\n\nobj = MyDataclass(\"John\", \"Doe\")\n\n# Serializable Python dictionary\nencoded = encode(obj)\nprint(encoded)\n# Output: {'first_name': 'John', 'last_name': 'Doe'}\n\ndecoded = decode(MyDataclass, encoded)\nprint(decoded)\n# Output: MyDataclass(first_name=\"John\", last_name=\"Doe\")\n\n# Native JSON handling\n\nraw_json = to_json(obj)\nprint(raw_json)\n# Output: '{\"first_name\": \"John\", \"last_name\": \"Doe\"}'\n\nrestored = from_json(MyDataclass, raw_json)\nprint(restored)\n# Output: MyDataclass(first_name=\"John\", last_name=\"Doe\")\n```\n\n### JSON codec\n\nThe JSON codec is a first class citizen of the package. It allows to easily convert dataclasses into and from JSON strings.\n\nSerialization can be customized by using the `json_field` value. It supports native conversion of `date` and `datetime` fields. Dataclasses can be nested to form complex objects.\n\n`json_field` extends the native dataclass `field` decorator to support custom serialization and deserialization.\n\n```python\nfrom dataclasses import dataclass\nfrom dataclasses_codec import json_codec, JSONOptional, JSON_MISSING\nfrom dataclasses_codec.codecs.json import json_field\nimport datetime as dt\n\n# Still a dataclass, so we can use its features like slots, frozen, etc.\n@dataclass(slots=True)\nclass MyMetadataDataclass:\n created_at: dt.datetime\n updated_at: dt.datetime = json_field(\n serializer=lambda d: d.isoformat(),\n deserializer=lambda s: dt.datetime.fromisoformat(s)\n )\n enabled: bool | JSONOptional = JSON_MISSING # Explicitly mark a field as optional\n description: str | None = None # None is intentionally serialized as null\n\n\n@dataclass\nclass MyDataclass:\n first_name: str\n last_name: str\n age: int\n metadata: MyMetadataDataclass = json_field(\n json_name=\"meta\"\n )\n\nobj = MyDataclass(\"John\", \"Doe\", 30, MyMetadataDataclass(dt.datetime.now(), dt.datetime.now()))\n\nraw_json = json_codec.to_json(obj)\nprint(raw_json)\n# 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}}'\n```\n\n### JSON Mixins\n\nThe package provides JSON mixins to add the serialization and deserialization capabilities to a dataclass.\n\nBy default, the JSON codec is used. See: `dataclasses_codec.codecs.json` for more details.\n\n```python\nfrom dataclasses import dataclass\nfrom dataclasses_codec import JSONSerializable, JSONDeserializable\n\n@dataclass\nclass MyDataclass(JSONSerializable, JSONDeserializable):\n first_name: str\n last_name: str\n age: int\n\nobj = MyDataclass(\"John\", \"Doe\", 30)\n\nencoded = obj.to_dict(to_camel_case=True)\nprint(encoded)\n# Output: {'firstName': 'John', 'lastName': 'Doe', 'age': 30}\n\nrestored = MyDataclass.from_dict(encoded, to_snake_case=True)\nprint(restored)\n# Output: MyDataclass(first_name=\"John\", last_name=\"Doe\", age=30)\n```\n\n### Extensibility\n\nThe package allows to extend the functionality of the codecs by implementing the `Codec` interface.\n\nEach implementation should use `is_dataclass` to check if the object is a dataclass.\n\n```python\nfrom dataclasses import dataclass, is_dataclass\nfrom dataclasses_codec import Codec, encode\nfrom dataclasses_codec.errors import CodecError\n\nclass MyCodec(Codec):\n def encode(self, obj, **kwargs):\n if not is_dataclass(obj):\n raise CodecError(f\"obj is not a dataclass, found: '{obj}'\")\n return obj\n def decode(self, cls, data, **kwargs):\n # Implement the decoding logic here\n raise CodecError(\"Decoding is not implemented for this codec\")\n\n@dataclass\nclass MyDataclass:\n first_name: str\n last_name: str\n age: int\n\nobj = MyDataclass(\"John\", \"Doe\", 30)\n\nencoded = encode(obj, codec=MyCodec())\nprint(encoded)\n# Output: {'first_name': 'John', 'last_name': 'Doe', 'age': 30}\n```\n\n## Development\n\n### Running the tests\n\n```bash\npython -m unittest\n```",
"bugtrack_url": null,
"license": null,
"summary": "Simple Python dataclass serialization package with no dependencies",
"version": "1.0.0",
"project_urls": {
"Documentation": "https://github.com/stupid-simple/dataclasses-codec#readme",
"Homepage": "https://github.com/stupid-simple/dataclasses-codec",
"Issues": "https://github.com/stupid-simple/dataclasses-codec/issues",
"Repository": "https://github.com/stupid-simple/dataclasses-codec"
},
"split_keywords": [
"codec",
" dataclass",
" decoder",
" encoder",
" json",
" serialization"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "8307676cc4dcaebdc6ee3f560add70bf0ecb4c7132d4e141f03410a689727075",
"md5": "5bd250abfe1542f1b9cf95e159b2ce2d",
"sha256": "e1fd5264924f11b68ba59dadd2c9b4e761764685c0fd348c2b1e84eb9af6d5ec"
},
"downloads": -1,
"filename": "dataclasses_codec-1.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "5bd250abfe1542f1b9cf95e159b2ce2d",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 8342,
"upload_time": "2025-10-25T12:09:16",
"upload_time_iso_8601": "2025-10-25T12:09:16.909757Z",
"url": "https://files.pythonhosted.org/packages/83/07/676cc4dcaebdc6ee3f560add70bf0ecb4c7132d4e141f03410a689727075/dataclasses_codec-1.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "004436ab7ec8ad4806d8b1686c17899c718c247c07eb9eca1202b5a45bf38275",
"md5": "ecfd6eb24bb9a1e4b5ea4928b865a8fa",
"sha256": "cb258cee3e29827bbef2ca77d0cc09321e01cb5446c69a87edb95b502644333f"
},
"downloads": -1,
"filename": "dataclasses_codec-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "ecfd6eb24bb9a1e4b5ea4928b865a8fa",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 11268,
"upload_time": "2025-10-25T12:09:18",
"upload_time_iso_8601": "2025-10-25T12:09:18.382556Z",
"url": "https://files.pythonhosted.org/packages/00/44/36ab7ec8ad4806d8b1686c17899c718c247c07eb9eca1202b5a45bf38275/dataclasses_codec-1.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-25 12:09:18",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "stupid-simple",
"github_project": "dataclasses-codec#readme",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "dataclasses-codec"
}