Source code for utils.serialization

import json
import logging

from typing import Mapping, Any, Dict, Union
import enum
import inspect

from adalflow.utils.registry import EntityMapping


log = logging.getLogger(__name__)


[docs] class ObjectTypes(enum.Enum): CLASS = 1 INSTANCE = 2 TYPE = 3
[docs] def check_object(obj) -> ObjectTypes: if inspect.isclass(obj): return ObjectTypes.CLASS elif isinstance(obj, type): return ObjectTypes.TYPE else: return ObjectTypes.INSTANCE
[docs] def default(o: Any) -> Union[Dict[str, Any], str]: r"""Customized JSON serializer. (1) Support internal dataclasses and components instance serialization by calling to_dict() method. (2) Support internal dataclasses class serialization by calling to_dict_class() method. (3) Any external instance if it has to_dict() method, it will be serialized. (4) All other objects will be serialized as {"type": type(o).__name__, "data": str(o)} """ seralized_obj = {} # 1. Handle the case like Component, DataClass where we have to_dict and to_dict_class obj_type = check_object(o) if obj_type == ObjectTypes.CLASS: log.debug(f"Object {o} is a class with name {o.__name__}") if hasattr(o, "to_dict_class") and callable(getattr(o, "to_dict_class")): try: seralized_obj = o.to_dict_class() return seralized_obj except Exception as e: log.error(f"Error serializing object {o}: {e}") pass elif obj_type == ObjectTypes.INSTANCE: log.debug(f"Object {o} is an instance of {o.__class__.__name__}") if hasattr(o, "to_dict") and callable(getattr(o, "to_dict")): try: seralized_obj = o.to_dict() return seralized_obj except Exception as e: log.error(f"Error serializing object {o}: {e}") pass elif obj_type == ObjectTypes.TYPE: log.debug(f"Object {o} is a type of {o.__name__}") try: return {"type": type(o).__name__, "data": str(o)} except Exception as e: log.error( f"Object of type {o.__class__.__name__} is not JSON serializable: {str(e)}" ) pass log.debug("Fallback to serializing attributes who come from external libraries") # (2) Fallback to serializing attributes who come from external libraries try: return {"type": type(o).__name__, "data": str(o)} except Exception as e: raise TypeError( f"Object of type {o.__class__.__name__} is not JSON serializable: {str(e)}" )
[docs] def serialize(obj: Mapping[str, Any]) -> str: """Serialize the object to a json string. Args: obj (Mapping[str, Any]): The object to be serialized. Returns: str: The serialized object in json format. """ return json.dumps(obj, indent=4, default=default)
[docs] def deserialize(data: str) -> Any: """Deserialize the JSON string back to an object.""" return json.loads(data, object_hook=_deserialize_object_hook)
def _deserialize_object_hook(d: Dict[str, Any]) -> Any: """Hook to deserialize objects based on their type.""" if "type" in d and "data" in d: class_name = d["type"] class_type = EntityMapping.get(class_name) if class_type: return class_type.from_dict(d) return d
[docs] def to_dict(obj: Any) -> Dict[str, Any]: """Convert the object to a dictionary. Args: obj (Any): The object to be converted. Returns: Dict[str, Any]: The dictionary representation of the object. """ return json.loads(serialize(obj))