7c7fcf87d1
- Cookbook-Profisuche: ganze HF-URL oder "owner/repo" direkt einfuegbar
(parseHfRepo) -> exakter Treffer statt unscharfer Suche; limit 12->40,
damit auch grosse/seltenere Modelle (z.B. Llama-4-Scout) erscheinen.
- jobengine.attach_download_progress: geglaettete Rate (EMA) + Restzeit
(eta_s) je Download; Aktivitaet zeigt "noch ~X min · Y MB/s".
- Jobs: erledigte/abgebrochene Eintraege einzeln loeschbar (DELETE
/api/jobs/{id}) + "Verlauf leeren" (POST /api/jobs/clear); laufende
bleiben geschuetzt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
45 lines
1.2 KiB
Python
45 lines
1.2 KiB
Python
"""
|
|
Jobs-Router: Status einzelner Hintergrund-Jobs + Liste der letzten Jobs.
|
|
Liefert die Daten fuer das Aktivitaets-Panel mit Live-Log.
|
|
"""
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
|
|
from auth import auth
|
|
from jobengine import JOBS, cancel_job, clear_finished, delete_job
|
|
|
|
router = APIRouter(prefix="/api", dependencies=[Depends(auth)])
|
|
|
|
|
|
@router.get("/jobs/{job_id}")
|
|
def job_status(job_id: str):
|
|
job = JOBS.get(job_id)
|
|
if not job:
|
|
raise HTTPException(404, "Job nicht gefunden.")
|
|
return job
|
|
|
|
|
|
@router.post("/jobs/{job_id}/cancel")
|
|
def job_cancel(job_id: str):
|
|
if not cancel_job(job_id):
|
|
raise HTTPException(409, "Job laeuft nicht (mehr) oder ist unbekannt.")
|
|
return {"ok": True}
|
|
|
|
|
|
@router.post("/jobs/clear")
|
|
def jobs_clear():
|
|
"""Alle abgeschlossenen Jobs aus dem Verlauf entfernen (laufende bleiben)."""
|
|
return {"ok": True, "removed": clear_finished()}
|
|
|
|
|
|
@router.delete("/jobs/{job_id}")
|
|
def job_delete(job_id: str):
|
|
if not delete_job(job_id):
|
|
raise HTTPException(409, "Job laeuft noch oder ist unbekannt — laufende erst abbrechen.")
|
|
return {"ok": True}
|
|
|
|
|
|
@router.get("/jobs")
|
|
def jobs_list():
|
|
return sorted(JOBS.values(), key=lambda j: j["started_at"], reverse=True)[:20]
|