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: object

CBORSerializable 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() and from_primitive(). to_primitive() converts an object to a CBOR primitive type (see Primitive), 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, use from_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 implement to_shallow_primitive() instead. to_shallow_primitive allows the returned object to be either CBOR Primitive or a CBORSerializable, as long as the CBORSerializable does 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:

CBORSerializable

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:

CBORSerializable

class pycardano.serialization.ArrayCBORSerializable

Bases: CBORSerializable

A 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: CBORSerializable

A 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: CBORSerializable

A 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: object

A 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: ArrayCBORSerializable

A 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.