# Interfaces

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:

  > serialization
  >   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.
  > deserialization
  >   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:

  > - overriding `json.JSONDecoder.decode()` and `json.JSONEncoder.default()` in subclasses
  > - or passing `object_hook` argument (or `object_hook_pairs`) to `json.load()`/`json.loads()` or `default` argument for `json.dump()`/`json.dumps()`.

  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'

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

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

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

  `to_partial_json`()

    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.

  `to_json`()

    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.

  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_loads`(json_string)

    Deserialize from JSON document string.

  `json_dumps`(**kwargs)

    Dump to JSON string using proper serializer.

    Returns: | JSON document string.
    Return type: | str

  `json_dumps_pretty`()

    Dump the object to pretty JSON document string.

    Return type: | str

  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.