Spaces:
Running
Running
| """OCR backend interface + result type.""" | |
| from __future__ import annotations | |
| import time | |
| from dataclasses import dataclass, field | |
| from pathlib import Path | |
| class OCRBackendResult: | |
| text: str = "" | |
| engine: str = "none" | |
| tier: str = "offline" # vlm | api | local | offline | |
| pages: int = 0 | |
| confidence: float = 0.0 | |
| latency_ms: float = 0.0 | |
| simulated: bool = False | |
| cost_usd: float = 0.0 | |
| error: str | None = None | |
| blocks: list = field(default_factory=list) | |
| def available(self) -> bool: | |
| return bool(self.text and self.text.strip()) and not self.error | |
| def to_channel_dict(self) -> dict: | |
| d = { | |
| "available": self.available, | |
| "chars": len(self.text.strip()), | |
| "engine": self.engine, | |
| "tier": self.tier, | |
| "confidence": round(self.confidence, 3), | |
| "latency_ms": round(self.latency_ms, 1), | |
| } | |
| if self.simulated: | |
| d["simulated"] = True | |
| if self.error: | |
| d["error"] = self.error | |
| if self.cost_usd: | |
| d["cost_usd"] = round(self.cost_usd, 6) | |
| return d | |
| class OCRBackend: | |
| name: str = "base" | |
| tier: str = "offline" | |
| requires: str = "" # human-readable description of what must be present | |
| def available(self) -> bool: # pragma: no cover - overridden | |
| return False | |
| def extract(self, file_path: str | Path) -> OCRBackendResult: # pragma: no cover | |
| raise NotImplementedError | |
| def _now() -> float: | |
| return time.perf_counter() | |
| def info(self) -> dict: | |
| return {"name": self.name, "tier": self.tier, | |
| "available": self.available(), "requires": self.requires} | |