86 lines
2.6 KiB
Python
86 lines
2.6 KiB
Python
from typing import Dict, List
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from pydantic import BaseModel, Field, model_validator
|
|
from sqlalchemy.orm import Session
|
|
|
|
from routes.dependencies import get_db
|
|
from services.settings import (
|
|
CSS_COLOR_DEFAULTS,
|
|
get_css_color_settings,
|
|
list_css_env_override_rows,
|
|
read_css_color_env_overrides,
|
|
update_css_color_settings,
|
|
)
|
|
|
|
router = APIRouter(prefix="/api/settings", tags=["Settings"])
|
|
|
|
|
|
class CSSSettingsPayload(BaseModel):
|
|
variables: Dict[str, str] = Field(default_factory=dict)
|
|
|
|
@model_validator(mode="after")
|
|
def _validate_allowed_keys(self) -> "CSSSettingsPayload":
|
|
invalid = set(self.variables.keys()) - set(CSS_COLOR_DEFAULTS.keys())
|
|
if invalid:
|
|
invalid_keys = ", ".join(sorted(invalid))
|
|
raise ValueError(
|
|
f"Unsupported CSS variables: {invalid_keys}."
|
|
" Accepted keys align with the default theme variables."
|
|
)
|
|
return self
|
|
|
|
|
|
class EnvOverride(BaseModel):
|
|
css_key: str
|
|
env_var: str
|
|
value: str
|
|
|
|
|
|
class CSSSettingsResponse(BaseModel):
|
|
variables: Dict[str, str]
|
|
env_overrides: Dict[str, str] = Field(default_factory=dict)
|
|
env_sources: List[EnvOverride] = Field(default_factory=list)
|
|
|
|
|
|
@router.get("/css", response_model=CSSSettingsResponse)
|
|
def read_css_settings(db: Session = Depends(get_db)) -> CSSSettingsResponse:
|
|
try:
|
|
values = get_css_color_settings(db)
|
|
env_overrides = read_css_color_env_overrides()
|
|
env_sources = [
|
|
EnvOverride(**row)
|
|
for row in list_css_env_override_rows()
|
|
]
|
|
except ValueError as exc:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
detail=str(exc),
|
|
) from exc
|
|
return CSSSettingsResponse(
|
|
variables=values,
|
|
env_overrides=env_overrides,
|
|
env_sources=env_sources,
|
|
)
|
|
|
|
|
|
@router.put("/css", response_model=CSSSettingsResponse, status_code=status.HTTP_200_OK)
|
|
def update_css_settings(payload: CSSSettingsPayload, db: Session = Depends(get_db)) -> CSSSettingsResponse:
|
|
try:
|
|
values = update_css_color_settings(db, payload.variables)
|
|
env_overrides = read_css_color_env_overrides()
|
|
env_sources = [
|
|
EnvOverride(**row)
|
|
for row in list_css_env_override_rows()
|
|
]
|
|
except ValueError as exc:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_422_UNPROCESSABLE_CONTENT,
|
|
detail=str(exc),
|
|
) from exc
|
|
return CSSSettingsResponse(
|
|
variables=values,
|
|
env_overrides=env_overrides,
|
|
env_sources=env_sources,
|
|
)
|