pyiv.serde

SerDe (Serialize/Deserialize) module for pyiv.

This module provides SerDe implementations as part of the chain of responsibility pattern. SerDe is a chain handler for the ENCODING chain type, providing serialization/deserialization for various encoding formats available in Python’s standard library.

Architecture:
  • SerDe: Base abstract class extending ChainHandler for ENCODING chain type

  • Standard encodings: JSON, Base64, XML, Pickle, NoOp

  • YAML: pyiv-common (from pyiv_common.serde import YAMLSerDe)

  • DI Integration: Register and inject SerDe instances via chain system

Usage:
Register SerDe implementations in Config:
>>> from pyiv import Config, get_injector, ChainType
>>> from pyiv.serde import JSONSerDe, PickleSerDe
>>> class MyConfig(Config):
...     def configure(self):
...         # Register by handler type
...         self.register_chain_handler(ChainType.ENCODING, "json", JSONSerDe)
...         # Register by name (allows multiple implementations)
...         self.register_chain_handler_by_name(
...             ChainType.ENCODING, "json-input", JSONSerDe, handler_type="json"
...         )
...         # Register default (no-op or pickle)
...         self.register_chain_handler(ChainType.ENCODING, "default", PickleSerDe)
>>> injector = get_injector(MyConfig)
>>> json_serde = injector.inject_chain_handler(ChainType.ENCODING, "json")
>>> json_serde.handler_type
'json'
>>> input_serde = injector.inject_chain_handler_by_name(ChainType.ENCODING, "json-input")
>>> input_serde.handler_type
'json'
class pyiv.serde.Base64SerDe[source]

Bases: SerDe

Base64 encoding SerDe.

Use this when binary payloads must travel as text (headers, logs, or text-only transports). Strings are UTF-8 encoded first; non-bytes objects fall back to pickle before encoding. Deserialize returns raw bytes.

Example

>>> from pyiv.serde.encodings import Base64SerDe
>>> serde = Base64SerDe()
>>> serde.handler_type
'base64'
>>> encoded = serde.serialize(b"hello")
>>> encoded
'aGVsbG8='
>>> serde.deserialize(encoded)
b'hello'
deserialize(data: str | bytes, target_type: Type[T] | None = None) → T[source]

Deserialize base64-encoded data.

Parameters:
  • data – The base64-encoded string or bytes

  • target_type – Optional type hint (returns bytes by default)

Returns:

Decoded bytes

property handler_type: str

Return the handler type identifier.

Returns:

The handler type identifier (“base64”)

serialize(obj: Any) → str[source]

Serialize using base64 encoding.

Parameters:

obj – The data to encode (bytes or string)

Returns:

Base64-encoded string

class pyiv.serde.JSONSerDe[source]

Bases: SerDe

Standard JSON SerDe using Python’s json module.

Use this for APIs, configs, and payloads that exchange JSON. Datetimes serialize to ISO strings; objects with __dict__ become dicts. Prefer this over pickle whenever the data is text-safe and interoperable.

Example

>>> from pyiv.serde.encodings import JSONSerDe
>>> serde = JSONSerDe()
>>> serde.handler_type
'json'
>>> serde.serialize({"a": 1})
'{"a": 1}'
>>> serde.deserialize('{"a": 1}')
{'a': 1}
deserialize(data: str | bytes, target_type: Type[T] | None = None) → T[source]

Deserialize JSON string/bytes back to a Python object.

Parameters:
  • data – The JSON string or bytes

  • target_type – Optional type hint for the expected result type

Returns:

Deserialized Python object

property handler_type: str

Return the handler type identifier.

Returns:

The handler type identifier (“json”)

serialize(obj: Any) → str[source]

Serialize using standard JSON encoding.

Parameters:

obj – The Python object to serialize

Returns:

JSON string representation

class pyiv.serde.NoOpSerDe[source]

Bases: SerDe

No-op SerDe that passes through data unchanged.

Use this as the default when no encoding is configured, or when a pipeline already holds strings/bytes and must not re-encode them. Strings and bytes are returned as-is; other objects become str(obj).

Why this exists: Default pass-through encoder when no wire format was configured.

Example

>>> from pyiv.serde.encodings import NoOpSerDe
>>> serde = NoOpSerDe()
>>> serde.handler_type
'noop'
>>> serde.serialize("already-encoded")
'already-encoded'
>>> serde.deserialize("already-encoded")
'already-encoded'
deserialize(data: str | bytes, target_type: Type[T] | None = None) → T[source]

Pass through the data unchanged.

Parameters:
  • data – The encoded data (string or bytes)

  • target_type – Optional type hint (ignored)

Returns:

The data unchanged

property handler_type: str

Return the handler type identifier.

Returns:

The handler type identifier (“noop”)

serialize(obj: Any) → str | bytes[source]

Pass through the object unchanged.

