54 lines
1.4 KiB
Python
54 lines
1.4 KiB
Python
"""# Summary
|
|
|
|
Example pipeline family — port contracts (stage interfaces + root interface).
|
|
|
|
Ports are declared as a DI tree: the root's annotated slots *are* the dependency
|
|
decisions. The concrete subclass in ``impl.py`` pins the stage types.
|
|
"""
|
|
from abc import ABC, abstractmethod
|
|
from typing import Any
|
|
|
|
from pipelines.shared.ports import FinalizePort
|
|
|
|
|
|
class IngestPort(ABC):
|
|
"""Obtain the raw input as text/bytes."""
|
|
|
|
@abstractmethod
|
|
def materialize(self, source: Any) -> str:
|
|
"""Return the raw input materialized as text."""
|
|
|
|
|
|
class ReadPort(ABC):
|
|
"""Parse materialized input into records."""
|
|
|
|
@abstractmethod
|
|
def read(self, content: str) -> list[dict[str, Any]]:
|
|
"""Return parsed records."""
|
|
|
|
|
|
class NormalizePort(ABC):
|
|
"""Normalize raw records into the target shape."""
|
|
|
|
@abstractmethod
|
|
def build(self, records: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
|
"""Return normalized records."""
|
|
|
|
|
|
class ExamplePipelinePort(ABC):
|
|
"""Root of the example family.
|
|
|
|
Notes:
|
|
The slot annotations below are contracts. A concrete subclass re-annotates
|
|
them with stage implementations; the DI container instantiates the tree.
|
|
"""
|
|
|
|
ingest: IngestPort
|
|
reader: ReadPort
|
|
normalize: NormalizePort
|
|
finalize: FinalizePort
|
|
|
|
@abstractmethod
|
|
async def run(self, source: Any) -> list[dict[str, Any]]:
|
|
"""Run the full stage chain and return the normalized records."""
|