Skip to content

adapters

agent_cover.instrumentation.structures.adapters

Module for converting data structures to dictionaries.

This module provides adapters for converting different data structures (e.g., Pydantic models, dataclasses) into dictionaries. These adapters enable AgentCover to process data from various sources in a unified manner.

Classes

AdapterRegistry

Registry for managing structure adapters.

This registry stores and provides access to different structure adapters, allowing AgentCover to handle various data structures uniformly.

Attributes:

Name Type Description
_adapters list[StructureAdapter]

A list of StructureAdapter instances.

Methods:

Name Description
register

StructureAdapter): Registers a new adapter.

clear

Clears all registered adapters.

get_adapter_for_class

type) -> Optional[StructureAdapter]: Retrieves the adapter for a given class.

get_adapter_for_instance

Any) -> Optional[StructureAdapter]: Retrieves the adapter for a given instance.

Source code in src/agent_cover/instrumentation/structures/adapters.py
class AdapterRegistry:
    """Registry for managing structure adapters.

    This registry stores and provides access to different structure adapters,
    allowing AgentCover to handle various data structures uniformly.

    Attributes:
        _adapters: A list of StructureAdapter instances.

    Methods:
        register(adapter: StructureAdapter):
            Registers a new adapter.
        clear():
            Clears all registered adapters.
        get_adapter_for_class(cls: type) -> Optional[StructureAdapter]:
            Retrieves the adapter for a given class.
        get_adapter_for_instance(obj: Any) -> Optional[StructureAdapter]:
            Retrieves the adapter for a given instance.
    """

    def __init__(self):
        """Initializes a new AdapterRegistry instance."""
        self._adapters: list[StructureAdapter] = [
            PydanticAdapter(),
            DataclassAdapter(),
        ]

    def register(self, adapter: StructureAdapter):
        """Registers a new structure adapter.

        Args:
            adapter: The StructureAdapter instance to register.
        """
        self._adapters.insert(0, adapter)

    def clear(self):
        """Clears all registered adapters."""
        self._adapters = []

    def get_adapter_for_class(self, cls: type) -> Optional[StructureAdapter]:
        """Retrieves the adapter for a given class.

        Args:
            cls: The class to find an adapter for.

        Returns:
            The StructureAdapter instance that can handle the class, or None.
        """
        for adapter in self._adapters:
            if adapter.can_handle_class(cls):
                return adapter
        return None

    def get_adapter_for_instance(self, obj: Any) -> Optional[StructureAdapter]:
        """Retrieves the adapter for a given instance.

        Args:
            obj: The instance to find an adapter for.

        Returns:
            The StructureAdapter instance that can handle the instance, or None.
        """
        for adapter in self._adapters:
            if adapter.can_handle_instance(obj):
                return adapter
        return None
Functions
__init__()

Initializes a new AdapterRegistry instance.

Source code in src/agent_cover/instrumentation/structures/adapters.py
def __init__(self):
    """Initializes a new AdapterRegistry instance."""
    self._adapters: list[StructureAdapter] = [
        PydanticAdapter(),
        DataclassAdapter(),
    ]
clear()

Clears all registered adapters.

Source code in src/agent_cover/instrumentation/structures/adapters.py
def clear(self):
    """Clears all registered adapters."""
    self._adapters = []
get_adapter_for_class(cls)

Retrieves the adapter for a given class.

Parameters:

Name Type Description Default
cls type

The class to find an adapter for.

required

Returns:

Type Description
Optional[StructureAdapter]

The StructureAdapter instance that can handle the class, or None.

Source code in src/agent_cover/instrumentation/structures/adapters.py
def get_adapter_for_class(self, cls: type) -> Optional[StructureAdapter]:
    """Retrieves the adapter for a given class.

    Args:
        cls: The class to find an adapter for.

    Returns:
        The StructureAdapter instance that can handle the class, or None.
    """
    for adapter in self._adapters:
        if adapter.can_handle_class(cls):
            return adapter
    return None
get_adapter_for_instance(obj)

Retrieves the adapter for a given instance.

Parameters:

Name Type Description Default
obj Any

The instance to find an adapter for.

required

Returns:

Type Description
Optional[StructureAdapter]

The StructureAdapter instance that can handle the instance, or None.

Source code in src/agent_cover/instrumentation/structures/adapters.py
def get_adapter_for_instance(self, obj: Any) -> Optional[StructureAdapter]:
    """Retrieves the adapter for a given instance.

    Args:
        obj: The instance to find an adapter for.

    Returns:
        The StructureAdapter instance that can handle the instance, or None.
    """
    for adapter in self._adapters:
        if adapter.can_handle_instance(obj):
            return adapter
    return None
