simple-serialize
simple-serialize is a small Python library for serializing Python objects
to and from JSON. Classes must be registered to be participate, either by using
the @serializable decorator (simplest), or the register function (for types
you don't control). Use serialize/deserialize for converting to and from
JSON strings, or save/load for writing and reading those strings to disk.
Requires Python 3.10 or later.
Installation
Install the published package from PyPI:
python -m pip install simple-serialize
To install from a local checkout instead:
python -m pip install .
Quick start
Decorate a class to make it serializable. Ordinary classes are serialized from their instance attributes. Dataclasses are serialized from their fields.
from dataclasses import dataclass
from simple_serialize import deserialize, serializable, serialize
@serializable
@dataclass
class Person:
name: str
age: int
person = Person("Ada", 36)
json_text = serialize(person)
print(json_text)
restored = deserialize(json_text)
assert restored == person
Registered objects are represented in JSON by a type name and serialized data.
{
"__type__": "Person",
"__data__": {
"name": "Ada",
"age": 36
}
}
Passing a string argument to @serializable will use that string instead of the class
name as the value of the __type__ key. Use an explicit name when the JSON type name should remain stable if the Python class is renamed.
For a class you can't decorate, use the register function, and supply serializer
and deserializer functions. For example:
from simple_serialize import register
class ExternalValue: # Some externally defined class you don't control
def __init__(self, value):
self.value = value
# Functions you define to handle serialization and deserialization
def serialize_external(obj: ExternalValue, options, ctx):
return {"value": obj.value}
def deserialize_external(cls, data, options, ctx):
return cls(data["value"])
# Register the class and its handler functions
register(
ExternalValue,
serialize_external,
deserialize_external,
json_name="ExternalValue",
units="meters",
)
The class must be registered in the current Python process before its serialized value can be deserialized.
Serializer callbacks receive the instance, an options dictionary, and an opaque context
context object (see below). They should return JSON-compatible data. Deserializers receive the class, decoded data, options dictionary, and context object. They should return a reconstructed instance. Additional keyword arguments to register become the options dictionary; json_name continues to select the JSON type name.
JSON strings and files
serialize(obj, ctx=None) returns an indented JSON string, and
deserialize(json_text, ctx=None) returns the decoded value. The file helpers
use UTF-8; save creates missing parent directories.
from simple_serialize import load, save
save(person, "data/person.json")
restored = load("data/person.json")
Both operations accept an optional opaque ctx value, which is passed to
custom serialization and deserialization callbacks unchanged.
from simple_serialize import deserialize, serialize
ctx = {"offset": 10}
json_text = serialize(person, ctx)
restored = deserialize(json_text, ctx)
The library does not inspect or modify ctx; define and interpret its structure
in your own callbacks.
Registration options
Keyword arguments passed to @serializable or register are collected into
an options dictionary passed to the serializer and deserializer. The default serializers for ordinary classes and dataclasses recognize three keywords:
exclude: a list of attribute or field names omitted from serialized data.select: a list of the only attribute or field names to serialize (overridesexclude).rename: a mapping from Python attribute or field names to JSON names. Renamed names are mapped back during deserialization. Attribute names not in this mapping remain unchanged.
For example:
@serializable(
exclude=["password"],
rename={"first_name": "firstName"},
)
@dataclass
class Account:
first_name: str
password: str
Names in select and exclude refer to Python attribute or field names, before
any renaming. An excluded or unselected value is not present in the JSON data. It therefore needs a suitable default or otherwise compatible constructor if the object is
to be deserialized.
Custom serialization callbacks receive these options in their options dictionary and remain responsible for applying them. The exported mapping_serializer and mapping_deserializer callbacks apply them to mapping keys when you register those callbacks for a mapping class. Native dictionaries are serialized as ordinary JSON objects and are not filtered or renamed.
Custom serialization
For a decorated class, define _serialize(self, options, ctx) and
_deserialize(cls, data, options, ctx) methods to define custom conversions to
and from JSON. Decorator keyword arguments are available in the options dictionary:
from simple_serialize import serializable
@serializable(scale=1.8)
class Temperature:
def __init__(self, celsius):
self.celsius = celsius
def _serialize(self, options, ctx):
return {"fahrenheit": self.celsius * options["scale"] + 32}
@classmethod
def _deserialize(cls, data, options, ctx):
return cls((data["fahrenheit"] - 32) / options["scale"])
If thse custom methods are omitted, enums use their member values, dataclasses use
their fields, and other classes use their instance attributes, including
initialized __slots__. The default deserializer for an ordinary class calls
its constructor without arguments, so such classes must support Class().
Supported types
JSON-native types (None, booleans, numbers, strings, lists, and dictionaries)
can be serialized directly. The library also has built-in handlers for:
tuple,set, andfrozenset(encoded as JSON arrays; set iteration order is not guaranteed)complex(real and imaginary components)fractions.Fraction(exact numerator and denominator)decimal.Decimal(text representation, preserving precision and exponent)uuid.UUID(canonical hyphenated string)ipaddressaddress, network, and interface values (canonical text)collections.Counter,collections.OrderedDict, andcollections.deque(including non-string keys, order, anddeque.maxlen)bytesandbytearray(base64 encoded)memoryview(contents, format, shape, and read-only state; only contiguous views are supported, and the original backing buffer is not retained)rangeandslice(start, stop, and step values)pathlib.Pathdatetime.datetime,datetime.date,datetime.time, anddatetime.timedelta(datetime.timezoneoffsets/names and keyedzoneinfo.ZoneInfovalues are preserved for datetimes and times)datetime.timezoneand keyedzoneinfo.ZoneInfovalues- Compiled regular expressions (
re.Pattern) andre.RegexFlag
Other Python classes, including enum and dataclass types, must be registered
before use. Restoring a ZoneInfo value requires the corresponding IANA
timezone database entry to be available on the receiving system. Arbitrary
custom tzinfo implementations are represented by their ISO offset rather
than reconstructed as the original timezone object.
Format and limitations
- The reserved JSON keys
__type__and__data__identify registered values. Any dictionary containing__type__is treated as serialization metadata when deserialized, so avoid using that key for ordinary dictionary data. - Registered objects cannot be dictionary keys.
- Circular references raise
ValueError. Repeated references that are not circular are serialized as independent values; object identity is not kept. - Only deserialize JSON from sources you trust. Deserialization invokes the registered callbacks and constructors in your process.
Running the tests
Install the test dependency and run pytest:
python -m pip install '.[test]'
python -m pytest
AI Usage
This project was developed with the assistance of Github Copilot, mostly using the GPT-6 Luna model.
License
MIT
Metadata
Release files for simple-serialize 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| simple_serialize-0.5.0.tar.gz | 25.6 kB | Without provenance | Details for simple_serialize-0.5.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| simple_serialize-0.5.0-py3-none-any.whl | Python 3 | none | any | Details for simple_serialize-0.5.0-py3-none-any.whl |
Total release size: 47.6 kB
Release files / simple_serialize-0.5.0.tar.gz
| Download URL | simple_serialize-0.5.0.tar.gz |
|---|---|
| Size | 25.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7a876b6009f4fd64afa9abb8eb73bd9a5da197150f1ee6a9115168195ed10329
|
|
BLAKE2b-256 checksum How to use checksums |
52442a81969f0389300219059d5acee0e026407d526bdd734f6083b7cf8dc5c5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.9
|
Release files / simple_serialize-0.5.0-py3-none-any.whl
| Download URL | simple_serialize-0.5.0-py3-none-any.whl |
|---|---|
| Size | 22.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1b913fd3c1be9d4dc3c6679b32f5f31c2f3d92ea669a2685e7863dfc0e7b2137
|
|
BLAKE2b-256 checksum How to use checksums |
e72bd93d2303da31d80971fc7ae1d5b82c65630c2eda034c46b7c338da44ab1b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.9
|
Security for simple-serialize 0.5.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.