JOSE interfaces.

class josepy.interfaces.JSONDeSerializable

Bases: object

Interface for (de)serializable JSON objects.

Please recall, that standard Python library implements json.JSONEncoder and json.JSONDecoder that perform translations based on respective conversion tables that look pretty much like the one below (for complete tables see relevant Python documentation):

JSON Python
object dict

While the above conversion table is about translation of JSON documents to/from the basic Python types only, JSONDeSerializable introduces the following two concepts:

Turning an arbitrary Python object into Python object that can be encoded into a JSON document. Full serialization produces a Python object composed of only basic types as required by the conversion table. Partial serialization (accomplished by to_partial_json()) produces a Python object that might also be built from other JSONDeSerializable objects.
Turning a decoded Python object (necessarily one of the basic types as required by the conversion table) into an arbitrary Python object.

Serialization produces serialized object (“partially serialized object” or “fully serialized object” for partial and full serialization respectively) and deserialization produces deserialized object, both usually denoted in the source code as jobj.

Wording in the official Python documentation might be confusing after reading the above, but in the light of those definitions, one can view json.JSONDecoder.decode() as decoder and deserializer of basic types, json.JSONEncoder.default() as serializer of basic types, json.JSONEncoder.encode() as serializer and encoder of basic types.

One could extend json to support arbitrary object (de)serialization either by:

Interestingly, default is required to perform only partial serialization, as json.dumps() applies default recursively. This is the idea behind making to_partial_json() produce only partial serialization, while providing custom json_dumps() that dumps with default set to json_dump_default().

To make further documentation a bit more concrete, please, consider the following imaginatory implementation example:

class Foo(JSONDeSerializable):
    def to_partial_json(self):
        return 'foo'

    def from_json(cls, jobj):
        return Foo()

class Bar(JSONDeSerializable):
    def to_partial_json(self):
        return [Foo(), Foo()]

    def from_json(cls, jobj):
        return Bar()
classmethod from_json(jobj)

Deserialize a decoded JSON document.

Parameters:jobj – Python object, composed of only other basic data types, as decoded from JSON document. Not necessarily dict (as decoded from “JSON object” document).
Raises:josepy.errors.DeserializationError – if decoding was unsuccessful, e.g. in case of unparseable X509 certificate, or wrong padding in JOSE base64 encoded string, etc.
classmethod json_dump_default(python_object)

Serialize Python object.

This function is meant to be passed as default to json.dump() or json.dumps(). They call default(python_object) only for non-basic Python types, so this function necessarily raises TypeError if python_object is not an instance of IJSONSerializable.

Please read the class docstring for more information.


Dump to JSON string using proper serializer.

Returns:JSON document string.
Return type:str

Dump the object to pretty JSON document string.

Return type:str
classmethod json_loads(json_string)

Deserialize from JSON document string.


Fully serialize.

Again, following the example from before, full serialization means the following:

assert Bar().to_json() == ['foo', 'foo']
Raises:josepy.errors.SerializationError – in case of any serialization error.
Returns:Fully serialized object.

Partially serialize.

Following the example, partial serialization means the following:

assert isinstance(Bar().to_partial_json()[0], Foo)
assert isinstance(Bar().to_partial_json()[1], Foo)

# in particular...
assert Bar().to_partial_json() != ['foo', 'foo']
Raises:josepy.errors.SerializationError – in case of any serialization error.
Returns:Partially serializable object.