register(adapter)

Registers a new structure adapter.

Parameters:

Name Type Description Default
adapter StructureAdapter

The StructureAdapter instance to register.

required
Source code in src/agent_cover/instrumentation/structures/adapters.py
def register(self, adapter: StructureAdapter):
    """Registers a new structure adapter.

    Args:
        adapter: The StructureAdapter instance to register.
    """
    self._adapters.insert(0, adapter)

DataclassAdapter

Bases: StructureAdapter

Adapter for dataclasses.

This adapter is designed to convert dataclasses into dictionaries, allowing AgentCover to analyze and process data from dataclass-based data structures.

Methods:

Name Description
can_handle_class

type) -> bool: Checks if the adapter can handle a given class.

can_handle_instance

Any) -> bool: Checks if the adapter can handle a given instance.

get_fields

type) -> dict[str, type]: Retrieves the fields of a class.

to_dict

Any) -> dict: Converts a dataclass instance to a dictionary.

Source code in src/agent_cover/instrumentation/structures/adapters.py
class DataclassAdapter(StructureAdapter):
    """Adapter for dataclasses.

    This adapter is designed to convert dataclasses into dictionaries,
    allowing AgentCover to analyze and process data from dataclass-based
    data structures.

    Attributes:
        None

    Methods:
        can_handle_class(cls: type) -> bool:
            Checks if the adapter can handle a given class.
        can_handle_instance(obj: Any) -> bool:
            Checks if the adapter can handle a given instance.
        get_fields(cls: type) -> dict[str, type]:
            Retrieves the fields of a class.
        to_dict(obj: Any) -> dict:
            Converts a dataclass instance to a dictionary.
    """

    def can_handle_class(self, cls: type) -> bool:
        """Checks if the given class is a dataclass.

        Args:
            cls: The class to check.

        Returns:
            True if the class is a dataclass, False otherwise.
        """
        return isinstance(cls, type) and is_dataclass(cls)

    def can_handle_instance(self, obj: Any) -> bool:
        """Checks if the given object is an instance of a dataclass.

        Args:
            obj: The object to check.

        Returns:
            True if the object is a dataclass instance, False otherwise.
        """
        return is_dataclass(obj) and not isinstance(obj, type)

    def get_fields(self, cls: type) -> dict[str, Any]:
        """Retrieves the fields of a dataclass.

        Args:
            cls: The dataclass class.

        Returns:
            A dictionary of field names and types.
        """
        return getattr(cls, "__annotations__", {})

    def to_dict(self, obj: Any) -> dict:
        """Converts a dataclass instance to a dictionary.

        Args:
            obj: The dataclass instance.

        Returns:
            A dictionary representation of the dataclass.
        """
        return asdict(obj)
Functions
can_handle_class(cls)

Checks if the given class is a dataclass.

Parameters:

Name Type Description Default
cls type

The class to check.

required

Returns:

Type Description
bool

True if the class is a dataclass, False otherwise.

Source code in src/agent_cover/instrumentation/structures/adapters.py
def can_handle_class(self, cls: type) -> bool:
    """Checks if the given class is a dataclass.

    Args:
        cls: The class to check.

    Returns:
        True if the class is a dataclass, False otherwise.
    """
    return isinstance(cls, type) and is_dataclass(cls)
can_handle_instance(obj)

Checks if the given object is an instance of a dataclass.

Parameters:

Name Type Description Default
obj Any

The object to check.

required

Returns:

Type Description
bool

True if the object is a dataclass instance, False otherwise.

Source code in src/agent_cover/instrumentation/structures/adapters.py
def can_handle_instance(self, obj: Any) -> bool:
    """Checks if the given object is an instance of a dataclass.

    Args:
        obj: The object to check.

    Returns:
        True if the object is a dataclass instance, False otherwise.
    """
    return is_dataclass(obj) and not isinstance(obj, type)
get_fields(cls)

Retrieves the fields of a dataclass.

Parameters:

Name Type Description Default
cls type

The dataclass class.

required

Returns:

Type Description
dict[str, Any]

A dictionary of field names and types.

Source code in src/agent_cover/instrumentation/structures/adapters.py
def get_fields(self, cls: type) -> dict[str, Any]:
    """Retrieves the fields of a dataclass.

    Args:
        cls: The dataclass class.

    Returns:
        A dictionary of field names and types.
    """
    return getattr(cls, "__annotations__", {})
