Upload folder using huggingface_hub
Browse files- app/api/routes.py +16 -0
- app/ml/runtime.py +3 -1
app/api/routes.py
CHANGED
|
@@ -345,6 +345,22 @@ async def db_status_endpoint():
|
|
| 345 |
return await repo.db_status()
|
| 346 |
|
| 347 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 348 |
# ---- History --------------------------------------------------------
|
| 349 |
@router.get("/history", tags=["Validation"])
|
| 350 |
async def get_history(limit: int = Query(default=50, ge=1, le=500)):
|
|
|
|
| 345 |
return await repo.db_status()
|
| 346 |
|
| 347 |
|
| 348 |
+
# ---- ML advisory diagnostics ----------------------------------------
|
| 349 |
+
@router.get("/ml/status", tags=["System"])
|
| 350 |
+
async def ml_status():
|
| 351 |
+
"""Operability of the advisory DistilBERT layer (flag / repo / load state)."""
|
| 352 |
+
from ..config import settings
|
| 353 |
+
from ..ml.runtime import get_model
|
| 354 |
+
|
| 355 |
+
model = get_model()
|
| 356 |
+
return {
|
| 357 |
+
"enabled": settings.ml_disposable_enabled,
|
| 358 |
+
"repo": settings.ml_model_repo,
|
| 359 |
+
"loaded": bool(model is not None and model.loaded),
|
| 360 |
+
"last_error": getattr(model, "last_error", None) if model else None,
|
| 361 |
+
}
|
| 362 |
+
|
| 363 |
+
|
| 364 |
# ---- History --------------------------------------------------------
|
| 365 |
@router.get("/history", tags=["Validation"])
|
| 366 |
async def get_history(limit: int = Query(default=50, ge=1, le=500)):
|
app/ml/runtime.py
CHANGED
|
@@ -58,6 +58,7 @@ class EmailRiskModel:
|
|
| 58 |
self._factory = pipeline_factory or default_pipeline_factory
|
| 59 |
self._pipeline = None
|
| 60 |
self._loaded = False
|
|
|
|
| 61 |
self._lock = threading.Lock()
|
| 62 |
|
| 63 |
@property
|
|
@@ -75,9 +76,10 @@ class EmailRiskModel:
|
|
| 75 |
)
|
| 76 |
self._loaded = True
|
| 77 |
return True
|
| 78 |
-
except Exception:
|
| 79 |
self._pipeline = None
|
| 80 |
self._loaded = False
|
|
|
|
| 81 |
return False
|
| 82 |
|
| 83 |
def predict(self, texts: list[str]) -> Optional[list[tuple[str, float]]]:
|
|
|
|
| 58 |
self._factory = pipeline_factory or default_pipeline_factory
|
| 59 |
self._pipeline = None
|
| 60 |
self._loaded = False
|
| 61 |
+
self.last_error: Optional[str] = None
|
| 62 |
self._lock = threading.Lock()
|
| 63 |
|
| 64 |
@property
|
|
|
|
| 76 |
)
|
| 77 |
self._loaded = True
|
| 78 |
return True
|
| 79 |
+
except Exception as exc:
|
| 80 |
self._pipeline = None
|
| 81 |
self._loaded = False
|
| 82 |
+
self.last_error = f"{type(exc).__name__}: {exc}"
|
| 83 |
return False
|
| 84 |
|
| 85 |
def predict(self, texts: list[str]) -> Optional[list[tuple[str, float]]]:
|