Skip to content

Core Utilities API Reference

This page provides detailed API documentation for SPOC's core utility modules, including exceptions, singleton patterns, dependency management, case conversion, and path injection utilities.

Exceptions

SPOC provides a hierarchy of custom exceptions for clear error handling and debugging.

SpocError

spoc.core.exceptions.SpocError(message, module_name=None)

Base exception for all dynamic import errors.

Parameters:

  • message (str) –

    The error message.

  • module_name (str | None, default: None ) –

    Name of the module that caused the error, if applicable.

AppNotFoundError

spoc.core.exceptions.AppNotFoundError(module_name)

Raised when a module cannot be found during dynamic import.

Parameters:

  • module_name (str) –

    Name of the module that could not be found.

ModuleNotCachedError

spoc.core.exceptions.ModuleNotCachedError(module_name)

Raised when attempting to access a module that is not in the cache.

Parameters:

  • module_name (str) –

    Name of the module that is not cached.

CircularDependencyError

spoc.core.exceptions.CircularDependencyError(modules)

Raised when a circular dependency is detected during startup/shutdown.

Parameters:

  • modules (list[str]) –

    List of modules involved in the circular dependency.

LifecycleError

spoc.core.exceptions.LifecycleError(message, module_name=None)

Raised when an error occurs during module lifecycle operations.

Parameters:

  • message (str) –

    The error message.

  • module_name (str | None, default: None ) –

    Name of the module where the lifecycle error occurred.

ConfigurationError

spoc.core.exceptions.ConfigurationError(message, config_file=None, original_error=None)

Error in configuration loading or validation.

Parameters:

  • message (str) –

    Error message

  • config_file (str | None, default: None ) –

    The configuration file that caused the error

  • original_error (Exception | None, default: None ) –

    The original exception that caused this error

Singleton Pattern

SPOC provides two approaches to implementing the Singleton pattern: a metaclass and a decorator.

SingletonMeta

spoc.core.singleton.SingletonMeta

Metaclass that creates a Singleton class.

Any class using this metaclass will have only one instance, with subsequent instantiations returning the same instance.

Example:

class SingletonClass(metaclass=SingletonMeta):
    def __init__(self, value=None):
        self.value = value or "default"

reset(mcs, target_cls=None) classmethod

Reset the singleton instance(s).

Parameters:

  • target_cls (type | None, default: None ) –

    A specific class to reset. If None, resets all instances.

This method is particularly useful for testing scenarios.

singleton Decorator

spoc.core.singleton.singleton(cls)

Decorator to convert a class into a Singleton.

Parameters:

  • cls (Type[T]) –

    The class to convert to a Singleton.

Returns:

  • Callable[..., T]

    A wrapped function that returns the singleton instance.

Example:

@singleton
class SingletonClass:
    def __init__(self, value=None):
        self.value = value or "default"

Dependency Management

DependencyGraph

spoc.core.utils.DependencyGraph()

Graph data structure for managing dependencies and their resolution order.

This class provides topological sorting algorithms to handle module dependencies for initialization and teardown procedures.

Time Complexity
  • Addition of nodes and edges: O(1)
  • Topological sort: O(V + E) where V is number of nodes and E is number of edges

add_node(node)

Add a node to the graph.

Parameters:

  • node (T) –

    The node to add.

add_edge(from_node, to_node)

Add a directed edge from one node to another.

Parameters:

  • from_node (T) –

    The source node.

  • to_node (T) –

    The target node that depends on the source.

topological_sort()

Perform topological sort on the graph.

Returns:

  • List[T]

    A list of nodes in topological order.

Raises:

reversed()

Create a new graph with all edges reversed.

Useful for shutdown sequence where dependencies need to be torn down in reverse order of initialization.

Returns:

  • 'DependencyGraph[T]'

    A new DependencyGraph with reversed edges.

Utility Functions

spoc.core.utils.get_attribute(obj, attr_path)

Get an attribute from an object using a dot-separated path.

Parameters:

  • obj (object) –

    The object to get the attribute from.

  • attr_path (str) –

    Dot-separated path to the attribute (e.g., "config.debug").

Returns:

  • object

    The attribute value.

Raises:

  • AttributeError

    If any part of the path doesn't exist.

Case Style Conversion

SPOC provides utilities to convert strings between different naming conventions.

case_style Function

spoc.case_style.case_style(s, mode='snake', clip_edges=True)

Convert string s between case styles by normalizing to words first.

Examples:

>>> case_style("HelloWorld", "snake")
"hello_world"
>>> case_style("hello_world", "pascal")
"HelloWorld"
>>> case_style("Hello-World", "kebab")
"hello-world"

Conversion Functions

spoc.case_style.to_snake_case(s, clip_edges=True) cached

AnyCase → snake_case.

spoc.case_style.to_camel_case(s) cached

snake_case (or any) → camelCase.

spoc.case_style.to_pascal_case(s) cached

snake_case (or any) → PascalCase.

spoc.case_style.to_kebab_case(s) cached

snake_case (or any) → kebab-case.

Type Guards

spoc.case_style.is_valid_case_style(mode)

True if mode is one of the supported case styles.

Path Injection

inject_apps Function

spoc.inject_apps.inject_apps(base_dir, apps_dir_name='apps', *, position=0)

Ensure an 'apps' directory exists under base_dir and inject it into Python's import path.

Helper Functions

spoc.inject_apps.ensure_directory(path, *, exist_ok=True)

Ensure that the given directory exists.

spoc.inject_apps.add_to_python_path(path, position=0)

Insert the given path into sys.path if not already present.