to_dict(obj)

Converts a dataclass instance to a dictionary.

Parameters:

Name Type Description Default
obj Any

The dataclass instance.

required

Returns:

Type Description
dict

A dictionary representation of the dataclass.

Source code in src/agent_cover/instrumentation/structures/adapters.py
def to_dict(self, obj: Any) -> dict:
    """Converts a dataclass instance to a dictionary.

    Args:
        obj: The dataclass instance.

    Returns:
        A dictionary representation of the dataclass.
    """
    return asdict(obj)

PydanticAdapter

Bases: StructureAdapter

Adapter for Pydantic models.

This adapter is designed to convert Pydantic models into dictionaries, allowing AgentCover to analyze and process data from Pydantic-based data structures. It supports both Pydantic V1 and V2.

Attributes:

Name Type Description
BaseModel

The Pydantic BaseModel class (dynamically imported).

Methods:

Name Description
can_handle_class

type) -> bool: Checks if the adapter can handle a given class.

can_handle_instance

Any) -> bool: Checks if the adapter can handle a given instance.

get_fields

type) -> dict[str, type]: Retrieves the fields of a class.

to_dict

Any) -> dict: Converts a Pydantic model instance to a dictionary.

Source code in src/agent_cover/instrumentation/structures/adapters.py
class PydanticAdapter(StructureAdapter):
    """Adapter for Pydantic models.

    This adapter is designed to convert Pydantic models into dictionaries,
    allowing AgentCover to analyze and process data from Pydantic-based
    data structures. It supports both Pydantic V1 and V2.

    Attributes:
        BaseModel: The Pydantic BaseModel class (dynamically imported).

    Methods:
        can_handle_class(cls: type) -> bool:
            Checks if the adapter can handle a given class.
        can_handle_instance(obj: Any) -> bool:
            Checks if the adapter can handle a given instance.
        get_fields(cls: type) -> dict[str, type]:
            Retrieves the fields of a class.
        to_dict(obj: Any) -> dict:
            Converts a Pydantic model instance to a dictionary.
    """

    def __init__(self, pydantic_module: Any = None):
        """Initializes a PydanticAdapter instance.

        Args:
            pydantic_module:  Optional. Dependency Injection of the pydantic module.
                If None, attempts to import it. If passed (e.g., Mock), uses that.
        """
        self.BaseModel = None

        if pydantic_module:
            # Test Case: Using the injected mocked module
            self.BaseModel = getattr(pydantic_module, "BaseModel", None)
        else:
            # Runtime Case: Let's try the real import
            try:
                import pydantic

                self.BaseModel = pydantic.BaseModel
            except ImportError:
                pass

    def can_handle_class(self, cls: type) -> bool:
        """Checks if the given class is a Pydantic model.

        Args:
            cls: The class to check.

        Returns:
            True if the class is a Pydantic model, False otherwise.
        """
        if self.BaseModel is None:
            return False
        # Robust verification to avoid false positives with mocks
        try:
            return (
                isinstance(cls, type)
                and issubclass(cls, self.BaseModel)
                and cls is not self.BaseModel
            )
        except TypeError:
            return False

    def can_handle_instance(self, obj: Any) -> bool:
        """Checks if the given object is an instance of a Pydantic model.

        Args:
            obj: The object to check.

        Returns:
            True if the object is a Pydantic model instance, False otherwise.
        """
        if self.BaseModel is None:
            return False
        return isinstance(obj, self.BaseModel)

    def get_fields(self, cls: type) -> dict[str, Any]:
        """Retrieves the fields of a Pydantic model.

        Args:
            cls: The Pydantic model class.

        Returns:
            A dictionary of field names and types.
        """
        # Dual V1/V2 support
        fields_info = getattr(cls, "model_fields", None)  # Pydantic V2
        if fields_info is None:
            fields_info = getattr(cls, "__fields__", {})  # Pydantic V1

        extracted = {}
        for name, info in fields_info.items():
            # In V1 info.type_, in V2 info.annotation
            extracted[name] = getattr(info, "annotation", getattr(info, "type_", None))
        return extracted

    def to_dict(self, obj: Any) -> dict:
        """Converts a Pydantic model instance to a dictionary.

        Args:
            obj: The Pydantic model instance.

        Returns:
            A dictionary representation of the Pydantic model.
        """
        # Dual V1/V2 dump support
        if hasattr(obj, "model_dump"):
            return obj.model_dump()  # V2
        if hasattr(obj, "dict"):
            return obj.dict()  # V1
        return {}
