Index
provide.foundation
¶
TODO: Add module docstring.
Classes¶
AsyncCircuitBreaker
¶
AsyncCircuitBreaker(
failure_threshold: int = 5,
recovery_timeout: float = 30.0,
expected_exception: (
type[Exception] | tuple[type[Exception], ...]
) = Exception,
time_source: Callable[[], float] | None = None,
)
Asynchronous circuit breaker for resilience patterns.
Uses asyncio.Lock for async-safe state management. For synchronous code, use SyncCircuitBreaker instead.
Initialize the asynchronous circuit breaker.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
failure_threshold
|
int
|
Number of failures before opening circuit |
5
|
recovery_timeout
|
float
|
Seconds to wait before attempting recovery |
30.0
|
expected_exception
|
type[Exception] | tuple[type[Exception], ...]
|
Exception type(s) to catch |
Exception
|
time_source
|
Callable[[], float] | None
|
Optional callable that returns current time (for testing). Defaults to time.time() for production use. |
None
|
Source code in provide/foundation/resilience/circuit_async.py
Functions¶
call
async
¶
Execute an asynchronous function through the circuit breaker.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Callable
|
Async callable to execute |
required |
*args
|
Any
|
Positional arguments for func |
()
|
**kwargs
|
Any
|
Keyword arguments for func |
{}
|
Returns:
| Type | Description |
|---|---|
Any
|
Result from func |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If circuit is open |
Exception
|
Whatever exception func raises |
Source code in provide/foundation/resilience/circuit_async.py
failure_count
async
¶
reset
async
¶
Reset the circuit breaker to its initial state.
state
async
¶
Get the current state of the circuit breaker.
Returns:
| Type | Description |
|---|---|
CircuitState
|
Current circuit state |
Source code in provide/foundation/resilience/circuit_async.py
CLIContext
¶
Bases: RuntimeConfig
Runtime context for CLI execution and state management.
Manages CLI-specific settings, output formatting, and runtime state during command execution. Supports loading from files, environment variables, and programmatic updates during CLI command execution.
Attributes¶
Functions¶
__attrs_post_init__
¶
copy
¶
freeze
¶
Freeze context to prevent further modifications.
from_dict
classmethod
¶
Create context from dictionary.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
dict[str, Any]
|
Dictionary with context values |
required |
source
|
ConfigSource
|
Source of the configuration data |
RUNTIME
|
Returns:
| Type | Description |
|---|---|
CLIContext
|
New CLIContext instance |
Source code in provide/foundation/context/core.py
load_config
¶
Load configuration from file.
Supports TOML, JSON, and YAML formats based on file extension.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Path to configuration file |
required |
Source code in provide/foundation/context/core.py
merge
¶
Merge with another context, with other taking precedence.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
other
|
CLIContext
|
CLIContext to merge with |
required |
override_defaults
|
bool
|
If False, only override if other's value differs from its class default |
False
|
Returns:
| Type | Description |
|---|---|
CLIContext
|
New merged CLIContext instance |
Source code in provide/foundation/context/core.py
save_config
¶
Save configuration to file.
Format is determined by file extension.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Path to save configuration |
required |
Source code in provide/foundation/context/core.py
to_dict
¶
Convert context to dictionary.
Source code in provide/foundation/context/core.py
update_from_env
¶
Update context from environment variables.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prefix
|
str
|
Environment variable prefix (default: PROVIDE) |
'PROVIDE'
|
Source code in provide/foundation/context/core.py
ComponentCategory
¶
Bases: Enum
Predefined component categories for Foundation.
These are the standard dimension values used internally by Foundation. External components can still use custom string dimensions for compatibility.
EventMapping
¶
Individual event enrichment mapping for a specific domain.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Unique identifier for this mapping |
visual_markers |
dict[str, str]
|
Mapping of values to visual indicators (e.g., emojis) |
metadata_fields |
dict[str, dict[str, Any]]
|
Additional metadata to attach based on values |
transformations |
dict[str, Callable[[Any], Any]]
|
Value transformation functions |
default_key |
str
|
Key to use when no specific match is found |
EventSet
¶
Complete event enrichment domain definition.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Unique identifier for this event set |
description |
str | None
|
Human-readable description |
mappings |
list[EventMapping]
|
List of EventMapping definitions |
field_mappings |
list[FieldMapping]
|
List of field-to-mapping associations |
priority |
int
|
Higher priority sets override lower ones |
FallbackChain
¶
Chain of fallback strategies for graceful degradation.
Executes fallback functions in order when primary function fails.
Functions¶
add_fallback
¶
Add a fallback function to the chain.
Source code in provide/foundation/resilience/fallback.py
execute
¶
Execute primary function with fallback chain (sync).
Source code in provide/foundation/resilience/fallback.py
execute_async
async
¶
Execute primary function with fallback chain (async).
Source code in provide/foundation/resilience/fallback.py
FieldMapping
¶
Maps a log field to an event set for enrichment.
Attributes:
| Name | Type | Description |
|---|---|---|
log_key |
str
|
The field key in log events (e.g., "http.method", "llm.provider") |
description |
str | None
|
Human-readable description of this field |
value_type |
str | None
|
Expected type of the field value |
event_set_name |
str | None
|
Name of the EventSet to use for enrichment |
default_override_key |
str | None
|
Override the default key for this specific field |
default_value |
Any | None
|
Default value to use if field is not present |
FoundationError
¶
FoundationError(
message: str,
*,
code: str | None = None,
context: dict[str, Any] | None = None,
cause: Exception | None = None,
**extra_context: Any
)
Bases: Exception
Base exception for all Foundation errors.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str
|
Human-readable error message. |
required |
code
|
str | None
|
Optional error code for programmatic handling. |
None
|
context
|
dict[str, Any] | None
|
Optional context dictionary with diagnostic data. |
None
|
cause
|
Exception | None
|
Optional underlying exception that caused this error. |
None
|
**extra_context
|
Any
|
Additional key-value pairs added to context. |
{}
|
Examples:
>>> raise FoundationError("Operation failed")
>>> raise FoundationError("Operation failed", code="OP_001")
>>> raise FoundationError("Operation failed", user_id=123, retry_count=3)
Source code in provide/foundation/errors/base.py
Functions¶
add_context
¶
Add context data to the error.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Context key (use dots for namespacing, e.g., 'aws.region'). |
required |
value
|
Any
|
Context value. |
required |
Returns:
| Type | Description |
|---|---|
FoundationError
|
Self for method chaining. |
Source code in provide/foundation/errors/base.py
to_dict
¶
Convert exception to dictionary for structured logging.
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Dictionary representation suitable for logging/serialization. |
Source code in provide/foundation/errors/base.py
Hub
¶
Hub(
context: CLIContext | None = None,
component_registry: Registry | None = None,
command_registry: Registry | None = None,
use_shared_registries: bool = False,
)
Bases: CoreHub
Central hub for managing components, commands, and Foundation integration.
The Hub provides a unified interface for: - Registering components and commands - Discovering plugins via entry points - Creating Click CLI applications - Managing component lifecycle - Foundation system initialization
Example
hub = Hub() hub.add_component(MyResource, "resource") hub.add_command(init_cmd, "init") hub.initialize_foundation()
Create CLI with all commands¶
cli = hub.create_cli() cli()
Initialize the hub.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
context
|
CLIContext | None
|
Foundation CLIContext for configuration |
None
|
component_registry
|
Registry | None
|
Custom component registry |
None
|
command_registry
|
Registry | None
|
Custom command registry |
None
|
use_shared_registries
|
bool
|
If True, use global shared registries |
False
|
Source code in provide/foundation/hub/manager.py
Functions¶
clear
¶
Clear registrations and dispose of resources properly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dimension
|
str | None
|
Optional dimension to clear (None = all) |
None
|
Source code in provide/foundation/hub/manager.py
dispose_all
¶
Dispose of all managed resources without clearing registrations.
get_foundation_config
¶
get_foundation_logger
¶
Get Foundation logger instance through Hub.
Auto-initializes Foundation if not already done. Thread-safe with fallback behavior.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str | None
|
Logger name (e.g., module name) |
None
|
Returns:
| Type | Description |
|---|---|
Any
|
Configured logger instance |
Source code in provide/foundation/hub/manager.py
initialize_foundation
¶
Initialize Foundation system through Hub.
Single initialization method replacing all setup_* functions. Thread-safe and idempotent, unless force=True.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
Any
|
Optional TelemetryConfig (defaults to from_env) |
None
|
force
|
bool
|
If True, force re-initialization even if already initialized |
False
|
Source code in provide/foundation/hub/manager.py
is_foundation_initialized
¶
LoggingConfig
¶
Registry
¶
Multi-dimensional registry for storing and retrieving objects.
Supports hierarchical organization by dimension (component, command, etc.) and name within each dimension. This is a generic registry that can be used for any type of object storage and retrieval.
Thread-safe: All operations are protected by an RLock for safe concurrent access.
Note: Uses threading.RLock (not asyncio.Lock) for thread safety. For async-only applications with high-frequency registry access in request hot-paths (>10k req/sec with runtime registration), consider using an async-native registry implementation with asyncio.Lock. For typical use cases (initialization-time registration, CLI apps, read-heavy workloads), the threading lock has negligible impact.
See: docs/architecture/design-decisions.md#threading-model
Initialize an empty registry.
Source code in provide/foundation/hub/registry.py
Functions¶
__contains__
¶
Check if an item exists in the registry.
Source code in provide/foundation/hub/registry.py
__iter__
¶
Iterate over all registry entries.
Source code in provide/foundation/hub/registry.py
__len__
¶
clear
¶
Clear the registry or a specific dimension.
Source code in provide/foundation/hub/registry.py
dispose_all
¶
get
¶
Get an item from the registry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Name or alias of the item |
required |
dimension
|
str | None
|
Optional dimension to search in |
None
|
Returns:
| Type | Description |
|---|---|
Any | None
|
The registered value or None if not found |
Source code in provide/foundation/hub/registry.py
get_by_type
¶
Get a registered instance by its type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
type_hint
|
type[Any]
|
Type to look up |
required |
Returns:
| Type | Description |
|---|---|
Any | None
|
Registered instance or None if not found |
Example
db = registry.get_by_type(DatabaseClient)
Source code in provide/foundation/hub/registry.py
get_entry
¶
Get the full registry entry.
Source code in provide/foundation/hub/registry.py
list_all
¶
list_dimension
¶
list_types
¶
register
¶
register(
name: str,
value: Any,
dimension: str = "default",
metadata: dict[str, Any] | None = None,
aliases: list[str] | None = None,
replace: bool = False,
) -> RegistryEntry
Register an item in the registry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Unique name within the dimension |
required |
value
|
Any
|
The item to register |
required |
dimension
|
str
|
Registry dimension for categorization |
'default'
|
metadata
|
dict[str, Any] | None
|
Optional metadata about the item |
None
|
aliases
|
list[str] | None
|
Optional list of aliases for this item |
None
|
replace
|
bool
|
Whether to replace existing entries |
False
|
Returns:
| Type | Description |
|---|---|
RegistryEntry
|
The created registry entry |
Raises:
| Type | Description |
|---|---|
ValueError
|
If name already exists and replace=False |
Source code in provide/foundation/hub/registry.py
register_type
¶
Register an instance by its type for dependency injection.
This enables type-based lookup which is essential for DI patterns.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
type_hint
|
type[Any]
|
Type to register under |
required |
instance
|
Any
|
Instance to register |
required |
name
|
str | None
|
Optional name for standard registry (defaults to type name) |
None
|
Example
registry.register_type(DatabaseClient, db_instance) db = registry.get_by_type(DatabaseClient)
Source code in provide/foundation/hub/registry.py
remove
¶
Remove an item from the registry.
Returns:
| Type | Description |
|---|---|
bool
|
True if item was removed, False if not found |
Source code in provide/foundation/hub/registry.py
RegistryEntry
¶
RetryExecutor
¶
RetryExecutor(
policy: RetryPolicy,
on_retry: (
Callable[[int, Exception], None] | None
) = None,
time_source: Callable[[], float] | None = None,
sleep_func: Callable[[float], None] | None = None,
async_sleep_func: (
Callable[[float], Awaitable[None]] | None
) = None,
)
Unified retry execution engine.
This executor handles the actual retry loop logic for both sync and async functions, using a RetryPolicy for configuration. It's used internally by both the @retry decorator and RetryMiddleware.
Initialize retry executor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
policy
|
RetryPolicy
|
Retry policy configuration |
required |
on_retry
|
Callable[[int, Exception], None] | None
|
Optional callback for retry events (attempt, error) |
None
|
time_source
|
Callable[[], float] | None
|
Optional callable that returns current time (for testing). Defaults to time.time() for production use. |
None
|
sleep_func
|
Callable[[float], None] | None
|
Optional synchronous sleep function (for testing). Defaults to time.sleep() for production use. |
None
|
async_sleep_func
|
Callable[[float], Awaitable[None]] | None
|
Optional asynchronous sleep function (for testing). Defaults to asyncio.sleep() for production use. |
None
|
Source code in provide/foundation/resilience/retry.py
Functions¶
execute_async
async
¶
Execute asynchronous function with retry logic.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Callable[..., Awaitable[T]]
|
Async function to execute |
required |
*args
|
Any
|
Positional arguments for func |
()
|
**kwargs
|
Any
|
Keyword arguments for func |
{}
|
Returns:
| Type | Description |
|---|---|
T
|
Result from successful execution |
Raises:
| Type | Description |
|---|---|
Exception
|
The last exception raised if all retry attempts are exhausted |
Source code in provide/foundation/resilience/retry.py
execute_sync
¶
Execute synchronous function with retry logic.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Callable[..., T]
|
Function to execute |
required |
*args
|
Any
|
Positional arguments for func |
()
|
**kwargs
|
Any
|
Keyword arguments for func |
{}
|
Returns:
| Type | Description |
|---|---|
T
|
Result from successful execution |
Raises:
| Type | Description |
|---|---|
Exception
|
The last exception raised if all retry attempts are exhausted |
Source code in provide/foundation/resilience/retry.py
RetryPolicy
¶
Configuration for retry behavior.
This policy can be used with both the @retry decorator and transport middleware, providing a unified configuration model for all retry scenarios.
Attributes:
| Name | Type | Description |
|---|---|---|
max_attempts |
int
|
Maximum number of retry attempts (must be >= 1) |
backoff |
BackoffStrategy
|
Backoff strategy to use for delays |
base_delay |
float
|
Base delay in seconds between retries |
max_delay |
float
|
Maximum delay in seconds (caps exponential growth) |
jitter |
bool
|
Whether to add random jitter to delays (±25%) |
retryable_errors |
tuple[type[Exception], ...] | None
|
Tuple of exception types to retry (None = all) |
retryable_status_codes |
set[int] | None
|
Set of HTTP status codes to retry (for middleware) |
Functions¶
__str__
¶
Human-readable string representation.
calculate_delay
¶
Calculate delay for a given attempt number.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attempt
|
int
|
Attempt number (1-based) |
required |
Returns:
| Type | Description |
|---|---|
float
|
Delay in seconds |
Source code in provide/foundation/resilience/retry.py
should_retry
¶
Determine if an error should be retried.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
error
|
Exception
|
The exception that occurred |
required |
attempt
|
int
|
Current attempt number (1-based) |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if should retry, False otherwise |
Source code in provide/foundation/resilience/retry.py
should_retry_response
¶
Check if HTTP response should be retried.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
response
|
Any
|
Response object with status attribute |
required |
attempt
|
int
|
Current attempt number (1-based) |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if should retry, False otherwise |
Source code in provide/foundation/resilience/retry.py
SyncCircuitBreaker
¶
SyncCircuitBreaker(
failure_threshold: int = 5,
recovery_timeout: float = 30.0,
expected_exception: (
type[Exception] | tuple[type[Exception], ...]
) = Exception,
time_source: Callable[[], float] | None = None,
)
Synchronous circuit breaker for resilience patterns.
Uses threading.RLock for thread-safe state management in synchronous code. For async code, use AsyncCircuitBreaker instead.
Initialize the synchronous circuit breaker.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
failure_threshold
|
int
|
Number of failures before opening circuit |
5
|
recovery_timeout
|
float
|
Seconds to wait before attempting recovery |
30.0
|
expected_exception
|
type[Exception] | tuple[type[Exception], ...]
|
Exception type(s) to catch |
Exception
|
time_source
|
Callable[[], float] | None
|
Optional callable that returns current time (for testing). Defaults to time.time() for production use. |
None
|
Source code in provide/foundation/resilience/circuit_sync.py
Functions¶
call
¶
Execute a synchronous function through the circuit breaker.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Callable
|
Callable to execute |
required |
*args
|
Any
|
Positional arguments for func |
()
|
**kwargs
|
Any
|
Keyword arguments for func |
{}
|
Returns:
| Type | Description |
|---|---|
Any
|
Result from func |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If circuit is open |
Exception
|
Whatever exception func raises |
Source code in provide/foundation/resilience/circuit_sync.py
failure_count
¶
reset
¶
Reset the circuit breaker to its initial state.
state
¶
Get the current state of the circuit breaker.
Source code in provide/foundation/resilience/circuit_sync.py
TelemetryConfig
¶
Bases: RuntimeConfig
Main configuration object for the Foundation Telemetry system.
Functions¶
from_env
classmethod
¶
from_env(
prefix: str = "",
delimiter: str = "_",
case_sensitive: bool = False,
) -> TelemetryConfig
Load configuration from environment variables.
This method explicitly provides the from_env() interface to ensure it's available on TelemetryConfig directly.
If OpenObserve is configured and reachable, OTLP settings are automatically configured if not already set.
Source code in provide/foundation/logger/config/telemetry.py
TokenBucketRateLimiter
¶
TokenBucketRateLimiter(
capacity: float,
refill_rate: float,
time_source: Callable[[], float] | None = None,
)
A Token Bucket rate limiter for asyncio applications.
This limiter allows for bursts up to a specified capacity and refills tokens at a constant rate. It is designed to be thread-safe using an asyncio.Lock.
Initialize the TokenBucketRateLimiter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
capacity
|
float
|
The maximum number of tokens the bucket can hold (burst capacity). |
required |
refill_rate
|
float
|
The rate at which tokens are refilled per second. |
required |
time_source
|
Callable[[], float] | None
|
Optional callable that returns current time (for testing). Defaults to time.monotonic. |
None
|
Source code in provide/foundation/utils/rate_limiting.py
Functions¶
get_current_tokens
async
¶
Returns the current number of tokens, for testing/monitoring.
Source code in provide/foundation/utils/rate_limiting.py
is_allowed
async
¶
Check if a request is allowed based on available tokens.
This method is asynchronous and thread-safe. It refills tokens based on elapsed time and then attempts to consume a token.
Returns:
| Type | Description |
|---|---|
bool
|
True if the request is allowed, False otherwise. |
Source code in provide/foundation/utils/rate_limiting.py
Functions¶
__getattr__
¶
Support lazy loading of modules and version.
This reduces initial import overhead by deferring module imports and version loading until first access.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Attribute name to lazy-load |
required |
Returns:
| Type | Description |
|---|---|
object
|
The imported module or attribute |
Raises:
| Type | Description |
|---|---|
AttributeError
|
If attribute doesn't exist |
ImportError
|
If module import fails |
Source code in provide/foundation/__init__.py
check_optional_deps
¶
check_optional_deps(
*, quiet: bool = False, return_status: bool = False
) -> list[DependencyStatus] | None
Check and display optional dependency status.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
quiet
|
bool
|
If True, don't print status (just return it) |
False
|
return_status
|
bool
|
If True, return the status list |
False
|
Returns:
| Type | Description |
|---|---|
list[DependencyStatus] | None
|
Optional list of dependency statuses if return_status=True |
Source code in provide/foundation/utils/deps.py
circuit_breaker
¶
circuit_breaker(
failure_threshold: int = 5,
recovery_timeout: float = DEFAULT_CIRCUIT_BREAKER_RECOVERY_TIMEOUT,
expected_exception: (
type[Exception] | tuple[type[Exception], ...]
) = Exception,
time_source: Callable[[], float] | None = None,
registry: Registry | None = None,
) -> Callable[[F], F]
Create a circuit breaker decorator.
Creates a SyncCircuitBreaker for synchronous functions and an AsyncCircuitBreaker for asynchronous functions to avoid locking issues.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
failure_threshold
|
int
|
Number of failures before opening circuit. |
5
|
recovery_timeout
|
float
|
Seconds to wait before attempting recovery. |
DEFAULT_CIRCUIT_BREAKER_RECOVERY_TIMEOUT
|
expected_exception
|
type[Exception] | tuple[type[Exception], ...]
|
Exception type(s) that trigger the breaker. Can be a single exception type or a tuple of exception types. |
Exception
|
time_source
|
Callable[[], float] | None
|
Optional callable that returns current time (for testing). |
None
|
registry
|
Registry | None
|
Optional registry to register the breaker with (for DI). |
None
|
Returns:
| Type | Description |
|---|---|
Callable[[F], F]
|
Circuit breaker decorator. |
Examples:
>>> @circuit_breaker(failure_threshold=3, recovery_timeout=30)
... def unreliable_service():
... return external_api_call()
>>> @circuit_breaker(expected_exception=(ValueError, TypeError))
... async def async_unreliable_service():
... return await async_api_call()
Source code in provide/foundation/resilience/decorators.py
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 | |
clear_hub
¶
Clear the global hub instance.
This is primarily used for testing to reset Foundation state between test runs.
Source code in provide/foundation/hub/manager.py
error_boundary
¶
error_boundary(
*catch: type[Exception],
on_error: Callable[[Exception], Any] | None = None,
log_errors: bool = True,
reraise: bool = True,
context: dict[str, Any] | None = None,
fallback: Any = None
) -> Generator[None, None, None]
Context manager for structured error handling with logging.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*catch
|
type[Exception]
|
Exception types to catch (defaults to Exception if empty). |
()
|
on_error
|
Callable[[Exception], Any] | None
|
Optional callback function when error is caught. |
None
|
log_errors
|
bool
|
Whether to log caught errors. |
True
|
reraise
|
bool
|
Whether to re-raise after handling. |
True
|
context
|
dict[str, Any] | None
|
Additional context for error logging. |
None
|
fallback
|
Any
|
Value to return if error is suppressed (when reraise=False). |
None
|
Yields:
| Type | Description |
|---|---|
None
|
None |
Examples:
>>> # Suppress and log specific errors
>>> with error_boundary(KeyError, reraise=False, fallback=None):
... value = data["missing_key"]
Source code in provide/foundation/errors/handlers.py
get_component_registry
¶
get_hub
¶
Get the global shared hub instance (singleton pattern).
This function acts as the Composition Root for the global singleton instance. It is maintained for backward compatibility and convenience.
Note: For building testable and maintainable applications, the recommended
approach is to use a Container or Hub instance created at your application's
entry point for explicit dependency management. This global accessor should be
avoided in application code.
Thread-safe: Uses double-checked locking pattern for efficient lazy initialization.
Auto-Initialization Behavior: This function automatically initializes the Foundation system on first access. The initialization is: - Idempotent: Safe to call multiple times - Thread-safe: Uses lock manager for coordination - Lazy: Only happens on first access
Returns:
| Type | Description |
|---|---|
Hub
|
Global Hub instance (created and initialized if needed) |
Example
hub = get_hub() hub.register_command("my_command", my_function)
Note
For isolated Hub instances (testing, advanced use cases), use:
hub = Hub(use_shared_registries=False)
Source code in provide/foundation/hub/manager.py
get_logger
¶
Get a logger instance through Hub with circular import protection.
This function provides access to the global logger instance. It is preserved for backward compatibility but should be avoided in new application code in favor of explicit Dependency Injection.
Circular Import Protection
Uses thread-local state to detect recursive initialization and falls back to basic structlog when circular dependencies are detected.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str | None
|
Logger name (e.g., name from a module) |
None
|
Returns:
| Type | Description |
|---|---|
Any
|
Configured structlog logger instance |
Note
For building testable and maintainable applications, the recommended
approach is to inject a logger instance via a Container. See the
Dependency Injection guide for more information.
Source code in provide/foundation/logger/factories.py
perr
¶
Output message to stderr.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
Any
|
Content to output (any type - will be stringified or JSON-encoded) |
required |
**kwargs
|
Any
|
Optional formatting arguments: color: Color name (red, green, yellow, blue, cyan, magenta, white) bold: Bold text dim: Dim text nl/newline: Add newline (default: True) json_key: Key for JSON output mode prefix: Optional prefix string ctx: Override context |
{}
|
Examples:
perr("Error occurred") perr("Warning", color="yellow") perr({"error": details}, json_key="error")
Source code in provide/foundation/console/output.py
pin
¶
Input from stdin with optional prompt.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prompt
|
str
|
Prompt to display before input |
''
|
**kwargs
|
Any
|
Optional formatting arguments: type: Type to convert input to (int, float, bool, etc.) default: Default value if no input provided password: Hide input for passwords (default: False) confirmation_prompt: Ask for confirmation (for passwords) hide_input: Hide the input (same as password) show_default: Show default value in prompt value_proc: Callable to process the value json_key: Key for JSON output mode ctx: Override context color: Color for prompt (red, green, yellow, blue, cyan, magenta, white) bold: Bold prompt text |
{}
|
Returns:
| Type | Description |
|---|---|
str | Any
|
User input as string or converted type |
Examples:
name = pin("Enter name: ") age = pin("Age: ", type=int, default=0) password = pin("Password: ", password=True)
In JSON mode, returns structured input data.
Source code in provide/foundation/console/input.py
pout
¶
Output message to stdout.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
Any
|
Content to output (any type - will be stringified or JSON-encoded) |
required |
**kwargs
|
Any
|
Optional formatting arguments: color: Color name (red, green, yellow, blue, cyan, magenta, white) bold: Bold text dim: Dim text nl/newline: Add newline (default: True) json_key: Key for JSON output mode prefix: Optional prefix string ctx: Override context |
{}
|
Examples:
pout("Hello world") pout({"data": "value"}) # Auto-JSON if dict/list pout("Success", color="green", bold=True) pout(results, json_key="results")
Source code in provide/foundation/console/output.py
resilient
¶
resilient(
func: None = None,
*,
fallback: Any = None,
log_errors: bool = True,
context_provider: (
Callable[[], dict[str, Any]] | None
) = None,
context: dict[str, Any] | None = None,
error_mapper: (
Callable[[Exception], Exception] | None
) = None,
suppress: tuple[type[Exception], ...] | None = None,
reraise: bool = True
) -> Callable[[F], F]
resilient(
func: F | None = None,
*,
fallback: Any = None,
log_errors: bool = True,
context_provider: (
Callable[[], dict[str, Any]] | None
) = None,
context: dict[str, Any] | None = None,
error_mapper: (
Callable[[Exception], Exception] | None
) = None,
suppress: tuple[type[Exception], ...] | None = None,
reraise: bool = True
) -> Callable[[F], F] | F
Decorator for automatic error handling with logging.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fallback
|
Any
|
Value to return when an error occurs. |
None
|
log_errors
|
bool
|
Whether to log errors. |
True
|
context_provider
|
Callable[[], dict[str, Any]] | None
|
Function that provides additional logging context. |
None
|
context
|
dict[str, Any] | None
|
Static context dict to include in logs (alternative to context_provider). |
None
|
error_mapper
|
Callable[[Exception], Exception] | None
|
Function to transform exceptions before re-raising. |
None
|
suppress
|
tuple[type[Exception], ...] | None
|
Tuple of exception types to suppress (return fallback instead). |
None
|
reraise
|
bool
|
Whether to re-raise exceptions after logging (default: True). |
True
|
Returns:
| Type | Description |
|---|---|
Callable[[F], F] | F
|
Decorated function. |
Note
Preserving Context in error_mapper: When using error_mapper with FoundationError exceptions, the original exception's context dictionary is not automatically transferred to the mapped exception. To preserve rich context, manually copy it:
from provide.foundation.errors import FoundationError @resilient( ... error_mapper=lambda e: ( ... ValidationError( ... str(e), ... context=e.context if isinstance(e, FoundationError) else {} ... ) if isinstance(e, FoundationError) ... else DomainError(str(e)) ... ) ... ) ... def process_data(data): ... # Low-level FoundationError will be mapped to ValidationError ... # with context preserved ... pass
Examples:
>>> @resilient(fallback=None, suppress=(KeyError,))
... def get_value(data, key):
... return data[key]
>>> @resilient(
... context_provider=lambda: {"request_id": get_request_id()}
... )
... def process_request():
... # errors will be logged with request_id
... pass
>>> @resilient(
... reraise=False,
... context={"component": "orchestrator", "method": "run"}
... )
... def run():
... # errors will be logged but not re-raised
... pass
Source code in provide/foundation/errors/decorators.py
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 | |
show_event_matrix
¶
Display the active event set configuration to the console. Shows all registered event sets and their field mappings.
Source code in provide/foundation/eventsets/display.py
shutdown_foundation
async
¶
Gracefully shutdown all Foundation subsystems.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
timeout_millis
|
int
|
Timeout for shutdown (currently unused) |
5000
|
Source code in provide/foundation/setup/__init__.py
timed_block
¶
timed_block(
logger_instance: FoundationLogger,
event_name: str,
layer_keys: dict[str, Any] | None = None,
initial_kvs: dict[str, Any] | None = None,
**extra_kvs: Any
) -> Generator[dict[str, Any], None, None]
Context manager that logs the duration of a code block.
Logs at DEBUG when entering, INFO on success, ERROR on exception.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logger_instance
|
FoundationLogger
|
Logger to use for output |
required |
event_name
|
str
|
Name of the operation being timed |
required |
layer_keys
|
dict[str, Any] | None
|
Semantic layer keys (e.g., llm-specific keys) |
None
|
initial_kvs
|
dict[str, Any] | None
|
Initial key-value pairs to include in logs |
None
|
**extra_kvs
|
Any
|
Additional key-value pairs |
{}
|
Yields:
| Type | Description |
|---|---|
dict[str, Any]
|
A mutable dict that can be updated with additional context |
Example
with timed_block(logger, "database_query") as ctx: ctx["query"] = "SELECT * FROM users" result = db.query("SELECT * FROM users") ctx["rows"] = len(result)