API: Interfaces Package
The interfaces package defines ports implemented by extractors, processors, cleaners, analyzers, visualizers, buffers, and orchestration adapters.
Stage Capabilities
StageCapabilities
dataclass
Stable execution contract declared by every pipeline stage.
The pipeline runtime uses these flags to build an execution plan without relying on implementation details such as ad-hoc attributes. Concrete stages should be conservative: declare streaming only when they can produce output progressively without requiring the full upstream sequence.
batch
classmethod
batch(
*,
stateful: bool = True,
preserves_order: bool = True,
supports_frame_parallelism: bool = False,
realtime_safe: bool = False,
) -> StageCapabilities
Return capabilities for stages that require a complete input sequence.
streaming
classmethod
streaming(
*,
stateful: bool = False,
preserves_order: bool = True,
supports_frame_parallelism: bool = False,
realtime_safe: bool = True,
) -> StageCapabilities
Return capabilities for stages that can process input progressively.
as_dict
as_dict() -> dict[str, bool]
Return a JSON-safe representation used by execution plans and UI.
Batch Component Contracts
IFrameExtractor
Bases: ABC
Batch source contract for frame-producing plugins.
A frame extractor is the pipeline entry point. Batch extractors return a
closed FrameBuffer; streaming extractors should additionally implement
IStreamingFrameExtractor so the planner can avoid materializing source
frames.
Extension guidance
Implementations should keep constructor configuration explicit and should
encode frame order through Frame.index when available.
__init__
__init__(config: dict[str, Any] | None = None)
Store optional extractor configuration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
dict[str, Any] | None
|
Plugin-specific configuration mapping. The core does not interpret this mapping after construction. |
None
|
extract
abstractmethod
extract() -> FrameBuffer
Extract raw frames and return them in a closed buffer.
Returns:
| Type | Description |
|---|---|
FrameBuffer
|
Buffer containing frames in source order. |
ISingleFrameProcessor
Bases: ABC
Contract for stateless or local frame transformations.
Single-frame processors are adapted into the frame-buffer pipeline by the core runtime. Use this contract when processing one frame does not require future or past frames.
__init__
__init__(config: dict[str, Any] | None = None)
Store plugin-specific processor configuration.
IFrameBufferProcessor
Bases: ABC
Buffer-level frame processing contract.
Implementations receive the whole frame sequence so both stateless per-frame operations and temporal algorithms can participate in the same frame processing pipeline.
Streaming implementations should also implement
IStreamingFrameBufferProcessor when they can publish processed frames
progressively without requiring the complete sequence first.
__init__
__init__(config: dict[str, Any] | None = None)
Store plugin-specific processor configuration.
process
abstractmethod
process(buffer: FrameBuffer) -> FrameBuffer
Return a processed frame buffer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
buffer
|
FrameBuffer
|
Input frames in pipeline order. |
required |
Returns:
| Type | Description |
|---|---|
FrameBuffer
|
Processed frames. Implementations should preserve order unless documented otherwise. |
FrameExportContext
dataclass
Runtime metadata passed to frame-buffer exporters.
Attributes:
| Name | Type | Description |
|---|---|---|
pipeline_id |
str | None
|
Optional run id. |
exporter_name |
str
|
Human-readable exporter component name. |
execution_metadata |
Mapping[str, Any]
|
Metadata supplied by the caller and propagated through the run. |
FrameExportResult
dataclass
Exporter result that preserves frames for downstream stages.
Exporters may create artifacts but must also return a frame buffer so signal extraction can continue after export.
IFrameExporter
Bases: ABC
Export final artifacts from processed frames without being a frame processor.
Exporters may write file-backed artifacts and must return a buffer that can still be consumed by signal extractors.
export
abstractmethod
export(
buffer: FrameBuffer, context: FrameExportContext
) -> FrameExportResult
Persist or build artifacts from the frame stream.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
buffer
|
FrameBuffer
|
Processed frame stream. |
required |
context
|
FrameExportContext
|
Runtime metadata for artifact naming and reproducibility. |
required |
Returns:
| Type | Description |
|---|---|
FrameExportResult
|
Forwarded frame buffer plus generated artifacts. |
ISignalExtractor
Bases: ABC
Batch contract for converting frames into signal samples.
Signal extractors consume processed frames and produce an ISignal that
analyzers can consume. Streaming implementations should also implement
IStreamingSignalExtractor and declare streaming capabilities.
__init__
__init__(config: dict[str, Any] | None = None)
Store plugin-specific extractor configuration.
extract
abstractmethod
extract(buffer: FrameBuffer) -> ISignal
Extract a signal from a frame buffer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
buffer
|
FrameBuffer
|
Processed frames in pipeline order. |
required |
Returns:
| Type | Description |
|---|---|
ISignal
|
Iterable signal samples preserving frame-time semantics when available. |
ISignalCleaner
Bases: ABC
Batch contract for transforming signal samples before analysis.
Cleaners should preserve signal semantics unless their documentation states otherwise. Typical implementations smooth, normalize, filter, or repair samples produced by a signal extractor.
__init__
__init__(config: Dict[str, Any] | None = None)
Store plugin-specific cleaner configuration.
IAnalyzer
Bases: ABC
Batch contract for turning a signal into analytical data.
An analyzer is the boundary between signal processing and visualization.
Streaming analyzers should also implement IStreamingAnalyzer to publish
progressive IData values while still returning a final result.
__init__
__init__(config: dict[str, Any] | None = None)
Store plugin-specific analyzer configuration.
IVisualizer
Bases: ABC
Batch contract for converting analytical data into visual artifacts.
Visualizers must return UI-agnostic VisualArtifact values. They should not
require Streamlit containers, OpenCV windows, notebook globals, or web
framework state unless they are explicitly adapter implementations outside
the core package.
__init__
__init__(config: dict[str, Any] | None = None)
Store plugin-specific visualizer configuration.
render
abstractmethod
render(
data: IData, context: VisualizationContext | None = None
) -> tuple[VisualArtifact, ...]
Build visual artifacts from analytical data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
IData
|
Analyzer result to render. |
required |
context
|
VisualizationContext | None
|
Optional run metadata, result index, and rendering hints. |
None
|
Returns:
| Type | Description |
|---|---|
tuple[VisualArtifact, ...]
|
Final or debug artifacts for UI and exporter adapters. |
Data Contracts
IData
Bases: ABC
Marker base class for chart-ready analytical data.
ISignal
Bases: ABC
Base contract for ordered signal samples.
Signals are analyzer input values. Batch signal extractors return this
complete collection, while streaming extractors publish ISignalSample
values progressively into a buffer.
signal
property
signal: list[ISignalSample]
Backward-compatible alias for samples.
__init__
__init__(
samples: Sequence[ISignalSample],
config: dict[str, Any] | None = None,
)
Create a signal from ordered samples.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
samples
|
Sequence[ISignalSample]
|
Signal samples in analysis order. |
required |
config
|
dict[str, Any] | None
|
Optional plugin-specific metadata retained for compatibility. |
None
|
__iter__
__iter__() -> Iterator[ISignalSample]
Iterate samples in analysis order.
__len__
__len__() -> int
Return the number of samples in the signal.
ISignalSample
Bases: ABC
Base contract for one time-indexed signal sample.
Attributes:
| Name | Type | Description |
|---|---|---|
frame_index |
Source frame index associated with the sample. |
|
timestamp_seconds |
Optional source timestamp in seconds. |
|
metadata |
Plugin-specific sample metadata. |
__init__
__init__(
frame_index: int,
timestamp_seconds: float | None = None,
metadata: dict[str, Any] | None = None,
)
Create a signal sample value.
Streaming Contracts
IBuffer
Bases: Protocol[T]
Minimal producer-side contract shared by pipeline buffers.
closed
property
closed: bool
Return True when the buffer no longer accepts new items.
put
put(item: T) -> None
Publish one item into the buffer.
close
close() -> None
Mark the stream as complete and wake consumers.
IAbortableBuffer
Bases: IBuffer[T], Protocol[T]
Buffer that can interrupt a stream immediately.
abort
abort() -> None
Cancel the stream and unblock waiting producers or consumers.
IBufferSubscription
Bases: Iterator[T], Protocol[T]
Consumer-side stream cursor that can cancel its upstream buffer.
abort
abort() -> None
Cancel the source buffer for cooperative downstream shutdown.
ISubscribableBuffer
Bases: IAbortableBuffer[T], Protocol[T]
Multi-consumer buffer with explicit fan-out configuration.
set_consumer_count
set_consumer_count(consumers: int) -> None
Declare how many consumers must observe each future item.
subscribe
subscribe(consumer_id: int) -> IBufferSubscription[T]
Return a consumer cursor for the configured stream.
IFrameBuffer
Bases: IAbortableBuffer[Frame], Iterable[Frame], Protocol
Frame stream contract required by realtime latency policies.
This intentionally lives outside IBuffer because capacity and dropping
are frame-queue concerns, not universal buffer responsibilities.
capacity
property
capacity: int
Maximum number of frame items retained by the public queue.
try_put
try_put(frame: Frame) -> bool
Publish without blocking. Return False when the frame is rejected.
drop_oldest
drop_oldest() -> Frame | None
Drop and return the oldest queued frame item, when available.
fill_ratio
fill_ratio() -> float
Return public queue occupancy in the [0, 1] range.
IStreamingFrameExtractor
Bases: IFrameExtractor
Frame extractor that can publish frames into a bounded output stream.
Implementations must close output_buffer on normal completion and should
cooperate with the supplied latency policy instead of writing directly with
unbounded buffering.
extract_into
abstractmethod
extract_into(
output_buffer: IFrameBuffer,
latency_policy: FrameLatencyPolicy,
) -> None
Read frames and publish accepted frames into output_buffer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
output_buffer
|
IFrameBuffer
|
Bounded frame queue owned by the runtime. |
required |
latency_policy
|
FrameLatencyPolicy
|
Per-run policy deciding whether each frame is accepted or dropped. |
required |
IStreamingFrameBufferProcessor
Bases: IFrameBufferProcessor
Frame processor that can transform a stream without materializing it.
Implementations should publish outputs progressively and preserve ordering unless their plugin documentation explicitly states otherwise.
process_into
abstractmethod
process_into(
input_buffer: Iterable[Frame],
output_buffer: IBuffer[Frame],
*,
processor_index: int,
intermediate_store: IntermediateFrameArtifactStore
| None,
) -> None
Consume input_buffer and publish processed frames.
Implementations must close output_buffer when finished and should
abort cooperatively when downstream consumers abort.
IStreamingFrameExporter
Bases: IFrameExporter
Frame exporter that writes artifacts while forwarding the frame stream.
This contract lets exporters produce file-backed artifacts without forcing the frame stream to be fully materialized before signal extraction.
export_into
abstractmethod
export_into(
frames: Iterable[Frame],
output_buffer: IBuffer[Frame],
context: FrameExportContext,
) -> tuple[VisualArtifact, ...]
Export frames and forward each original frame to output_buffer.
IStreamingSignalExtractor
Bases: ISignalExtractor
Signal extractor that emits samples progressively from frame input.
extract_into
abstractmethod
extract_into(
frames: IFrameBuffer,
output_buffer: IBuffer[ISignalSample],
) -> None
Consume frames and publish signal samples to output_buffer.
IStreamingSignalCleaner
Bases: ISignalCleaner
Signal cleaner that can transform samples progressively.
clean_into
abstractmethod
clean_into(
input_signal: Iterable[ISignalSample],
output_buffer: IBuffer[ISignalSample],
) -> None
Consume signal samples and publish cleaned samples to output_buffer.
IStreamingAnalyzer
Bases: IAnalyzer
Analyzer that can publish progressive data and still return a final result.
Progressive values feed streaming visualizers during execution. The returned
final IData remains the authoritative analyzer result included in
PipelineOutputs.
analyze_into
abstractmethod
analyze_into(
signal: Iterable[ISignalSample],
output_buffer: IBuffer[IData],
) -> IData
Consume signal samples, publish progressive data, and return final data.
IStreamingVisualizer
Bases: IVisualizer
Visualizer that can consume progressive analyzer data.
Streaming visualizers should avoid toolkit-specific blocking calls in core execution paths. For live UI updates, publish through adapter-safe contracts such as realtime sinks or return final artifacts after the stream closes.
render_stream
abstractmethod
render_stream(
data: Iterable[IData],
context: VisualizationContext | None = None,
) -> tuple[VisualArtifact, ...]
Render from a data stream subscription.
Orchestration Ports
IPipelineFactory
Bases: ABC
Factory port that creates executable Pipeline instances.
Applications can replace this port to inject custom execution policy, event buses, metadata propagation, or pipeline subclasses without changing the orchestrator.
create
abstractmethod
create(
context: PipelineContext,
event_bus: IEventBus | None = None,
pipeline_id: str | None = None,
execution_metadata: Mapping[str, Any] | None = None,
) -> Pipeline
Create a pipeline facade for a validated context.
Returns:
| Type | Description |
|---|---|
Pipeline
|
Executable pipeline instance ready for a runner. |
IPipelineRunner
Bases: ABC
Executes Pipeline instances synchronously or asynchronously.
Implementations own execution concerns such as active-run tracking, retry, lifecycle events, and monitor registration/completion.
run
abstractmethod
run(
pipeline_id: str, pipeline: Pipeline
) -> PipelineOutputs
Execute a pipeline synchronously and return completed outputs.
submit
abstractmethod
submit(
pipeline_id: str, pipeline: Pipeline
) -> Future[PipelineOutputs]
Submit a pipeline for asynchronous execution.
cancel
abstractmethod
cancel(pipeline_id: str) -> bool
Cancel queued work for a run id when supported.
active_ids
abstractmethod
active_ids() -> list[str]
Return a snapshot of active run ids.
snapshot
abstractmethod
snapshot(pipeline_id: str) -> PipelineRunSnapshot | None
Return the latest snapshot for a run id, if known.
snapshots
abstractmethod
snapshots() -> list[PipelineRunSnapshot]
Return latest snapshots for all tracked runs.
shutdown
abstractmethod
shutdown(wait: bool = True) -> None
Release runner resources and optionally wait for active work.
IPipelineMonitor
Bases: ABC
Port for observable pipeline execution state.
Monitors are read by UIs, APIs, and operators. Implementations should keep state transitions deterministic and should not expose mutable internal storage through snapshots.
register
abstractmethod
register(pipeline_id: str) -> None
Record a newly queued pipeline run.
mark_running
abstractmethod
mark_running(pipeline_id: str, attempt: int) -> None
Mark a run attempt as actively executing.
complete
abstractmethod
complete(pipeline_id: str) -> None
Mark a run as successfully completed.
fail
abstractmethod
fail(
pipeline_id: str, error: Exception | str, attempt: int
) -> None
Mark a run as failed with an observable error message.
terminate
abstractmethod
terminate(pipeline_id: str) -> None
Mark a run as cancelled or terminated.
active_ids
abstractmethod
active_ids() -> list[str]
Return a snapshot of queued or running pipeline ids.
snapshot
abstractmethod
snapshot(pipeline_id: str) -> PipelineRunSnapshot | None
Return the latest snapshot for a run id, if known.
snapshots
abstractmethod
snapshots() -> list[PipelineRunSnapshot]
Return latest snapshots for all tracked runs.
IPipelineOutputStore
Bases: ABC
Persistence port for completed pipeline outputs.
Stores may be in-memory, filesystem-backed, database-backed, or service
backed. Implementations should treat PipelineOutputs as immutable values.
save
abstractmethod
save(pipeline_id: str, outputs: PipelineOutputs) -> None
Persist outputs for a completed run id.
get
abstractmethod
get(pipeline_id: str) -> PipelineOutputs | None
Return stored outputs for a run id, if available.
delete
abstractmethod
delete(pipeline_id: str) -> None
Remove stored outputs for a run id.
IPipelineValidator
Bases: ABC
Validation port for executable pipeline instances.
Validators are application-level checks. They should not mutate the pipeline and should raise typed configuration or validation errors when a run cannot be accepted.
validate
abstractmethod
validate(pipeline: 'Pipeline') -> None
Validate a pipeline before execution.
IEventBus
Bases: ABC
Typed async-first pub/sub interface.
Two publication paths
dispatch— synchronous, for use within pipeline execution threads where no event loop is running.publish— async, for external callers operating in an asyncio context.
Per-listener error isolation: a failing handler must never prevent other handlers from receiving the same event.
subscribe
abstractmethod
subscribe(event_type: str, handler: EventHandler) -> None
Register a handler for one event type.
Use IEventBus.WILDCARD to observe every event.
unsubscribe
abstractmethod
unsubscribe(event_type: str, handler: EventHandler) -> None
Remove a previously registered handler when present.
dispatch
abstractmethod
dispatch(event: Event) -> None
Publish an event synchronously.
Implementations should isolate handler failures so one subscriber does not prevent remaining subscribers from receiving the event.
publish
abstractmethod
async
publish(event: Event) -> None
Publish an event from an async caller.
IRetryPolicy
Bases: ABC
Strategy interface that governs retry behavior for runners.
Design rationale
Extracting the retry decision into its own object follows the Open/Closed Principle: new strategies such as backoff, jitter, or circuit breakers are added by creating a new class, never by editing the runner. The runner calls only two methods:
should_retry: binary gate deciding whether to keep trying.wait_seconds: optional pause before the next attempt.
Both receive the 1-based attempt number that just failed, so policies can implement attempt-dependent logic such as exponential backoff.
should_retry
abstractmethod
should_retry(attempt: int, error: Exception) -> bool
Decide whether execution should be retried.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attempt
|
int
|
The 1-based number of the attempt that just failed. |
required |
error
|
Exception
|
The exception that caused the failure. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
wait_seconds
wait_seconds(attempt: int) -> float
Seconds to pause before the next attempt.
Override in subclasses that implement backoff strategies.
The base implementation returns 0.0 (no wait).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attempt
|
int
|
The 1-based number of the attempt that just failed. |
required |
IBranchingRule
Bases: ABC
Strategy that decides IF and HOW to create a secondary pipeline in response to a domain event.
Design rationale
The Orchestrator holds a list of IBranchingRules. When a domain event arrives on the EventBus, each rule is evaluated in order:
matches(event)— should this event trigger a secondary pipeline?build_context(event)— build the PipelineContext for the new pipeline.
This is the Strategy pattern: users define their own branching logic by subclassing IBranchingRule, without touching the Orchestrator.
Example
class TrackingLostBranch(IBranchingRule): ... def matches(self, event: Event) -> bool: ... return event.event_type == "tracking_lost" ... ... def build_context(self, event: Event) -> PipelineContext: ... return PipelineContext( ... frame_extractor=..., ... signal_extractor=..., ... analyzers=[...], ... )
matches
abstractmethod
matches(event: Event) -> bool
Return True if event should trigger a secondary pipeline.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
Event
|
The domain event published on the EventBus. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
build_context
abstractmethod
build_context(event: Event) -> PipelineContext
Build the PipelineContext for the secondary pipeline.
Called only when matches(event) returned True.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
Event
|
The same domain event that matched. |
required |
Returns:
| Type | Description |
|---|---|
PipelineContext
|
A fully configured, immutable context ready for execution by a secondary Pipeline. |