from __future__ import annotations import json from typing import Any, Dict from .types import BuildReport def format_report(report: BuildReport, db_selfcheck: Dict[str, Any], show_per_person: bool = True) -> str: lines = [] lines.append("==== build report ====") lines.append(f"total_person_dirs: {report.total_person_dirs}") lines.append(f"enrolled_persons: {report.enrolled_persons}") lines.append(f"total_images: {report.total_images}") lines.append(f"processed_images: {report.processed_images}") lines.append(f"ok_images: {report.ok_images}") lines.append(f"failed_images: {report.failed_images}") lines.append("\n-- failure reasons --") if report.failure_reasons: for k in sorted(report.failure_reasons.keys()): lines.append(f"{k}: {report.failure_reasons[k]}") else: lines.append("(none)") if show_per_person: lines.append("\n-- per person used samples --") for name in sorted(report.per_person_used.keys()): lines.append(f"{name}: {report.per_person_used[name]}") if report.skipped_persons: lines.append("\n-- persons skipped (no valid embeddings) --") for name in sorted(set(report.skipped_persons)): fails = report.per_person_failed.get(name, []) lines.append(f"{name}: failed_images={len(fails)}") if fails: reason_cnt: Dict[str, int] = {} for _path, r, _detail in fails: reason_cnt[str(r)] = reason_cnt.get(str(r), 0) + 1 lines.append(" reasons: " + ", ".join([f"{k}={reason_cnt[k]}" for k in sorted(reason_cnt.keys())])) for path, r, detail in fails[:3]: lines.append(f" sample: {r} {path} | {detail}") lines.append("\n-- db selfcheck --") lines.append(json.dumps(db_selfcheck, ensure_ascii=False, indent=2)) return "\n".join(lines)