Initial commit: Nat20 Notes — TTRPG session transcription & summarization
This commit is contained in:
73
backend/app/diagnostics.py
Normal file
73
backend/app/diagnostics.py
Normal file
@@ -0,0 +1,73 @@
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
import requests
|
||||
|
||||
from . import database as db, config
|
||||
|
||||
|
||||
def _check_ffmpeg() -> dict:
|
||||
path = shutil.which("ffmpeg")
|
||||
if not path:
|
||||
return {"name": "ffmpeg", "ok": False, "message": "ffmpeg not found on PATH. This should be baked into the Docker image - if you're seeing this, the image build is broken."}
|
||||
return {"name": "ffmpeg", "ok": True, "message": path}
|
||||
|
||||
|
||||
def _check_gpu() -> dict:
|
||||
try:
|
||||
import torch
|
||||
if torch.cuda.is_available():
|
||||
name = torch.cuda.get_device_name(0)
|
||||
free, total = torch.cuda.mem_get_info(0)
|
||||
free_gb, total_gb = free / 1e9, total / 1e9
|
||||
return {"name": "gpu", "ok": True, "message": f"{name} — {free_gb:.1f}GB free of {total_gb:.1f}GB"}
|
||||
return {"name": "gpu", "ok": False, "message": "No CUDA GPU visible. Check that the container was started with --gpus all / GPU passthrough in compose, and that host NVIDIA drivers + Container Toolkit are installed. Transcription will fall back to CPU, which is much slower."}
|
||||
except Exception as e:
|
||||
return {"name": "gpu", "ok": False, "message": f"Could not query GPU: {e}"}
|
||||
|
||||
|
||||
def _check_hf_token() -> dict:
|
||||
settings = db.get_settings()
|
||||
token = settings.get("hf_token", "")
|
||||
if not token:
|
||||
return {"name": "huggingface_token", "ok": False, "message": "No HF token set. Diarization (speaker separation) will fail without one. Add it in Settings."}
|
||||
return {"name": "huggingface_token", "ok": True, "message": "Token is set (not validated against HF until first diarization run)."}
|
||||
|
||||
|
||||
def _check_llm_backend() -> dict:
|
||||
settings = db.get_settings()
|
||||
if settings.get("llm_mode") == "api":
|
||||
if not settings.get("api_key"):
|
||||
return {"name": "llm_backend", "ok": False, "message": "Hosted API selected but no API key set."}
|
||||
return {"name": "llm_backend", "ok": True, "message": f"Hosted API configured ({settings.get('api_base_url')})"}
|
||||
|
||||
host = settings.get("ollama_host", "http://localhost:11434")
|
||||
model = settings.get("ollama_model", "")
|
||||
try:
|
||||
resp = requests.get(f"{host.rstrip('/')}/api/tags", timeout=5)
|
||||
resp.raise_for_status()
|
||||
models = [m["name"] for m in resp.json().get("models", [])]
|
||||
if model not in models:
|
||||
return {"name": "llm_backend", "ok": False, "message": f"Reached Ollama at {host}, but model '{model}' isn't pulled there. Available: {', '.join(models) or '(none)'}. Run: ollama pull {model}"}
|
||||
return {"name": "llm_backend", "ok": True, "message": f"Ollama reachable at {host}, model '{model}' available"}
|
||||
except requests.exceptions.ConnectionError:
|
||||
return {"name": "llm_backend", "ok": False, "message": f"Could not connect to Ollama at {host}. Check the host/port in Settings, and that Ollama is running and reachable from this container."}
|
||||
except Exception as e:
|
||||
return {"name": "llm_backend", "ok": False, "message": f"Error checking Ollama: {e}"}
|
||||
|
||||
|
||||
def _check_disk_space() -> dict:
|
||||
usage = shutil.disk_usage(config.DATA_DIR)
|
||||
free_gb = usage.free / 1e9
|
||||
ok = free_gb > 5
|
||||
return {"name": "disk_space", "ok": ok, "message": f"{free_gb:.1f}GB free in {config.DATA_DIR}" + ("" if ok else " — this is low, recordings and model caches need room")}
|
||||
|
||||
|
||||
def run_diagnostics() -> list[dict]:
|
||||
return [
|
||||
_check_ffmpeg(),
|
||||
_check_gpu(),
|
||||
_check_hf_token(),
|
||||
_check_llm_backend(),
|
||||
_check_disk_space(),
|
||||
]
|
||||
Reference in New Issue
Block a user