feat(config): move youtube_api_key to DB (encrypted, admin-editable)

Register youtube_api_key in the sysconfig registry as a secret and resolve it from
the DB-override-or-env layer in YouTubeClient (self.db is in scope). Adds a YouTube
API group to the Configuration page (EN/HU/DE).

Google OAuth client id/secret stay env-only for now: the authlib client is
registered at module load (auth.py), and the token-refresh reads them too, so a
runtime DB override needs a lazy/re-registerable OAuth client — that belongs to the
install-wizard epic (first-boot OAuth config without restart). Admin-role-via-UI
moves to the auth-overhaul epic (user management lives there).
This commit is contained in:
npeter83 2026-06-19 13:19:06 +02:00
parent c953642e30
commit 2dc374cc7b
6 changed files with 16 additions and 7 deletions

View file

@ -48,6 +48,8 @@ SPECS: tuple[ConfigSpec, ...] = (
# --- Batch sizes ---
ConfigSpec("enrich_batch_size", "int", "batch", "enrich_batch_size", min=1, max=50),
ConfigSpec("autotag_title_sample", "int", "batch", "autotag_title_sample", min=1, max=1_000),
# --- YouTube Data API key (secret; optional — public reads prefer it over OAuth) ---
ConfigSpec("youtube_api_key", "str", "youtube", "youtube_api_key", secret=True),
)
_BY_KEY: dict[str, ConfigSpec] = {s.key: s for s in SPECS}

View file

@ -11,7 +11,7 @@ from datetime import datetime, timedelta, timezone
import httpx
from app import quota
from app import quota, sysconfig
from app.config import settings
from app.models import User
from app.security import decrypt
@ -86,8 +86,9 @@ class YouTubeClient:
def _get(self, path: str, params: dict, cost: int = 1, allow_key: bool = True) -> dict:
p = dict(params)
headers = {}
if allow_key and settings.youtube_api_key:
p["key"] = settings.youtube_api_key
api_key = sysconfig.get_str(self.db, "youtube_api_key")
if allow_key and api_key:
p["key"] = api_key
else:
headers["Authorization"] = f"Bearer {self._access_token()}"
resp = self._http.get(f"{API_BASE}/{path}", params=p, headers=headers)