Download app/services/validation.py from nvikou/Sheetly: direct link, hf CLI and curl.
- Browser
- Download file 2.67 kB
-
https://huggingface.co/spaces/nvikou/Sheetly/resolve/main/app/services/validation.py
- Command line
-
hf download hf://spaces/nvikou/Sheetly/app/services/validation.py
-
curl -L -o validation.py https://huggingface.co/spaces/nvikou/Sheetly/resolve/main/app/services/validation.py
2.67 kB
| """Post-extraction consistency and duplicate checks.""" | |
| from __future__ import annotations | |
| from typing import Any | |
| from sqlalchemy.ext.asyncio import AsyncSession | |
| from app.models import Document | |
| from app.schemas import DocType | |
| from app.services.consistency import check_consistency | |
| from app.services.doctypes import ARRAY_FIELD_KEYS | |
| from app.services.duplicates import find_duplicate, register_invoice | |
| async def apply_post_extract_checks( | |
| session: AsyncSession, | |
| *, | |
| document_id: str, | |
| doc_type: str, | |
| data: dict[str, Any], | |
| register_if_new: bool = True, | |
| ) -> tuple[list[dict[str, Any]], bool, str | None]: | |
| """ | |
| Run consistency + duplicate checks. | |
| Returns (issues, is_duplicate, duplicate_of). | |
| """ | |
| issues = [ | |
| i.model_dump() for i in check_consistency(doc_type, data) | |
| ] | |
| is_dup = False | |
| dup_of: str | None = None | |
| if doc_type != DocType.INVOICE.value: | |
| return issues, is_dup, dup_of | |
| dup_of = await find_duplicate( | |
| session, | |
| supplier=data.get("supplier"), | |
| invoice_number=data.get("invoice_number"), | |
| exclude_id=document_id, | |
| ) | |
| if dup_of: | |
| is_dup = True | |
| issues.append( | |
| { | |
| "code": "duplicate_invoice", | |
| "message": ( | |
| "Same supplier + invoice number " | |
| f"already processed ({dup_of})" | |
| ), | |
| "severity": "warning", | |
| } | |
| ) | |
| elif register_if_new: | |
| await register_invoice( | |
| session, | |
| document_id=document_id, | |
| supplier=data.get("supplier"), | |
| invoice_number=data.get("invoice_number"), | |
| ) | |
| return issues, is_dup, dup_of | |
| def mark_fields_confirmed( | |
| extracted: dict[str, Any], | |
| previous: dict[str, Any] | None = None, | |
| ) -> dict[str, dict]: | |
| """Mark scalar fields as manually confirmed (score 1.0).""" | |
| conf = dict(previous or {}) | |
| for key in extracted: | |
| if key in ARRAY_FIELD_KEYS: | |
| continue | |
| conf[key] = {"score": 1.0, "needs_review": False} | |
| return conf | |
| def average_from_detail(confidence: dict[str, Any]) -> float: | |
| """Average score from detailed confidence map.""" | |
| scores = [ | |
| v["score"] | |
| for v in confidence.values() | |
| if isinstance(v, dict) and "score" in v | |
| ] | |
| if not scores: | |
| return 0.0 | |
| return sum(scores) / len(scores) | |
| def apply_duplicate_flags( | |
| doc: Document, | |
| *, | |
| is_duplicate: bool, | |
| duplicate_of: str | None, | |
| ) -> None: | |
| """Write duplicate flags onto a document row.""" | |
| doc.is_duplicate = is_duplicate | |
| doc.duplicate_of = duplicate_of | |