Spaces:
Sleeping
Sleeping
Hikity commited on
Commit ·
717e080
1
Parent(s): 2543a43
fix: warm EasyOCR at startup — cold-init on first currency request exceeded HF proxy timeout and 500'd after every container restart
Browse files- app/currency_detector.py +13 -8
- app/main.py +16 -0
app/currency_detector.py
CHANGED
|
@@ -52,20 +52,25 @@ import numpy as np
|
|
| 52 |
import torch
|
| 53 |
import torch.nn as nn
|
| 54 |
|
|
|
|
|
|
|
| 55 |
_easyocr_reader = None
|
|
|
|
| 56 |
|
| 57 |
|
| 58 |
def _get_ocr_reader():
|
| 59 |
"""Lazy-loaded, process-wide EasyOCR reader (pure Python, no Tesseract
|
| 60 |
-
binary dependency — heavy to init, so load once).
|
|
|
|
| 61 |
global _easyocr_reader
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
|
|
|
| 69 |
return _easyocr_reader or None
|
| 70 |
|
| 71 |
|
|
|
|
| 52 |
import torch
|
| 53 |
import torch.nn as nn
|
| 54 |
|
| 55 |
+
import threading
|
| 56 |
+
|
| 57 |
_easyocr_reader = None
|
| 58 |
+
_easyocr_lock = threading.Lock()
|
| 59 |
|
| 60 |
|
| 61 |
def _get_ocr_reader():
|
| 62 |
"""Lazy-loaded, process-wide EasyOCR reader (pure Python, no Tesseract
|
| 63 |
+
binary dependency — heavy to init, so load once). Lock-guarded because
|
| 64 |
+
startup warms it from a background thread while requests may arrive."""
|
| 65 |
global _easyocr_reader
|
| 66 |
+
with _easyocr_lock:
|
| 67 |
+
if _easyocr_reader is None:
|
| 68 |
+
try:
|
| 69 |
+
import easyocr
|
| 70 |
+
_easyocr_reader = easyocr.Reader(["en"], gpu=torch.cuda.is_available(), verbose=False)
|
| 71 |
+
except Exception as e:
|
| 72 |
+
print(f"[CURRENCY] EasyOCR unavailable ({e}) — OCR-based checks will report not_applicable.")
|
| 73 |
+
_easyocr_reader = False # sentinel: tried and failed, don't retry every call
|
| 74 |
return _easyocr_reader or None
|
| 75 |
|
| 76 |
|
app/main.py
CHANGED
|
@@ -85,6 +85,22 @@ async def lifespan(app: FastAPI):
|
|
| 85 |
currency_detector = CurrencyDetector(weights_dir=weights_dir, device=device)
|
| 86 |
print(f" [OK] Currency detector ready (mode: {currency_detector.mode})")
|
| 87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
print(f"\n{'='*60}")
|
| 89 |
print(" KAWACH startup complete — 6 endpoints live")
|
| 90 |
print(f"{'='*60}\n")
|
|
|
|
| 85 |
currency_detector = CurrencyDetector(weights_dir=weights_dir, device=device)
|
| 86 |
print(f" [OK] Currency detector ready (mode: {currency_detector.mode})")
|
| 87 |
|
| 88 |
+
# Warm EasyOCR in the background: its lazy first-call init takes long
|
| 89 |
+
# enough on the free-tier 2vCPU host that the first currency request
|
| 90 |
+
# after every container (re)start blew past the HF proxy timeout and
|
| 91 |
+
# 500'd (observed 2026-07-19 — failures rotated across images, warm
|
| 92 |
+
# container always fine). Boot stays fast; only OCR-dependent checks
|
| 93 |
+
# degrade gracefully until the thread finishes.
|
| 94 |
+
import threading
|
| 95 |
+
from app.currency_detector import _get_ocr_reader
|
| 96 |
+
|
| 97 |
+
def _warm_ocr():
|
| 98 |
+
print(" [P7] Warming EasyOCR reader (background)...")
|
| 99 |
+
_get_ocr_reader()
|
| 100 |
+
print(" [P7] EasyOCR reader warm")
|
| 101 |
+
|
| 102 |
+
threading.Thread(target=_warm_ocr, daemon=True).start()
|
| 103 |
+
|
| 104 |
print(f"\n{'='*60}")
|
| 105 |
print(" KAWACH startup complete — 6 endpoints live")
|
| 106 |
print(f"{'='*60}\n")
|