Serialization

Defines CBOR serialization interfaces and provides useful serialization classes.

pycardano.serialization.default_encoder(encoder: _cbor2.CBOREncoder, value: Union[pycardano.serialization.CBORSerializable, pycardano.serialization.IndefiniteList])

A fallback function that encodes CBORSerializable to CBOR

class pycardano.serialization.IndefiniteList(li: Union[bytes, bytearray, str, int, float, decimal.Decimal, bool, None, tuple, list, pycardano.serialization.IndefiniteList, dict, collections.defaultdict, collections.OrderedDict, undefined_type, datetime.datetime, re.Pattern, CBORSimpleValue, _cbor2.CBORTag, set, frozenset, frozendict.frozendict, frozenlist._frozenlist.FrozenList, pycardano.serialization.IndefiniteFrozenList])

Bases: collections.UserList

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() Union[bytes, bytearray, str, int, float, decimal.Decimal, bool, None, tuple, list, pycardano.serialization.IndefiniteList, dict, collections.defaultdict, collections.OrderedDict, undefined_type, datetime.datetime, re.Pattern, CBORSimpleValue, _cbor2.CBORTag, set, frozenset, frozendict.frozendict, frozenlist._frozenlist.FrozenList, pycardano.serialization.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.

to_primitive() Union[bytes, bytearray, str, int, float, decimal.Decimal, bool, None, tuple, list, pycardano.serialization.IndefiniteList, dict, collections.defaultdict, collections.OrderedDict, undefined_type, datetime.datetime, re.Pattern, CBORSimpleValue, _cbor2.CBORTag, set, frozenset, frozendict.frozendict, frozenlist._frozenlist.FrozenList, pycardano.serialization.IndefiniteFrozenList]

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() Union[bytes, bytearray, str, int, float, decimal.Decimal, bool, None, tuple, list, pycardano.serialization.IndefiniteList, dict, collections.defaultdict, collections.OrderedDict, undefined_type, datetime.datetime, re.Pattern, CBORSimpleValue, _cbor2.CBORTag, set, frozenset, frozendict.frozendict, frozenlist._frozenlist.FrozenList, pycardano.serialization.IndefiniteFrozenList]

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) pycardano.serialization.CBORBase

Turn a CBOR primitive to its original class type.

Parameters
  • cls (CBORBase) – The original class type.

  • value (Primitive) – A CBOR primitive.

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: Union[str, bytes]) pycardano.serialization.CBORSerializable

Restore a CBORSerializable object from a CBOR.

Parameters

payload (Union[str, bytes]) – CBOR bytes or hex string to restore from.

Returns

Restored CBORSerializable object.

Return type

CBORSerializable

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))
class pycardano.serialization.ArrayCBORSerializable

Bases: pycardano.serialization.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() List[Union[bytes, bytearray, str, int, float, decimal.Decimal, bool, None, tuple, list, pycardano.serialization.IndefiniteList, dict, collections.defaultdict, collections.OrderedDict, undefined_type, datetime.datetime, re.Pattern, CBORSimpleValue, _cbor2.CBORTag, set, frozenset, frozendict.frozendict, frozenlist._frozenlist.FrozenList, pycardano.serialization.IndefiniteFrozenList]]
Returns

A CBOR primitive.

Return type

Primitive

Raises

SerializeException – When the object could not be converted to CBOR primitive types.

classmethod from_primitive(values: Union[list, tuple]) pycardano.serialization.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: pycardano.serialization.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() Union[bytes, bytearray, str, int, float, decimal.Decimal, bool, None, tuple, list, pycardano.serialization.IndefiniteList, dict, collections.defaultdict, collections.OrderedDict, undefined_type, datetime.datetime, re.Pattern, CBORSimpleValue, _cbor2.CBORTag, set, frozenset, frozendict.frozendict, frozenlist._frozenlist.FrozenList, pycardano.serialization.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(values: dict) pycardano.serialization.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: pycardano.serialization.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):
 ...
TypeError: type of key must be str; got int instead
KEY_TYPE = typing.Any
VALUE_TYPE = typing.Any
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) pycardano.serialization.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() pycardano.serialization.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[pycardano.serialization.CBORBase]) Callable[[List[Union[bytes, bytearray, str, int, float, decimal.Decimal, bool, None, tuple, list, pycardano.serialization.IndefiniteList, dict, collections.defaultdict, collections.OrderedDict, undefined_type, datetime.datetime, re.Pattern, CBORSimpleValue, _cbor2.CBORTag, set, frozenset, frozendict.frozendict, frozenlist._frozenlist.FrozenList, pycardano.serialization.IndefiniteFrozenList]]], List[pycardano.serialization.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.