Skip to content

symfonic.agent.configuration.serialization

serialization

Shared deterministic rendering for configuration values.

canonical_json_value

canonical_json_value(value: Any) -> Any

Render configuration values with a stable order for unordered containers.

Source code in src/symfonic/agent/configuration/serialization.py
def canonical_json_value(value: Any) -> Any:
    """Render configuration values with a stable order for unordered containers."""
    if isinstance(value, BaseModel):
        return canonical_json_value(value.model_dump(mode="python"))
    if isinstance(value, Enum):
        return canonical_json_value(value.value)
    if isinstance(value, dict):
        return {str(key): canonical_json_value(item) for key, item in value.items()}
    if isinstance(value, (set, frozenset)):
        items = [canonical_json_value(item) for item in value]
        return sorted(items, key=lambda item: json.dumps(item, sort_keys=True))
    if isinstance(value, (list, tuple)):
        return [canonical_json_value(item) for item in value]
    if is_dataclass(value) and not isinstance(value, type):
        return {
            field.name: canonical_json_value(getattr(value, field.name)) for field in fields(value)
        }
    return value