#!/usr/bin/env python3 from __future__ import annotations import argparse import json import sys from pathlib import Path REPO_ROOT = Path(__file__).resolve().parents[1] API_ROOT = REPO_ROOT / "apps" / "api" sys.path.insert(0, str(API_ROOT)) from app.services.pii_masking_eval import evaluate_fixture # noqa: E402 def build_parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser(description="Evaluate local PII masking fixtures.") parser.add_argument( "--fixtures", default=str(REPO_ROOT / "data" / "privacy" / "pii-masking-ko-fixtures.json"), ) parser.add_argument("--json", action="store_true") parser.add_argument( "--include-evidence-text", action="store_true", help="Include masked text and remaining forbidden strings for local synthetic debugging only.", ) return parser def main() -> int: parser = build_parser() args = parser.parse_args() report = evaluate_fixture(Path(args.fixtures), include_evidence_text=args.include_evidence_text) if args.json: print(json.dumps(report, ensure_ascii=False, indent=2, sort_keys=True)) else: status = "PASS" if report["passed"] else "FAIL" print( f"{status}: {report['cases_passed']}/{report['cases_total']} cases, " f"entity_recall={report['expected_entity_recall']}, " f"forbidden_removed={report['forbidden_substring_removal']}, " f"unexpected_entity_violations={report['unexpected_entity_violations']}" ) for result in report["results"]: if not result["passed"]: print(json.dumps(result, ensure_ascii=False, sort_keys=True)) return 0 if report["passed"] else 1 if __name__ == "__main__": raise SystemExit(main())