← Files NGS Analysis WorkbenchARCHIVED FILE

mcp/ngs_workbench_execution_monitoring/registry.py

2.01 KB · Sep 30, 2026 · 23:20 UTC

↓ Download file

"""Select a replaceable execution evidence adapter by execution binding."""

from __future__ import annotations

from collections.abc import Iterable
from dataclasses import dataclass
from pathlib import Path
from types import MappingProxyType
from typing import Mapping, Protocol, runtime_checkable

from .base import ExecutionObserver
from .models import ExecutionObservation, empty_observation
from .nextflow_trace import NextflowTraceObserver
from .snakemake_log import SnakemakeLogObserver


@runtime_checkable
class FileExecutionObserver(Protocol):
    """The file-input capability; other adapters may still implement only observe()."""

    evidence_kind: str
    file_patterns: tuple[str, ...]

    def observe_lines(
        self, lines: Iterable[str], *, evidence_path: str, workflow_status: str
    ) -> ExecutionObservation: ...


@dataclass(frozen=True)
class ObserverRegistry:
    """Immutable binding-to-adapter registry suitable for dependency injection."""

    observers: Mapping[str, ExecutionObserver]

    def file_observer(self, binding: str) -> FileExecutionObserver:
        observer = self.observers.get(binding)
        if not isinstance(observer, FileExecutionObserver):
            raise ValueError(f"no file execution evidence adapter for binding: {binding}")
        return observer

    def observe(
        self,
        run_dir: Path,
        binding: str,
        workflow_status: str,
    ) -> ExecutionObservation:
        observer = self.observers.get(binding)
        if observer is None:
            return empty_observation(
                engine=binding,
                evidence_kind="unsupported",
                evidence_path=None,
                reason=f"no execution evidence adapter for binding: {binding}",
            )
        return observer.observe(run_dir, workflow_status)


DEFAULT_OBSERVER_REGISTRY = ObserverRegistry(
    MappingProxyType(
        {
            NextflowTraceObserver.binding: NextflowTraceObserver(),
            SnakemakeLogObserver.binding: SnakemakeLogObserver(),
        }
    )
)

SHA-256: 55c75b2adda56b335ff114ccc33d14f9fd0f59e2faeae8805bbeb5cae6c279c2