pltobing's picture
feat(readiness): add W1-T semantic timing proxy
c9761c3
Raw History Blame Contribute Delete
3.54 kB
# License: Apache-2.0 License
# Created by: Patrick Lumbantobing, VertoX-AI
# Copyright (c) 2026 VertoX-AI. All rights reserved.
#
# This work is licensed under the Apache-2.0 License.
# To view a copy of this license, visit
# https://www.apache.org/licenses/LICENSE-2.0
"""Compose W1-T providers and delegate offline timing to the reusable service."""
from __future__ import annotations
import argparse
import json
from pathlib import Path
from speech_text_data_aligners.application.readiness import run_readiness
from speech_text_data_aligners.backends.registry import (
BackendRegistry,
default_backend_registry,
)
from speech_text_data_aligners.core.errors import ConfigurationError
from speech_text_data_aligners.runtime.alignment_evidence import EvidenceCandidate
def configure_parser(parser: argparse.ArgumentParser) -> None:
"""Register source paths and an explicit evidence/provider catalog on ``parser``.
Side Effects:
Adds W1-T arguments and the command handler without loading a backend.
"""
parser.add_argument("metadata_csv", type=Path)
parser.add_argument("boundaries_jsonl", type=Path)
parser.add_argument("audio_dir", type=Path)
parser.add_argument("output_dir", type=Path)
parser.add_argument("--catalog", type=Path, required=True)
parser.set_defaults(handler=run)
def run(args: argparse.Namespace, *, registry: BackendRegistry | None = None) -> int:
"""Build catalog-selected providers and delegate W1-T to the application service.
Parameters
----------
args: Parsed W1-T arguments.
registry: Optional injectable lazy provider registry.
Returns
-------
Zero for the timing coverage gate, three for a packaged BLOCKED timing result.
Raises
------
ConfigurationError: If the catalog is malformed or unavailable.
SpeechTextAlignerError: If provider construction or source validation fails.
Side Effects:
The service writes sidecar/evidence and runs only missing backend pairs.
"""
selected = registry or default_backend_registry()
try:
catalog = json.loads(args.catalog.read_text(encoding="utf-8"))
specs = catalog["backends"]
candidates = {
(row["audio_id"], row["backend"]): tuple(
EvidenceCandidate(Path(c["path"]), c["sha256"])
for c in row["candidates"]
)
for row in catalog.get("evidence", [])
}
identities = {name: spec["identity"] for name, spec in specs.items()}
unavailable = {
name: spec.get("unavailable_reason", "runtime was not supplied")
for name, spec in specs.items()
}
configs = {name: spec.get("config") for name, spec in specs.items()}
except (
OSError,
UnicodeError,
ValueError,
KeyError,
TypeError,
AttributeError,
) as error:
raise ConfigurationError(f"invalid W1-T catalog: {error}") from error
backends = {
name: selected.create(name, config=config) if config is not None else None
for name, config in configs.items()
}
receipt = run_readiness(
metadata_csv=args.metadata_csv,
boundaries_jsonl=args.boundaries_jsonl,
audio_dir=args.audio_dir,
output_dir=args.output_dir,
backends=backends,
identities=identities,
candidates=candidates,
unavailable_reasons=unavailable,
)
return 0 if receipt["status"] == "COMPLETE" else 3