Functions
__init__(pydantic_module=None)

Initializes a PydanticAdapter instance.

Parameters:

Name Type Description Default
pydantic_module Any

Optional. Dependency Injection of the pydantic module. If None, attempts to import it. If passed (e.g., Mock), uses that.

None
Source code in src/agent_cover/instrumentation/structures/adapters.py
def __init__(self, pydantic_module: Any = None):
    """Initializes a PydanticAdapter instance.

    Args:
        pydantic_module:  Optional. Dependency Injection of the pydantic module.
            If None, attempts to import it. If passed (e.g., Mock), uses that.
    """
    self.BaseModel = None

    if pydantic_module:
        # Test Case: Using the injected mocked module
        self.BaseModel = getattr(pydantic_module, "BaseModel", None)
    else:
        # Runtime Case: Let's try the real import
        try:
            import pydantic

            self.BaseModel = pydantic.BaseModel
        except ImportError:
            pass
can_handle_class(cls)

Checks if the given class is a Pydantic model.

Parameters:

Name Type Description Default
cls type

The class to check.

required

Returns:

Type Description
bool

True if the class is a Pydantic model, False otherwise.

Source code in src/agent_cover/instrumentation/structures/adapters.py
def can_handle_class(self, cls: type) -> bool:
    """Checks if the given class is a Pydantic model.

    Args:
        cls: The class to check.

    Returns:
        True if the class is a Pydantic model, False otherwise.
    """
    if self.BaseModel is None:
        return False
    # Robust verification to avoid false positives with mocks
    try:
        return (
            isinstance(cls, type)
            and issubclass(cls, self.BaseModel)
            and cls is not self.BaseModel
        )
    except TypeError:
        return False
can_handle_instance(obj)

Checks if the given object is an instance of a Pydantic model.

Parameters:

Name Type Description Default
obj Any

The object to check.

required

Returns:

Type Description
bool

True if the object is a Pydantic model instance, False otherwise.

Source code in src/agent_cover/instrumentation/structures/adapters.py
def can_handle_instance(self, obj: Any) -> bool:
    """Checks if the given object is an instance of a Pydantic model.

    Args:
        obj: The object to check.

    Returns:
        True if the object is a Pydantic model instance, False otherwise.
    """
    if self.BaseModel is None:
        return False
    return isinstance(obj, self.BaseModel)
get_fields(cls)

Retrieves the fields of a Pydantic model.

Parameters:

Name Type Description Default
cls type

The Pydantic model class.

required

Returns:

Type Description
dict[str, Any]

A dictionary of field names and types.

Source code in src/agent_cover/instrumentation/structures/adapters.py
def get_fields(self, cls: type) -> dict[str, Any]:
    """Retrieves the fields of a Pydantic model.

    Args:
        cls: The Pydantic model class.

    Returns:
        A dictionary of field names and types.
    """
    # Dual V1/V2 support
    fields_info = getattr(cls, "model_fields", None)  # Pydantic V2
    if fields_info is None:
        fields_info = getattr(cls, "__fields__", {})  # Pydantic V1

    extracted = {}
    for name, info in fields_info.items():
        # In V1 info.type_, in V2 info.annotation
        extracted[name] = getattr(info, "annotation", getattr(info, "type_", None))
    return extracted
to_dict(obj)

Converts a Pydantic model instance to a dictionary.

Parameters:

Name Type Description Default
obj Any

The Pydantic model instance.

required

Returns:

Type Description
dict

A dictionary representation of the Pydantic model.

Source code in src/agent_cover/instrumentation/structures/adapters.py
def to_dict(self, obj: Any) -> dict:
    """Converts a Pydantic model instance to a dictionary.

    Args:
        obj: The Pydantic model instance.

    Returns:
        A dictionary representation of the Pydantic model.
    """
    # Dual V1/V2 dump support
    if hasattr(obj, "model_dump"):
        return obj.model_dump()  # V2
    if hasattr(obj, "dict"):
        return obj.dict()  # V1
    return {}

StructureAdapter

Bases: ABC

Abstract base class for structure adapters.

Structure adapters are responsible for converting objects of different types into dictionaries, enabling unified handling of various data structures within the AgentCover framework.

Methods:

Name Description
can_handle_class

type) -> bool: Abstract method to check if the adapter can handle a given class.

can_handle_instance