Parameters:

obj – The Python object to serialize

Returns:

The object unchanged (as string or bytes)

class pyiv.serde.PickleSerDe[source]

Bases: SerDe

Python pickle SerDe.

Use this when you need to round-trip arbitrary Python objects that JSON, XML, or base64 text cannot represent. Prefer safer text codecs for untrusted input; pickle is a stdlib fallback for trusted local data.

Example

>>> from pyiv.serde.encodings import PickleSerDe
>>> serde = PickleSerDe()
>>> serde.handler_type
'pickle'
>>> serde.deserialize(serde.serialize({"x": 2}))
{'x': 2}
deserialize(data: str | bytes, target_type: Type[T] | None = None) → T[source]

Deserialize using pickle.

Parameters:
  • data – The pickled data (bytes)

  • target_type – Optional type hint (ignored, pickle handles types)

Returns:

Deserialized Python object

property handler_type: str

Return the handler type identifier.

Returns:

The handler type identifier (“pickle”)

serialize(obj: Any) → bytes[source]

Serialize using pickle.

Parameters:

obj – The Python object to serialize

Returns:

Pickled bytes representation

class pyiv.serde.SerDe[source]

Bases: ChainHandler

Abstract base class for serialization/deserialization operations.

SerDe is a chain handler for the ENCODING chain. Subclass it for each codec (JSON, base64, XML, pickle, etc.); YAML lives in pyiv-common.

Use this when callers should pick a codec by handler_type instead of hard-coding json.dumps / pickle.loads. Register implementations on the ENCODING chain so injectors and pipelines can swap formats without rewriting call sites. Multiple handlers may share a handler_type with different behaviors (date formatting, null handling, and so on).

Subclasses must implement handler_type, serialize, and deserialize.

Example

>>> import json
>>> from typing import Any, Optional, Type
>>> from pyiv.serde.base import SerDe
>>> class MyJSONSerDe(SerDe):
...     @property
...     def handler_type(self) -> str:
...         return "json"
...     def serialize(self, obj: Any) -> str:
...         return json.dumps(obj)
...     def deserialize(
...         self, data: str, target_type: Optional[Type] = None
...     ) -> Any:
...         return json.loads(data)
>>> serde = MyJSONSerDe()
>>> serde.deserialize(serde.serialize({"a": 1}))
{'a': 1}
property chain_type: ChainType

Return the chain type (always ENCODING for SerDe).

Returns:

ChainType.ENCODING

abstract deserialize(data: str | bytes, target_type: Type[T] | None = None) → T[source]

Deserialize encoded data back to a Python object.

Parameters:
  • data – The encoded data (string or bytes)

  • target_type – Optional type hint for the expected result type

Returns:

Deserialized Python object

handle(request: Any, **kwargs) → Any[source]

Handle a serialization/deserialization request.

This is the chain handler interface. For SerDe, requests can be: - A tuple of (“serialize”, obj) -> returns serialized data - A tuple of (“deserialize”, data, target_type) -> returns deserialized object - A dict with “action” key -> processes accordingly

Parameters:
  • request – The request (can be tuple, dict, or direct object)

  • **kwargs – Additional keyword arguments

Returns:

The result of the operation

abstract property handler_type: str

Return the encoding type identifier (e.g., “json”, “base64”, “pickle”).

Returns:

A string identifying the encoding format

abstract serialize(obj: Any) → str | bytes[source]

Serialize a Python object to encoded format.

Parameters:

obj – The Python object to serialize

Returns:

Serialized representation as string or bytes

class pyiv.serde.XMLSerDe[source]

Bases: SerDe

XML encoding SerDe for simple dict/list structures.

Use this when interoperability with XML-oriented systems matters and the payload is a shallow dict or list. Nested dicts become child elements; lists become item children. Not a full schema or namespace mapper.

Example

>>> from pyiv.serde.encodings import XMLSerDe
>>> serde = XMLSerDe()
>>> serde.handler_type
'xml'
>>> xml = serde.serialize({"name": "Ada"})
>>> xml
'<root><name>Ada</name></root>'
>>> serde.deserialize(xml)
{'name': 'Ada'}
deserialize(data: str | bytes, target_type: Type[T] | None = None) → T[source]

Deserialize XML string/bytes back to a Python object.

Parameters:
  • data – The XML string or bytes

  • target_type – Optional type hint (returns dict by default)

Returns:

Deserialized Python object (dict or list)

property handler_type: str

Return the handler type identifier.

Returns:

The handler type identifier (“xml”)

serialize(obj: Any) → str[source]

Serialize using XML encoding.

Parameters:

obj – The Python object to serialize (dict or list)

Returns:

XML string representation

Modules

base

Base SerDe interface for serialization/deserialization.

encodings

Standard Python encoding SerDe implementations.

json

JSON SerDe implementation.