Spaces:
Sleeping
Sleeping
Claude
refactor(architecture): inversion de dépendance reports_v2 + corrections audit
4255304 unverified | """``picarones-rewrite run`` — exécute un benchmark depuis un YAML. | |
| Wrapper Click mince autour du :class:`RunOrchestrator` (couche | |
| ``app/services/``) — toute la logique métier vit dans le service, | |
| ce module ne fait que du parsing CLI, l'injection du renderer HTML | |
| (:class:`HtmlReportRenderer` de la couche ``reports_v2/``) et le | |
| formatage de sortie. | |
| Usage | |
| ----- | |
| :: | |
| python -m picarones.interfaces.cli run --spec ./run.yaml | |
| Codes de sortie : 0 succès, 1 erreur métier (typée | |
| ``PicaronesError``), 2 erreur Click (option mal formée). | |
| """ | |
| from __future__ import annotations | |
| import sys | |
| from pathlib import Path | |
| import click | |
| from picarones.app.results import RunResult | |
| from picarones.app.schemas import RunSpecLoadError, load_run_spec_from_yaml | |
| from picarones.app.services.corpus_service import CorpusImportError | |
| from picarones.app.services.run_orchestrator import RunOrchestrator | |
| from picarones.reports_v2.html import HtmlReportRenderer | |
| def _render_html_report( | |
| result: RunResult, output_path: Path, lang: str, | |
| ) -> Path: | |
| """Adapte :class:`HtmlReportRenderer` au protocole ``ReportRenderer`` | |
| attendu par :meth:`RunOrchestrator.execute`.""" | |
| renderer = HtmlReportRenderer(lang=lang) | |
| output_path.write_text(renderer.render(result), encoding="utf-8") | |
| return output_path | |
| def run_command(spec_path: Path, no_report: bool) -> None: | |
| """Exécute un benchmark complet depuis une spec YAML.""" | |
| # 1. Parsing de la spec. | |
| try: | |
| spec = load_run_spec_from_yaml(spec_path.read_text(encoding="utf-8")) | |
| except RunSpecLoadError as exc: | |
| click.echo(f"erreur : spec invalide : {exc}", err=True) | |
| sys.exit(1) | |
| # 2. Délégation au service d'orchestration avec injection du | |
| # renderer HTML (sauf si --no-report). | |
| orchestrator = RunOrchestrator(output_dir=Path(spec.output_dir)) | |
| renderer = None if no_report else _render_html_report | |
| try: | |
| result = orchestrator.execute(spec, report_renderer=renderer) | |
| except CorpusImportError as exc: | |
| click.echo(f"erreur : import corpus : {exc}", err=True) | |
| sys.exit(1) | |
| except RunSpecLoadError as exc: | |
| click.echo(f"erreur : résolution pipeline : {exc}", err=True) | |
| sys.exit(1) | |
| # 3. Formatage de la sortie utilisateur. | |
| click.echo( | |
| f"Corpus chargé : {result.run_result.manifest.corpus_name} " | |
| f"({result.run_result.n_documents} docs, " | |
| f"{result.extracted_corpus_dir})", | |
| ) | |
| click.echo( | |
| f"Lancement du run : " | |
| f"{len(result.run_result.manifest.pipeline_names)} pipeline(s) × " | |
| f"{len(result.run_result.manifest.view_specs)} vue(s) × " | |
| f"{result.run_result.n_documents} doc(s)…", | |
| ) | |
| persist_dir = next(iter(result.persisted_files.values())).parent | |
| click.echo(f"Run persisté dans : {persist_dir}") | |
| for kind, path in result.persisted_files.items(): | |
| click.echo(f" {kind}: {path}") | |
| if result.report_path is not None: | |
| click.echo(f"Rapport : {result.report_path}") | |
| click.echo("OK") | |
| __all__ = ["run_command"] | |