BL / scripts /run_eval.py
youssefboutaleb's picture
Implement OCR pipeline enhancements: Pydantic schemas, validation gate, retry, and evaluation harness (excluding images)
497c3ef
Raw History Blame Contribute Delete
1.94 kB
"""Run the structural OCR eval harness over a directory of saved outputs.
Each input is a saved provider response (a ``*.json`` file containing a
``document_annotation``), as produced by ``main.py``. Usage::
python scripts/run_eval.py path/to/outputs
python scripts/run_eval.py path/to/outputs --json report.json
"""
from __future__ import annotations
import argparse
import json
from pathlib import Path
from bl_ocr.eval.harness import evaluate_directory
PROJECT_ROOT = Path(__file__).resolve().parents[1]
DEFAULT_SCHEMA = PROJECT_ROOT / "schema.json"
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("outputs_dir", help="Directory of saved OCR output JSON files.")
parser.add_argument("--schema", default=str(DEFAULT_SCHEMA), help="Path to schema.json.")
parser.add_argument("--json", dest="json_out", help="Optional path to write the full JSON report.")
args = parser.parse_args(argv)
summary = evaluate_directory(Path(args.outputs_dir), Path(args.schema))
data = summary.as_dict()
if args.json_out:
Path(args.json_out).write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
rates = data["rates"]
print(f"files evaluated: {data['total']}")
print(f" parse_pass: {data['parse_pass']}/{data['total']} ({rates['parse_pass']:.0%})")
print(f" schema_pass: {data['schema_pass']}/{data['total']} ({rates['schema_pass']:.0%})")
print(f" schema errors: {data['schema_error_total']}")
print(f" row_count_pass: {data['row_count_pass']}/{data['total']} ({rates['row_count_pass']:.0%})")
print(f" arithmetic_pass: {data['arithmetic_pass']}/{data['total']} ({rates['arithmetic_pass']:.0%})")
print(f" critical: {data['critical']}/{data['total']} ({rates['critical']:.0%})")
return 0
if __name__ == "__main__":
raise SystemExit(main())