Files
kadence/backend/app/api/routes_settings.py
T
2026-10-18 18:02:05 +03:00

55 lines
1.8 KiB
Python

"""Settings endpoints.
The browser never sees a real token: `GET` masks every secret, and a `PUT` that
sends the mask back untouched keeps the stored value.
"""
from __future__ import annotations
import json
from typing import Any
from fastapi import APIRouter, Body, HTTPException
from pydantic import ValidationError
from app.api.deps import DbSession, Settings
from app.services import blocker_service, settings_service
from app.settings_schema import AppSettings
router = APIRouter(prefix="/api/settings", tags=["settings"])
@router.get("")
def get_settings(settings: Settings) -> dict:
return {
"settings": settings_service.mask_secrets(settings.model_dump(mode="json")),
"defaults": {
"blocked_domains": blocker_service.DEFAULT_DOMAINS,
"blocked_apps": blocker_service.DEFAULT_APPS,
},
}
@router.put("")
def put_settings(session: DbSession, patch: dict[str, Any] = Body(...)) -> dict:
try:
updated = settings_service.apply_patch(session, patch)
except ValidationError as exc:
# `exc.errors()` can carry exception objects in `ctx`, which JSON cannot
# take; pydantic's own `json()` renders them as text.
raise HTTPException(status_code=422, detail=json.loads(exc.json())) from exc
return {"settings": settings_service.mask_secrets(updated.model_dump(mode="json"))}
@router.post("/reset")
def reset_settings(session: DbSession) -> dict:
"""Back to defaults, re-seeded from the environment."""
updated = settings_service.save_settings(session, settings_service.settings_from_env())
return {"settings": settings_service.mask_secrets(updated.model_dump(mode="json"))}
@router.get("/schema")
def settings_schema() -> dict:
"""The JSON Schema, so a client can render the settings form generically."""
return AppSettings.model_json_schema()