fix: env var overrides for campaign settings (hf_token, ollama_host etc)
Some checks failed
Build and Push / build (push) Has been cancelled
Some checks failed
Build and Push / build (push) Has been cancelled
This commit is contained in:
@@ -64,3 +64,34 @@ CAMPAIGN_SETTINGS = {
|
||||
"player_recap_style": "story",
|
||||
"player_recap_custom_prompt": "",
|
||||
}
|
||||
|
||||
# Env var names that can override CAMPAIGN_SETTINGS at read time.
|
||||
# Set these in docker-compose.yml to prefill the setup wizard.
|
||||
CAMPAIGN_ENV_OVERRIDES = {
|
||||
"hf_token": "NAT20_HF_TOKEN",
|
||||
"whisper_model": "NAT20_WHISPER_MODEL",
|
||||
"whisper_compute_type": "NAT20_WHISPER_COMPUTE_TYPE",
|
||||
"ollama_host": "NAT20_OLLAMA_HOST",
|
||||
"ollama_model": "NAT20_OLLAMA_MODEL",
|
||||
"api_base_url": "NAT20_API_BASE_URL",
|
||||
"api_key": "NAT20_API_KEY",
|
||||
"api_model": "NAT20_API_MODEL",
|
||||
"chunk_word_target": "NAT20_CHUNK_WORD_TARGET",
|
||||
"world_context": "NAT20_WORLD_CONTEXT",
|
||||
"world_context_path": "NAT20_WORLD_CONTEXT_PATH",
|
||||
"player_recap_style": "NAT20_PLAYER_RECAP_STYLE",
|
||||
"player_recap_custom_prompt": "NAT20_PLAYER_RECAP_CUSTOM_PROMPT",
|
||||
}
|
||||
|
||||
|
||||
def merge_campaign_settings_with_env(raw: dict) -> dict:
|
||||
"""Priority: env var > DB value > CAMPAIGN_SETTINGS default."""
|
||||
merged = {**CAMPAIGN_SETTINGS}
|
||||
for key, val in raw.items():
|
||||
if val and val.strip():
|
||||
merged[key] = val.strip()
|
||||
for key, env_name in CAMPAIGN_ENV_OVERRIDES.items():
|
||||
val = os.environ.get(env_name)
|
||||
if val is not None:
|
||||
merged[key] = val
|
||||
return merged
|
||||
|
||||
@@ -4,6 +4,7 @@ import subprocess
|
||||
import requests
|
||||
|
||||
from . import database as db, config
|
||||
from .config import merge_campaign_settings_with_env
|
||||
|
||||
|
||||
def _check_ffmpeg() -> dict:
|
||||
@@ -27,7 +28,7 @@ def _check_gpu() -> dict:
|
||||
|
||||
|
||||
def _check_hf_token(campaign_id: str = "default") -> dict:
|
||||
settings = db.get_campaign_settings(campaign_id)
|
||||
settings = merge_campaign_settings_with_env(db.get_campaign_settings(campaign_id))
|
||||
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."}
|
||||
@@ -35,7 +36,7 @@ def _check_hf_token(campaign_id: str = "default") -> dict:
|
||||
|
||||
|
||||
def _check_llm_backend(campaign_id: str = "default") -> dict:
|
||||
settings = db.get_campaign_settings(campaign_id)
|
||||
settings = merge_campaign_settings_with_env(db.get_campaign_settings(campaign_id))
|
||||
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."}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from fastapi import APIRouter, HTTPException
|
||||
|
||||
from .. import database as db, config
|
||||
from .. import database as db
|
||||
from ..config import CAMPAIGN_SETTINGS, merge_campaign_settings_with_env
|
||||
|
||||
router = APIRouter(prefix="/api/campaigns", tags=["campaigns"])
|
||||
|
||||
@@ -52,17 +53,14 @@ def get_campaign_settings(campaign_id: str):
|
||||
if not db.get_campaign(campaign_id):
|
||||
raise HTTPException(404, "Campaign not found")
|
||||
raw = db.get_campaign_settings(campaign_id)
|
||||
# return defaults for any missing keys
|
||||
merged = {**config.CAMPAIGN_SETTINGS, **raw}
|
||||
return merged
|
||||
return merge_campaign_settings_with_env(raw)
|
||||
|
||||
|
||||
@router.post("/{campaign_id}/settings")
|
||||
def update_campaign_settings(campaign_id: str, body: dict):
|
||||
if not db.get_campaign(campaign_id):
|
||||
raise HTTPException(404, "Campaign not found")
|
||||
clean = {k: str(v) for k, v in body.items() if k in config.CAMPAIGN_SETTINGS}
|
||||
clean = {k: str(v) for k, v in body.items() if k in CAMPAIGN_SETTINGS}
|
||||
db.update_campaign_settings(campaign_id, clean)
|
||||
raw = db.get_campaign_settings(campaign_id)
|
||||
merged = {**config.CAMPAIGN_SETTINGS, **raw}
|
||||
return merged
|
||||
return merge_campaign_settings_with_env(raw)
|
||||
|
||||
@@ -2,6 +2,7 @@ import requests
|
||||
from fastapi import APIRouter, Query
|
||||
|
||||
from .. import database as db
|
||||
from ..config import merge_campaign_settings_with_env
|
||||
|
||||
router = APIRouter(prefix="/api/models", tags=["models"])
|
||||
|
||||
@@ -10,7 +11,7 @@ router = APIRouter(prefix="/api/models", tags=["models"])
|
||||
def list_ollama_models(campaign_id: str = Query("default")):
|
||||
"""List models already pulled on the configured Ollama host, so the setup
|
||||
wizard can offer a dropdown instead of asking the user to type a tag blind."""
|
||||
settings = db.get_campaign_settings(campaign_id)
|
||||
settings = merge_campaign_settings_with_env(db.get_campaign_settings(campaign_id))
|
||||
host = settings.get("ollama_host", "http://host.docker.internal:11434")
|
||||
try:
|
||||
resp = requests.get(f"{host.rstrip('/')}/api/tags", timeout=5)
|
||||
|
||||
@@ -3,6 +3,7 @@ from pathlib import Path
|
||||
from fastapi import APIRouter, HTTPException, Request
|
||||
|
||||
from .. import database as db, jobs
|
||||
from ..config import merge_campaign_settings_with_env
|
||||
from ..pipeline.turns import load_turns
|
||||
from ..pipeline.summarize import summarize_session
|
||||
|
||||
@@ -19,7 +20,7 @@ async def generate_notes(session_id: str, request: Request):
|
||||
raise HTTPException(400, "Session hasn't been transcribed yet")
|
||||
|
||||
cid = session["campaign_id"] or "default"
|
||||
settings = db.get_campaign_settings(cid)
|
||||
settings = merge_campaign_settings_with_env(db.get_campaign_settings(cid))
|
||||
speaker_map = {r["raw_label"]: r["display_name"] for r in
|
||||
db.get_conn().execute("SELECT raw_label, display_name FROM speakers WHERE session_id = ?", (session_id,))
|
||||
if r["display_name"]}
|
||||
|
||||
@@ -6,6 +6,7 @@ from pathlib import Path
|
||||
from fastapi import APIRouter, UploadFile, File, Form, HTTPException
|
||||
|
||||
from .. import database as db, config, jobs
|
||||
from ..config import merge_campaign_settings_with_env
|
||||
from ..errors import PipelineError
|
||||
from ..pipeline.audio import extract_audio
|
||||
from ..pipeline.transcribe import transcribe_and_diarize
|
||||
@@ -86,7 +87,7 @@ def get_session(session_id: str):
|
||||
|
||||
def _run_transcription(session_id: str, video_path: Path, audio_path: Path, transcript_path: Path, campaign_id: str | None = None):
|
||||
cid = campaign_id or "default"
|
||||
settings = db.get_campaign_settings(cid)
|
||||
settings = merge_campaign_settings_with_env(db.get_campaign_settings(cid))
|
||||
|
||||
def run(progress_cb):
|
||||
db.get_conn() # ensure thread-local connection exists in this worker thread
|
||||
|
||||
Reference in New Issue
Block a user