Serialization
Defines CBOR serialization interfaces and provides useful serialization classes.
- pycardano.serialization.default_encoder(encoder: CBOREncoder, value: CBORSerializable | IndefiniteList)
A fallback function that encodes CBORSerializable to CBOR
- class pycardano.serialization.IndefiniteList(li: bytes | bytearray | str | int | float | Decimal | bool | None | tuple | list | IndefiniteList | dict | defaultdict | OrderedDict | datetime | Pattern | CBORSimpleValue | CBORTag | set | Fraction | frozenset | FrozenDict | FrozenList | IndefiniteFrozenList | ByteString)
Bases:
UserList
- class pycardano.serialization.IndefiniteFrozenList
Bases:
FrozenList,IndefiniteList
- class pycardano.serialization.CBORSerializable
Bases:
objectCBORSerializable standardizes the interfaces a class should implement in order for it to be serialized to and deserialized from CBOR.
Two required interfaces to implement are
to_primitive()andfrom_primitive().to_primitive()converts an object to a CBOR primitive type (seePrimitive), which could be then encoded by CBOR library.from_primitive()restores an object from a CBOR primitive type.To convert a CBORSerializable to CBOR, use
to_cbor(). To restore a CBORSerializable from CBOR, usefrom_cbor().Note
to_primitive()needs to return a pure CBOR primitive type, meaning that the returned value and all its child elements have to be CBOR primitives, which could mean a good amount of work. An alternative but simpler approach is to implementto_shallow_primitive()instead. to_shallow_primitive allows the returned object to be either CBORPrimitiveor aCBORSerializable, as long as theCBORSerializabledoes not refer to itself, which could cause infinite loops.- to_shallow_primitive() bytes | bytearray | str | int | float | Decimal | bool | None | tuple | list | IndefiniteList | dict | defaultdict | OrderedDict | datetime | Pattern | CBORSimpleValue | CBORTag | set | Fraction | frozenset | FrozenDict | FrozenList | IndefiniteFrozenList | ByteString | CBORSerializable
Convert the instance to a CBOR primitive. If the primitive is a container, e.g. list, dict, the type of its elements could be either a Primitive or a CBORSerializable.
- Returns:
A CBOR primitive.
- Return type:
Primitive- Raises:
SerializeException – When the object could not be converted to CBOR primitive types.
- to_primitive() bytes | bytearray | str | int | float | Decimal | bool | None | tuple | list | IndefiniteList | dict | defaultdict | OrderedDict | datetime | Pattern | CBORSimpleValue | CBORTag | set | Fraction | frozenset | FrozenDict | FrozenList | IndefiniteFrozenList | ByteString
Convert the instance and its elements to CBOR primitives recursively.
- Returns:
A CBOR primitive.
- Return type:
Primitive- Raises:
SerializeException – When the object or its elements could not be converted to CBOR primitive types.
- validate()
Validate the data stored in the current instance. Defaults to always pass.
- Raises:
InvalidDataException – When the data is invalid.
- to_validated_primitive() bytes | bytearray | str | int | float | Decimal | bool | None | tuple | list | IndefiniteList | dict | defaultdict | OrderedDict | datetime | Pattern | CBORSimpleValue | CBORTag | set | Fraction | frozenset | FrozenDict | FrozenList | IndefiniteFrozenList | ByteString
Convert the instance and its elements to CBOR primitives recursively with data validated by
validate()method.- Returns:
A CBOR primitive.
- Return type:
Primitive- Raises:
SerializeException – When the object or its elements could not be converted to CBOR primitive types.
- classmethod from_primitive(value: Any, type_args: tuple | None = None) CBORBase
Turn a CBOR primitive to its original class type.
- Parameters:
cls (CBORBase) – The original class type.
value (
Primitive) – A CBOR primitive.type_args (Optional[tuple]) – Type arguments for the class.
- Returns:
A CBOR serializable object.
- Return type:
CBORBase
- Raises:
DeserializeException – When the object could not be restored from primitives.
- to_cbor() bytes
Encode a Python object into CBOR bytes.
- Returns:
Python object encoded in cbor bytes.
- Return type:
bytes
Examples
>>> class Test(CBORSerializable): ... def __init__(self, number1, number2): ... self.number1 = number1 ... self.number2 = number2 ... ... def to_primitive(value): ... return [value.number1, value.number2] ... ... @classmethod ... def from_primitive(cls, value): ... return cls(value[0], value[1]) ... ... def __repr__(self): ... return f"Test({self.number1}, {self.number2})" >>> a = Test(1, 2) >>> a.to_cbor().hex() '820102'
- to_cbor_hex() str
Encode a Python object into CBOR hex.
- Returns:
Python object encoded in cbor hex string.
- Return type:
str
- classmethod from_cbor(payload: str | bytes) CBORBase
Restore a CBORSerializable object from a CBOR.
- Parameters:
payload (Union[str, bytes]) – CBOR bytes or hex string to restore from.
- Returns:
Restored CBORSerializable object of the specific subclass type.
- Return type:
CBORBase
Examples
Basic use case:
>>> class Test(CBORSerializable): ... def __init__(self, number1, number2): ... self.number1 = number1 ... self.number2 = number2 ... ... def to_primitive(value): ... return [value.number1, value.number2] ... ... @classmethod ... def from_primitive(cls, value): ... return cls(value[0], value[1]) ... ... def __repr__(self): ... return f"Test({self.number1}, {self.number2})" >>> a = Test(1, 2) >>> cbor_hex = a.to_cbor_hex() >>> print(Test.from_cbor(cbor_hex)) Test(1, 2)
For a CBORSerializable that has CBORSerializables as attributes, we will need to pass each child value to the
from_primitive()method of its corresponding CBORSerializable. Example:>>> class TestParent(CBORSerializable): ... def __init__(self, number1, test): ... self.number1 = number1 ... self.test = test ... ... def to_shallow_primitive(value): # Implementing `to_shallow_primitive` simplifies the work. ... return [value.number1, value.test] ... ... @classmethod ... def from_primitive(cls, value): ... test = Test.from_primitive(value[1]) # Restore test by passing `value[1]` to ... # `Test.from_primitive` ... return cls(value[0], test) ... ... def __repr__(self): ... return f"TestParent({self.number1}, {self.test})" >>> a = Test(1, 2) >>> b = TestParent(3, a) >>> b TestParent(3, Test(1, 2)) >>> cbor_hex = b.to_cbor_hex() >>> cbor_hex '8203820102' >>> print(TestParent.from_cbor(cbor_hex)) TestParent(3, Test(1, 2))
- property json_type: str
Return the class name of the CBORSerializable object.
This property provides a default string representing the type of the object for use in JSON serialization.
- Returns:
The class name of the object.
- Return type:
str
- property json_description: str
Return the docstring of the CBORSerializable object’s class.
This property provides a default string description of the object for use in JSON serialization.
- Returns:
The docstring of the object’s class.
- Return type:
str
- to_json(key_type: str | None = None, description: str | None = None, **kwargs) str
Convert the CBORSerializable object to a JSON string containing type, description, and CBOR hex.
This method returns a JSON representation of the object, including its type, description, and CBOR hex encoding.
- Parameters:
key_type (str) – The type to use in the JSON output. Defaults to the class name.
description (str) – The description to use in the JSON output. Defaults to the class docstring.
**kwargs – Extra key word arguments to be passed to json.dumps()
- Returns:
The JSON string representation of the object.
- Return type:
str
- classmethod from_json(data: str) CBORSerializable
Load a CBORSerializable object from a JSON string containing its CBOR hex representation.
- Parameters:
data (str) – The JSON string to load the object from.
- Returns:
The loaded CBORSerializable object.
- Return type:
- Raises:
DeserializeException – If the loaded object is not of the expected type.
- save(path: str, key_type: str | None = None, description: str | None = None, **kwargs)
Save the CBORSerializable object to a file in JSON format.
- This method writes the object’s JSON representation to the specified file path.
It raises an error if the file already exists and is not empty.
- Parameters:
path (str) – The file path to save the object to.
key_type (str, optional) – The type to use in the JSON output. Defaults to the class name.
description (str, optional) – The description to use in the JSON output. Defaults to the class docstring.
**kwargs – Extra key word arguments to be passed to json.dumps()
- Raises:
IOError – If the file already exists and is not empty.
- classmethod load(path: str)
Load a CBORSerializable object from a file containing its JSON representation.
- Parameters:
path (str) – The file path to load the object from.
- Returns:
The loaded CBORSerializable object.
- Return type:
- class pycardano.serialization.ArrayCBORSerializable
Bases:
CBORSerializableA base class that can serialize its child dataclass into a CBOR array.
The class is useful when the position of each item in a list have its own semantic meaning.
Examples
Basic usages:
>>> from dataclasses import dataclass >>> @dataclass ... class Test1(ArrayCBORSerializable): ... a: str ... b: str=None >>> @dataclass ... class Test2(ArrayCBORSerializable): ... c: str ... test1: Test1 >>> t = Test2(c="c", test1=Test1(a="a")) >>> t Test2(c='c', test1=Test1(a='a', b=None)) >>> cbor_hex = t.to_cbor_hex() >>> cbor_hex '826163826161f6' >>> Test2.from_cbor(cbor_hex) Test2(c='c', test1=Test1(a='a', b=None))
A value of None will be encoded as nil (#7.22) in cbor. This will become a problem if the field is meant to be optional. To exclude an optional attribute from cbor, we can use field constructor with a metadata field “optional” set to True and default value set to None.
Note
In ArrayCBORSerializable, all non-optional fields have to be declared before any optional field.
Example:
>>> from dataclasses import dataclass, field >>> @dataclass ... class Test1(ArrayCBORSerializable): ... a: str ... b: str=field(default=None, metadata={"optional": True}) >>> @dataclass ... class Test2(ArrayCBORSerializable): ... c: str ... test1: Test1 >>> t = Test2(c="c", test1=Test1(a="a")) >>> t Test2(c='c', test1=Test1(a='a', b=None)) >>> t.to_primitive() # Notice below that attribute "b" is not included in converted primitive. ['c', ['a']] >>> cbor_hex = t.to_cbor_hex() >>> cbor_hex '826163816161' >>> Test2.from_cbor(cbor_hex) Test2(c='c', test1=Test1(a='a', b=None))
- to_shallow_primitive() bytes | bytearray | str | int | float | Decimal | bool | None | tuple | list | IndefiniteList | dict | defaultdict | OrderedDict | datetime | Pattern | CBORSimpleValue | CBORTag | set | Fraction | frozenset | FrozenDict | FrozenList | IndefiniteFrozenList | ByteString
- Returns:
A CBOR primitive.
- Return type:
Primitive- Raises:
SerializeException – When the object could not be converted to CBOR primitive types.
- classmethod from_primitive(values: list | tuple | IndefiniteList) ArrayBase
Restore a primitive value to its original class type.
- Parameters:
cls (ArrayBase) – The original class type.
values (List[Primitive]) – A list whose elements are CBOR primitives.
- Returns:
Restored object.
- Return type:
ArrayBase- Raises:
DeserializeException – When the object could not be restored from primitives.
- class pycardano.serialization.MapCBORSerializable
Bases:
CBORSerializableA base class that can serialize its child dataclass into a CBOR Map.
The class is useful when each key in a map have its own semantic meaning.
Examples
Basic usage:
>>> from dataclasses import dataclass, field >>> @dataclass ... class Test1(MapCBORSerializable): ... a: str="" ... b: str="" >>> @dataclass ... class Test2(MapCBORSerializable): ... c: str=None ... test1: Test1=field(default_factory=Test1) >>> t = Test2(test1=Test1(a="a")) >>> t Test2(c=None, test1=Test1(a='a', b='')) >>> t.to_primitive() {'c': None, 'test1': {'a': 'a', 'b': ''}} >>> cbor_hex = t.to_cbor_hex() >>> cbor_hex 'a26163f6657465737431a261616161616260' >>> Test2.from_cbor(cbor_hex) Test2(c=None, test1=Test1(a='a', b=''))
In the example above, all keys in the map share the same name as their corresponding attributes. However, sometimes we want to use different keys when serializing some attributes, this could be achieved by adding a “key” value to the metadata of a field. Example:
>>> from dataclasses import dataclass, field >>> @dataclass ... class Test1(MapCBORSerializable): ... a: str=field(default="", metadata={"key": "0"}) ... b: str=field(default="", metadata={"key": "1"}) >>> @dataclass ... class Test2(MapCBORSerializable): ... c: str=field(default=None, metadata={"key": "0", "optional": True}) ... test1: Test1=field(default_factory=Test1, metadata={"key": "1"}) >>> t = Test2(test1=Test1(a="a")) >>> t Test2(c=None, test1=Test1(a='a', b='')) >>> t.to_primitive() {'1': {'0': 'a', '1': ''}} >>> cbor_hex = t.to_cbor_hex() >>> cbor_hex 'a16131a261306161613160' >>> Test2.from_cbor(cbor_hex) Test2(c=None, test1=Test1(a='a', b=''))
- to_shallow_primitive() bytes | bytearray | str | int | float | Decimal | bool | None | tuple | list | IndefiniteList | dict | defaultdict | OrderedDict | datetime | Pattern | CBORSimpleValue | CBORTag | set | Fraction | frozenset | FrozenDict | FrozenList | IndefiniteFrozenList | ByteString
Convert the instance to a CBOR primitive. If the primitive is a container, e.g. list, dict, the type of its elements could be either a Primitive or a CBORSerializable.
- Returns:
A CBOR primitive.
- Return type:
Primitive- Raises:
SerializeException – When the object could not be converted to CBOR primitive types.
- classmethod from_primitive(values: dict | FrozenDict) MapBase
Restore a primitive value to its original class type.
- Parameters:
cls (MapBase) – The original class type.
values (
Primitive) – A CBOR primitive.
- Returns:
Restored object.
- Return type:
MapBase- Raises:
pycardano.exception.DeserializeException – When the object could not be restored from primitives.
- class pycardano.serialization.DictCBORSerializable(*args, **kwargs)
Bases:
CBORSerializableA dictionary class where all keys share the same type and all values share the same type.
Examples
>>> @dataclass ... class Test1(ArrayCBORSerializable): ... a: int ... b: str >>> >>> class Test2(DictCBORSerializable): ... KEY_TYPE = str ... VALUE_TYPE = Test1 >>> >>> t = Test2() >>> t["x"] = Test1(a=1, b="x") >>> t["y"] = Test1(a=2, b="y") >>> primitives = t.to_primitive() >>> deserialized = Test2.from_primitive(primitives) >>> assert t == deserialized >>> t[1] = 2 Traceback (most recent call last): ... typeguard.TypeCheckError: int is not an instance of str
- KEY_TYPE
alias of
Type[Any]
- VALUE_TYPE
alias of
Type[Any]
- validate()
Validate the data stored in the current instance. Defaults to always pass.
- Raises:
InvalidDataException – When the data is invalid.
- to_shallow_primitive() dict
Convert the instance to a CBOR primitive. If the primitive is a container, e.g. list, dict, the type of its elements could be either a Primitive or a CBORSerializable.
- Returns:
A CBOR primitive.
- Return type:
Primitive- Raises:
SerializeException – When the object could not be converted to CBOR primitive types.
- classmethod from_primitive(value: dict) DictBase
Restore a primitive value to its original class type.
- Parameters:
cls (DictBase) – The original class type.
value (
Primitive) – A CBOR primitive.
- Returns:
Restored object.
- Return type:
DictBase- Raises:
DeserializeException – When the object could not be restored from primitives.
- copy() DictCBORSerializable
- class pycardano.serialization.RawCBOR(cbor: bytes)
Bases:
objectA wrapper class for bytes that represents a CBOR value.
- cbor: bytes
- pycardano.serialization.list_hook(cls: Type[CBORBase]) Callable[[List[bytes | bytearray | str | int | float | Decimal | bool | None | tuple | list | IndefiniteList | dict | defaultdict | OrderedDict | datetime | Pattern | CBORSimpleValue | CBORTag | set | Fraction | frozenset | FrozenDict | FrozenList | IndefiniteFrozenList | ByteString]], List[CBORBase]]
A factory that generates a Callable which turns a list of Primitive to a list of CBORSerializables.
- Parameters:
cls (CBORBase) – The type of CBORSerializable the list will be converted to.
- Returns:
- An Callable that restores a list of Primitive to a list of
CBORSerializables.
- Return type:
Callable[[List[Primitive]], List[CBORBase]]
- pycardano.serialization.limit_primitive_type(*allowed_types)
A helper function to validate primitive type given to from_primitive class methods
Not exposed to public by intention.
- class pycardano.serialization.OrderedSet(iterable: List[T] | IndefiniteList | None = None, use_tag: bool = True)
Bases:
Generic[T],CBORSerializable- append(item: T) None
- extend(items: Iterable[T]) None
- remove(item: T) None
- to_shallow_primitive() CBORTag | List[T] | IndefiniteList | FrozenList | IndefiniteFrozenList
Convert the instance to a CBOR primitive. If the primitive is a container, e.g. list, dict, the type of its elements could be either a Primitive or a CBORSerializable.
- Returns:
A CBOR primitive.
- Return type:
Primitive- Raises:
SerializeException – When the object could not be converted to CBOR primitive types.
- classmethod from_primitive(value: bytes | bytearray | str | int | float | Decimal | bool | None | tuple | list | IndefiniteList | dict | defaultdict | OrderedDict | datetime | Pattern | CBORSimpleValue | CBORTag | set | Fraction | frozenset | FrozenDict | FrozenList | IndefiniteFrozenList | ByteString, type_args: tuple | None = None) OrderedSet[T]
Turn a CBOR primitive to its original class type.
- Parameters:
cls (CBORBase) – The original class type.
value (
Primitive) – A CBOR primitive.type_args (Optional[tuple]) – Type arguments for the class.
- Returns:
A CBOR serializable object.
- Return type:
CBORBase
- Raises:
DeserializeException – When the object could not be restored from primitives.
- class pycardano.serialization.NonEmptyOrderedSet(iterable: List[T] | IndefiniteList | None = None, use_tag: bool = True)
Bases:
OrderedSet[T]- validate()
Validate the data stored in the current instance. Defaults to always pass.
- Raises:
InvalidDataException – When the data is invalid.
- classmethod from_primitive(value: bytes | bytearray | str | int | float | Decimal | bool | None | tuple | list | IndefiniteList | dict | defaultdict | OrderedDict | datetime | Pattern | CBORSimpleValue | CBORTag | set | Fraction | frozenset | FrozenDict | FrozenList | IndefiniteFrozenList | ByteString, type_args: tuple | None = None) NonEmptyOrderedSet[T]
Turn a CBOR primitive to its original class type.
- Parameters:
cls (CBORBase) – The original class type.
value (
Primitive) – A CBOR primitive.type_args (Optional[tuple]) – Type arguments for the class.
- Returns:
A CBOR serializable object.
- Return type:
CBORBase
- Raises:
DeserializeException – When the object could not be restored from primitives.
- class pycardano.serialization.CodedSerializable
Bases:
ArrayCBORSerializableA base class for CBORSerializable types that have a specific code.
This class provides a mechanism to validate the type of the object based on its first element.
Examples
>>> from dataclasses import dataclass, field >>> @dataclass ... class TestCoded(CodedSerializable): ... _CODE = 1 ... value: str >>> >>> # Create and serialize an instance >>> test = TestCoded("hello") >>> primitives = test.to_primitive() >>> primitives [1, 'hello'] >>> >>> # Deserialize valid data >>> restored = TestCoded.from_primitive(primitives) >>> restored.value 'hello' >>> >>> # Attempting to deserialize with wrong code raises exception >>> invalid_data = [2, "hello"] >>> TestCoded.from_primitive(invalid_data) Traceback (most recent call last): ... DeserializeException: Invalid TestCoded type 2
- classmethod from_primitive(values: list | tuple) CodedSerializable
Restore a primitive value to its original class type.
- Parameters:
cls (ArrayBase) – The original class type.
values (List[Primitive]) – A list whose elements are CBOR primitives.
- Returns:
Restored object.
- Return type:
ArrayBase- Raises:
DeserializeException – When the object could not be restored from primitives.