Files
Nat20-Notes/backend/app/routers/settings.py
KansaiGaijin ef44155b5d
Some checks failed
Build and Push / build (push) Failing after 2m15s
Add CI workflow, full env docs, fix Up button navigation
- .gitea/workflows/build.yaml: Gitea Actions — push latest on main
- docker-compose.example.yml: image-based pull, all NAT20_ vars shown
- settings.py: add NAT20_PLAYER_RECAP_STYLE / CUSTOM_PROMPT overrides
- README.md: full env var reference table with accepted values + rationale
- files.py: fix parent_path to avoid up-button bug; add path traversal guard
- Files.tsx: remove copy/paste/autoPlay, scope to campaign
2026-07-10 22:17:47 +12:00

69 lines
2.3 KiB
Python

import os
from fastapi import APIRouter
from .. import database as db, config
router = APIRouter(prefix="/api/settings", tags=["settings"])
# Settings are stored as flat key/value rows (see database.py / config.DEFAULT_SETTINGS).
# This router is a thin pass-through over that table - it must not invent its own
# schema, or the Settings/Setup pages will silently stop affecting the actual
# transcription/summarization pipeline, which reads these same flat keys.
# Env var overrides — set these in docker-compose.yml to prefill the setup wizard
_ENV_OVERRIDES = {
"onboarding_completed": "NAT20_ONBOARDING_COMPLETED",
"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",
}
_BOOL_KEYS = {"onboarding_completed"}
def _coerce(key: str, value: str):
if key in _BOOL_KEYS:
return str(value).lower() in ("1", "true", "yes")
return value
def _merge_with_env(raw: dict) -> dict:
"""Priority: explicit user DB saves (non-default) > env vars > DEFAULT_SETTINGS."""
merged = {**config.DEFAULT_SETTINGS}
for key, env_name in _ENV_OVERRIDES.items():
val = os.environ.get(env_name)
if val is not None:
merged[key] = val
for key, val in raw.items():
db_val = val.strip()
if db_val and db_val != config.DEFAULT_SETTINGS.get(key, ""):
merged[key] = db_val
return merged
@router.get("")
async def get_settings():
raw = db.get_settings()
merged = _merge_with_env(raw)
return {k: _coerce(k, v) for k, v in merged.items()}
@router.post("")
async def update_settings(patch: dict):
clean = {k: str(v) for k, v in patch.items() if k in config.DEFAULT_SETTINGS}
db.update_settings(clean)
raw = db.get_settings()
merged = _merge_with_env(raw)
return {k: _coerce(k, v) for k, v in merged.items()}