Spaces:
Running
Running
| from __future__ import annotations | |
| from typing import Any | |
| from app.services.trust_scorer import build_risk_flags, score_trust | |
| LIMITATIONS = [ | |
| "BitCheck provides risk signals and does not make absolute claims that an image is fake or real.", | |
| "Missing metadata or missing C2PA provenance is not proof of AI generation.", | |
| "Classifier output is probabilistic and may produce false positives or false negatives.", | |
| "Visible watermark detection depends on OCR quality and available templates.", | |
| "Forensic indicators are lightweight risk signals, not definitive proof of manipulation.", | |
| "Grad-CAM shows model-influential regions, not confirmed manipulated regions.", | |
| "No official SynthID detector/API is integrated.", | |
| ] | |
| def build_report( | |
| verification_id: str, | |
| input_info: dict[str, Any], | |
| filename_analysis: dict[str, Any], | |
| metadata: dict[str, Any], | |
| provenance: dict[str, Any], | |
| visible_watermark_ocr: dict[str, Any], | |
| visible_watermark_template: dict[str, Any], | |
| classifier: dict[str, Any], | |
| forensics: dict[str, Any], | |
| explainability: dict[str, Any], | |
| processing_time_ms: float, | |
| user_email: str, | |
| ) -> dict[str, Any]: | |
| trust = score_trust(filename_analysis, metadata, provenance, visible_watermark_ocr, visible_watermark_template, classifier, forensics) | |
| flags = build_risk_flags(filename_analysis, metadata, provenance, visible_watermark_ocr, visible_watermark_template, classifier, forensics, explainability) | |
| report = { | |
| "verification_id": verification_id, | |
| "service": "BitCheck", | |
| "file_type": "image", | |
| "status": "completed", | |
| "processing_time_ms": round(processing_time_ms, 2), | |
| "user_email": user_email, | |
| "input": input_info, | |
| "filename_analysis": filename_analysis, | |
| "metadata": metadata, | |
| "provenance": provenance, | |
| "visible_watermark_ocr": visible_watermark_ocr, | |
| "visible_watermark_template": visible_watermark_template, | |
| "synthid": { | |
| "checked": False, | |
| "status": "not_available", | |
| "reason": "No official SynthID detector/API integrated.", | |
| }, | |
| "classifier": classifier, | |
| "forensics": forensics, | |
| "explainability": explainability, | |
| "trust": trust, | |
| "risk_flags": flags, | |
| "recommended_actions": _recommended_actions(trust, flags), | |
| "limitations": LIMITATIONS, | |
| "warnings": _warnings(classifier, explainability, provenance), | |
| } | |
| return report | |
| def _recommended_actions(trust: dict[str, Any], flags: list[str]) -> list[str]: | |
| if trust.get("decision") == "approve": | |
| return ["Proceed if the surrounding business context is acceptable."] | |
| actions = ["Send the image for manual review before relying on it."] | |
| if any("watermark" in flag.lower() for flag in flags): | |
| actions.append("Inspect visible branding or watermark evidence in the image.") | |
| if any("metadata" in flag.lower() for flag in flags): | |
| actions.append("Review extracted metadata and source context.") | |
| return actions | |
| def _warnings(classifier: dict[str, Any], explainability: dict[str, Any], provenance: dict[str, Any]) -> list[str]: | |
| warnings: list[str] = [] | |
| for section in (classifier, explainability, provenance): | |
| warning = section.get("warning") | |
| if warning: | |
| warnings.append(str(warning)) | |
| return warnings | |