Skip to content

plaid.utils.json_codec

plaid.utils.json_codec

Generic JSON value codec with fast array encoding.

This module serializes arbitrary JSON-shaped values to a language-neutral payload. NumPy arrays are encoded as base64 little-endian C-contiguous bytes with explicit dtype and shape metadata, so the payload can be decoded from Python, MATLAB, R, JavaScript, or any language with base64 and typed-array support. Scalars pass through unchanged, and lists and dictionaries are encoded element-wise.

plaid.utils.json_codec.encode_json_value

encode_json_value(value)

Recursively encode a value into a JSON-compatible structure.

Scalars pass through unchanged. Lists and tuples are encoded element-wise. Dictionaries are encoded value-wise with string keys. NumPy scalars, NumPy arrays, and bytes are encoded with the portable base64 schema.

Parameters:

  • value (Any) –

    Value to encode.

Returns:

  • Any

    A JSON-compatible representation of value.

Raises:

  • TypeError

    If a leaf value type is not supported.

Source code in plaid/utils/json_codec.py
def encode_json_value(value: Any) -> Any:
    """Recursively encode a value into a JSON-compatible structure.

    Scalars pass through unchanged. Lists and tuples are encoded element-wise.
    Dictionaries are encoded value-wise with string keys. NumPy scalars,
    NumPy arrays, and bytes are encoded with the portable base64 schema.

    Args:
        value: Value to encode.

    Returns:
        A JSON-compatible representation of ``value``.

    Raises:
        TypeError: If a leaf value type is not supported.
    """
    if value is None or isinstance(value, (bool, int, float, str)):
        return value

    if isinstance(value, dict):
        return {str(key): encode_json_value(item) for key, item in value.items()}

    if isinstance(value, (list, tuple)):
        return [encode_json_value(item) for item in value]

    return encode_leaf_value(value)

plaid.utils.json_codec.decode_json_value

decode_json_value(value)

Recursively decode a value produced by :func:encode_json_value.

Encoded NumPy arrays and bytes are detected by their kind marker and restored. Other dictionaries and lists are decoded element-wise, and scalars pass through unchanged.

Parameters:

  • value (Any) –

    Value to decode.

Returns:

  • Any

    The decoded value.

Source code in plaid/utils/json_codec.py
def decode_json_value(value: Any) -> Any:
    """Recursively decode a value produced by :func:`encode_json_value`.

    Encoded NumPy arrays and bytes are detected by their ``kind`` marker and
    restored. Other dictionaries and lists are decoded element-wise, and
    scalars pass through unchanged.

    Args:
        value: Value to decode.

    Returns:
        The decoded value.
    """
    if isinstance(value, dict):
        if value.get("kind") in ("ndarray", "bytes"):
            return decode_leaf_value(value)
        return {key: decode_json_value(item) for key, item in value.items()}

    if isinstance(value, list):
        return [decode_json_value(item) for item in value]

    return value

plaid.utils.json_codec.encode_leaf_value

encode_leaf_value(value)

Encode a single leaf value (scalar, NumPy scalar/array, or bytes).

Parameters:

  • value (Any) –

    Leaf value to encode.

Returns:

  • Any

    A JSON-compatible representation of value.

Raises:

  • TypeError

    If the value type is not supported.

Source code in plaid/utils/json_codec.py
def encode_leaf_value(value: Any) -> Any:
    """Encode a single leaf value (scalar, NumPy scalar/array, or bytes).

    Args:
        value: Leaf value to encode.

    Returns:
        A JSON-compatible representation of ``value``.

    Raises:
        TypeError: If the value type is not supported.
    """
    if value is None or isinstance(value, (bool, int, float, str)):
        return value

    if isinstance(value, bytes):
        return {
            "kind": "bytes",
            "encoding": ARRAY_ENCODING,
            "data": base64.b64encode(value).decode("ascii"),
        }

    if isinstance(value, np.generic):
        return encode_leaf_value(value.item())

    if isinstance(value, np.ndarray):
        return _encode_array(value)

    if isinstance(value, (list, tuple)):
        return [encode_leaf_value(item) for item in value]

    raise TypeError(f"Unsupported value type for JSON serialization: {type(value)!r}")

plaid.utils.json_codec.decode_leaf_value

decode_leaf_value(value)

Decode a single leaf value produced by :func:encode_leaf_value.

Parameters:

  • value (Any) –

    Leaf value to decode.

Returns:

  • Any

    The decoded value.

Source code in plaid/utils/json_codec.py
def decode_leaf_value(value: Any) -> Any:
    """Decode a single leaf value produced by :func:`encode_leaf_value`.

    Args:
        value: Leaf value to decode.

    Returns:
        The decoded value.
    """
    if isinstance(value, dict):
        kind = value.get("kind")
        if kind == "ndarray":
            return _decode_array(value)
        if kind == "bytes":
            return base64.b64decode(value["data"])
    if isinstance(value, list):
        return [decode_leaf_value(item) for item in value]
    return value