Any) -> bool: Abstract method to check if the adapter can handle a given instance.

get_fields

type) -> dict[str, type]: Abstract method to retrieve the fields of a class.

to_dict

Any) -> dict: Abstract method to convert an object to a dictionary.

Source code in src/agent_cover/instrumentation/structures/adapters.py
class StructureAdapter(ABC):
    """Abstract base class for structure adapters.

    Structure adapters are responsible for converting objects of different
    types into dictionaries, enabling unified handling of various data
    structures within the AgentCover framework.

    Attributes:
        None

    Methods:
        can_handle_class(cls: type) -> bool:
            Abstract method to check if the adapter can handle a given class.
        can_handle_instance(obj: Any) -> bool:
            Abstract method to check if the adapter can handle a given instance.
        get_fields(cls: type) -> dict[str, type]:
            Abstract method to retrieve the fields of a class.
        to_dict(obj: Any) -> dict:
            Abstract method to convert an object to a dictionary.
    """

    @abstractmethod
    def can_handle_class(self, cls: type) -> bool:
        """Checks if this adapter can handle the given class.

        Args:
            cls: The class to check.

        Returns:
            True if the adapter can handle the class, False otherwise.
        """
        pass

    @abstractmethod
    def can_handle_instance(self, obj: Any) -> bool:
        """Checks if this adapter can handle the given instance.

        Args:
            obj: The instance to check.

        Returns:
            True if the adapter can handle the instance, False otherwise.
        """
        pass

    @abstractmethod
    def get_fields(self, cls: type) -> dict[str, type]:
        """Retrieves the fields of the given class.

        Args:
            cls: The class to inspect.

        Returns:
            A dictionary where keys are field names and values are field types.
        """
        pass

    @abstractmethod
    def to_dict(self, obj: Any) -> dict:
        """Converts the given object to a dictionary.

        Args:
            obj: The object to convert.

        Returns:
            A dictionary representation of the object.
        """
        pass
Functions
can_handle_class(cls) abstractmethod

Checks if this adapter can handle the given class.

Parameters:

Name Type Description Default
cls type

The class to check.

required

Returns:

Type Description
bool

True if the adapter can handle the class, False otherwise.

Source code in src/agent_cover/instrumentation/structures/adapters.py
@abstractmethod
def can_handle_class(self, cls: type) -> bool:
    """Checks if this adapter can handle the given class.

    Args:
        cls: The class to check.

    Returns:
        True if the adapter can handle the class, False otherwise.
    """
    pass
can_handle_instance(obj) abstractmethod

Checks if this adapter can handle the given instance.

Parameters:

Name Type Description Default
obj Any

The instance to check.

required

Returns:

Type Description
bool

True if the adapter can handle the instance, False otherwise.

Source code in src/agent_cover/instrumentation/structures/adapters.py
@abstractmethod
def can_handle_instance(self, obj: Any) -> bool:
    """Checks if this adapter can handle the given instance.

    Args:
        obj: The instance to check.

    Returns:
        True if the adapter can handle the instance, False otherwise.
    """
    pass
get_fields(cls) abstractmethod

Retrieves the fields of the given class.

Parameters:

Name Type Description Default
cls type

The class to inspect.

required

Returns:

Type Description
dict[str, type]

A dictionary where keys are field names and values are field types.

Source code in src/agent_cover/instrumentation/structures/adapters.py
@abstractmethod
def get_fields(self, cls: type) -> dict[str, type]:
    """Retrieves the fields of the given class.

    Args:
        cls: The class to inspect.

    Returns:
        A dictionary where keys are field names and values are field types.
    """
    pass
to_dict(obj) abstractmethod

Converts the given object to a dictionary.

Parameters:

Name Type Description Default
obj Any

The object to convert.

required

Returns:

Type Description
dict

A dictionary representation of the object.

Source code in src/agent_cover/instrumentation/structures/adapters.py
@abstractmethod
def to_dict(self, obj: Any) -> dict:
    """Converts the given object to a dictionary.

    Args:
        obj: The object to convert.

    Returns:
        A dictionary representation of the object.
    """
    pass

Functions

get_default_adapter_registry()

Retrieves the default AdapterRegistry instance.

Returns:

Type Description

The default AdapterRegistry instance.

Source code in src/agent_cover/instrumentation/structures/adapters.py
def get_default_adapter_registry():
    """Retrieves the default AdapterRegistry instance.

    Returns:
        The default AdapterRegistry instance.
    """
    return _default_adapter_registry