Skip to content

factflow-foundation

Shared configuration framework, path resolution, and observability primitives used by every other factflow-* package.

Virtually every backend package imports something from here. Users don’t import it directly — they consume it transitively through whatever shared service or workflow they plug into.

Three concerns, one package:

  1. Configuration — typed Pydantic-settings config with environment-aware loading, dependency-injected Config object. Explicitly no singletons; all access goes through get_config() / override_config().
  2. Path resolution — deterministic keys and paths for executions, stages, and artefacts. ExecutionPathResolver is the canonical way to derive a storage key from an execution + route + stage + message.
  3. Observability — correlation-id propagation across async contexts, structured logging helpers, message-flow tracking.

These concerns share enough utility (path and correlation both lean on UUIDs; config drives logging) that combining them into one package avoids tight coupling in downstream packages. Splitting later is cheap if needed.

Two subpackages, both re-exported via their own __init__.

Configuration (factflow_foundation.configuration)

Section titled “Configuration (factflow_foundation.configuration)”
from factflow_foundation.configuration import (
Config, # the root config object (DI-injected)
ConfigProtocol, # the protocol the Config satisfies
AppConfig, # app-level settings
DatabaseConfig,
LoggingConfig,
PathConfig,
get_config, # lazy accessor (uses override if set)
set_config, # explicit set — prod path
override_config, # test-scoped override
reset_config, # test teardown
)

No import-time side effects. Config is loaded when get_config() first runs or when set_config() is called explicitly. Tests use override_config() with a context manager.

Shared utilities (factflow_foundation.shared)

Section titled “Shared utilities (factflow_foundation.shared)”
from factflow_foundation.shared import (
# Correlation + logging
correlation_context, # async context-manager that propagates a correlation id
get_correlation_id,
set_correlation_id,
CorrelationIdFilter, # logging.Filter that injects the correlation id
configure_correlation_logging,
get_contextual_logger,
# Message-flow tracing
MessageFlow,
track_message_flow,
# Path resolution
ExecutionPathResolver, # build storage keys from execution + route + stage
PipelineStage, # enum of canonical stage names
# Storage scope
StorageContext,
)

The correlation helpers are imported by factflow-lineage and every adapter that logs. ExecutionPathResolver is the contract every storage-writing adapter uses to derive its key.

  • Runtime: pydantic, pydantic-settings, python-dotenv, pyyaml, tomli, colorlog, uuid-utils
  • Workspace: factflow-protocols
  • External services: none

Tests live at backend/packages/factflow-foundation/tests/. The fixtures for config override patterns are reusable — downstream package tests that need a config override should import the helpers from here rather than roll their own.