Update app.py
Browse files
app.py
CHANGED
|
@@ -116,6 +116,19 @@ warmup_state: Dict[str, Any] = {
|
|
| 116 |
|
| 117 |
warmup_lock = threading.Lock()
|
| 118 |
warmup_stop = threading.Event()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
|
| 120 |
def _default_model_list() -> List[str]:
|
| 121 |
"""
|
|
@@ -518,11 +531,14 @@ from copy import deepcopy
|
|
| 518 |
|
| 519 |
@app.post("/warmup/start", tags=["warmup"])
|
| 520 |
async def warmup_start(payload: Optional[Dict[str, Any]] = Body(None)):
|
| 521 |
-
|
| 522 |
Démarre le téléchargement séquentiel des modèles.
|
| 523 |
Corps JSON optionnel: { "models": ["repo1","repo2", ...] }
|
| 524 |
Si vide: lit la variable d'env WARMUP_MODELS (JSON).
|
| 525 |
"""
|
|
|
|
|
|
|
|
|
|
| 526 |
models = []
|
| 527 |
if payload and isinstance(payload, dict):
|
| 528 |
models = [str(x).strip() for x in (payload.get("models") or []) if str(x).strip()]
|
|
@@ -561,7 +577,6 @@ async def warmup_start(payload: Optional[Dict[str, Any]] = Body(None)):
|
|
| 561 |
|
| 562 |
return {"ok": True, "started": True, "total": len(models), "job_id": job_id}
|
| 563 |
|
| 564 |
-
|
| 565 |
@app.get("/warmup/status", tags=["warmup"])
|
| 566 |
def warmup_status():
|
| 567 |
"""Retourne l'état courant du warm-up (progression, logs, etc.)."""
|
|
@@ -585,8 +600,10 @@ def warmup_stop_api():
|
|
| 585 |
running = bool(warmup_state.get("running"))
|
| 586 |
if running:
|
| 587 |
warmup_stop.set()
|
|
|
|
| 588 |
return {"ok": True, "was_running": True}
|
| 589 |
return {"ok": True, "was_running": False}
|
|
|
|
| 590 |
# >>> B1_END warmup_routes
|
| 591 |
|
| 592 |
|
|
@@ -1059,8 +1076,12 @@ const DEFAULT_MODELS = [
|
|
| 1059 |
|
| 1060 |
function openWarmupPopup(){ if(warmupPopup) warmupPopup.style.display = 'block'; }
|
| 1061 |
|
| 1062 |
-
function closeWarmupPopup(){ if(warmupPopup) warmupPopup.style.display = 'none'; }
|
|
|
|
|
|
|
| 1063 |
if (warmupCloseBtn) warmupCloseBtn.addEventListener('click', closeWarmupPopup);
|
|
|
|
|
|
|
| 1064 |
|
| 1065 |
// Rafraîchissement d’état
|
| 1066 |
let warmupTimer = null;
|
|
@@ -1134,14 +1155,14 @@ async function refreshWarmupUI(){
|
|
| 1134 |
warmupLogs.scrollTop = warmupLogs.scrollHeight;
|
| 1135 |
}
|
| 1136 |
|
| 1137 |
-
|
| 1138 |
-
|
| 1139 |
-
if (running) {
|
| 1140 |
-
openWarmupPopup();
|
| 1141 |
if (!warmupTimer) warmupTimer = setInterval(refreshWarmupUI, 1000);
|
| 1142 |
} else {
|
| 1143 |
if (warmupTimer) { clearInterval(warmupTimer); warmupTimer = null; }
|
|
|
|
| 1144 |
}
|
|
|
|
| 1145 |
}catch(e){ /* no-op */ }
|
| 1146 |
}
|
| 1147 |
|
|
@@ -1187,13 +1208,11 @@ if (warmupStartBtn){
|
|
| 1187 |
} catch(e) {
|
| 1188 |
warmupPreface = '';
|
| 1189 |
}
|
| 1190 |
-
|
| 1191 |
-
|
| 1192 |
-
|
| 1193 |
-
|
| 1194 |
// Ouvre la popup et affiche immédiatement la liste demandée
|
|
|
|
| 1195 |
openWarmupPopup();
|
| 1196 |
-
if (warmupPopupStatus) warmupPopupStatus.textContent = '
|
|
|
|
| 1197 |
if (warmupLogs) {
|
| 1198 |
warmupLogs.textContent = (warmupPreface ? warmupPreface + '\n' : '') + '— démarrage…';
|
| 1199 |
warmupLogs.scrollTop = warmupLogs.scrollHeight; // auto-scroll vers le bas
|
|
@@ -1319,6 +1338,7 @@ if (launchSelectedBtn){
|
|
| 1319 |
.filter(cb=>cb.checked).map(cb=>cb.value);
|
| 1320 |
if(!picks.length){ alert('Sélectionne au moins un modèle.'); return; }
|
| 1321 |
window.lastRequestedModels = picks.slice();
|
|
|
|
| 1322 |
if (typeof openWarmupPopup === 'function') openWarmupPopup();
|
| 1323 |
if (typeof refreshWarmupUI === 'function') await refreshWarmupUI();
|
| 1324 |
try{
|
|
|
|
| 116 |
|
| 117 |
warmup_lock = threading.Lock()
|
| 118 |
warmup_stop = threading.Event()
|
| 119 |
+
# --- Shim anti-avertissement Pylance (défini si absent) ----------------------
|
| 120 |
+
if "_hf_cache_dir" not in globals():
|
| 121 |
+
def _hf_cache_dir() -> str:
|
| 122 |
+
return os.path.expanduser(os.getenv("HF_HOME", "/home/user/.cache/huggingface"))
|
| 123 |
+
|
| 124 |
+
if "_is_repo_cached" not in globals():
|
| 125 |
+
def _is_repo_cached(repo_id: str) -> bool:
|
| 126 |
+
local_dir = os.path.join(_hf_cache_dir(), "models", repo_id.replace("/", "__"))
|
| 127 |
+
try:
|
| 128 |
+
return os.path.isdir(local_dir) and any(os.scandir(local_dir))
|
| 129 |
+
except FileNotFoundError:
|
| 130 |
+
return False
|
| 131 |
+
# ---------------------------------------------------------------------------
|
| 132 |
|
| 133 |
def _default_model_list() -> List[str]:
|
| 134 |
"""
|
|
|
|
| 531 |
|
| 532 |
@app.post("/warmup/start", tags=["warmup"])
|
| 533 |
async def warmup_start(payload: Optional[Dict[str, Any]] = Body(None)):
|
| 534 |
+
"""
|
| 535 |
Démarre le téléchargement séquentiel des modèles.
|
| 536 |
Corps JSON optionnel: { "models": ["repo1","repo2", ...] }
|
| 537 |
Si vide: lit la variable d'env WARMUP_MODELS (JSON).
|
| 538 |
"""
|
| 539 |
+
# Nettoie un éventuel stop précédent pour permettre un nouveau run
|
| 540 |
+
warmup_stop.clear()
|
| 541 |
+
|
| 542 |
models = []
|
| 543 |
if payload and isinstance(payload, dict):
|
| 544 |
models = [str(x).strip() for x in (payload.get("models") or []) if str(x).strip()]
|
|
|
|
| 577 |
|
| 578 |
return {"ok": True, "started": True, "total": len(models), "job_id": job_id}
|
| 579 |
|
|
|
|
| 580 |
@app.get("/warmup/status", tags=["warmup"])
|
| 581 |
def warmup_status():
|
| 582 |
"""Retourne l'état courant du warm-up (progression, logs, etc.)."""
|
|
|
|
| 600 |
running = bool(warmup_state.get("running"))
|
| 601 |
if running:
|
| 602 |
warmup_stop.set()
|
| 603 |
+
_log_warmup("[STOP] Demande d'arrêt reçue — arrêt après le dépôt en cours")
|
| 604 |
return {"ok": True, "was_running": True}
|
| 605 |
return {"ok": True, "was_running": False}
|
| 606 |
+
|
| 607 |
# >>> B1_END warmup_routes
|
| 608 |
|
| 609 |
|
|
|
|
| 1076 |
|
| 1077 |
function openWarmupPopup(){ if(warmupPopup) warmupPopup.style.display = 'block'; }
|
| 1078 |
|
| 1079 |
+
function closeWarmupPopup(){ if(warmupPopup) warmupPopup.style.display = 'none'; }
|
| 1080 |
+
let userClosedWarmupPopup = false;
|
| 1081 |
+
|
| 1082 |
if (warmupCloseBtn) warmupCloseBtn.addEventListener('click', closeWarmupPopup);
|
| 1083 |
+
if (warmupCloseBtn) warmupCloseBtn.addEventListener('click', ()=>{ userClosedWarmupPopup = true; });
|
| 1084 |
+
|
| 1085 |
|
| 1086 |
// Rafraîchissement d’état
|
| 1087 |
let warmupTimer = null;
|
|
|
|
| 1155 |
warmupLogs.scrollTop = warmupLogs.scrollHeight;
|
| 1156 |
}
|
| 1157 |
|
| 1158 |
+
if (running) {
|
| 1159 |
+
if (!userClosedWarmupPopup) openWarmupPopup();
|
|
|
|
|
|
|
| 1160 |
if (!warmupTimer) warmupTimer = setInterval(refreshWarmupUI, 1000);
|
| 1161 |
} else {
|
| 1162 |
if (warmupTimer) { clearInterval(warmupTimer); warmupTimer = null; }
|
| 1163 |
+
userClosedWarmupPopup = false;
|
| 1164 |
}
|
| 1165 |
+
|
| 1166 |
}catch(e){ /* no-op */ }
|
| 1167 |
}
|
| 1168 |
|
|
|
|
| 1208 |
} catch(e) {
|
| 1209 |
warmupPreface = '';
|
| 1210 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1211 |
// Ouvre la popup et affiche immédiatement la liste demandée
|
| 1212 |
+
userClosedWarmupPopup = false;
|
| 1213 |
openWarmupPopup();
|
| 1214 |
+
if (warmupPopupStatus) warmupPopupStatus.textContent = 'Téléchargement en cours…';
|
| 1215 |
+
|
| 1216 |
if (warmupLogs) {
|
| 1217 |
warmupLogs.textContent = (warmupPreface ? warmupPreface + '\n' : '') + '— démarrage…';
|
| 1218 |
warmupLogs.scrollTop = warmupLogs.scrollHeight; // auto-scroll vers le bas
|
|
|
|
| 1338 |
.filter(cb=>cb.checked).map(cb=>cb.value);
|
| 1339 |
if(!picks.length){ alert('Sélectionne au moins un modèle.'); return; }
|
| 1340 |
window.lastRequestedModels = picks.slice();
|
| 1341 |
+
userClosedWarmupPopup = false;
|
| 1342 |
if (typeof openWarmupPopup === 'function') openWarmupPopup();
|
| 1343 |
if (typeof refreshWarmupUI === 'function') await refreshWarmupUI();
|
| 1344 |
try{
|