1+ """FastAPI endpoints for settings management."""
2+ from fastapi import APIRouter , HTTPException , Depends
3+ from typing import List
4+ import logging
5+
6+ from lets_talk .api .models .settings import (
7+ SettingsResponse ,
8+ SettingsUpdateSchema ,
9+ SettingsUpdateResponse ,
10+ RestoreDefaultsResponse
11+ )
12+ from lets_talk .core .services .settings import SettingsService
13+ from lets_talk .core .services .settings_init import settings_initializer
14+ from lets_talk .shared .config import LOGGER_NAME
15+
16+ logger = logging .getLogger (f"{ LOGGER_NAME } .api.settings" )
17+
18+ router = APIRouter (
19+ prefix = "/settings" ,
20+ tags = ["settings" ],
21+ responses = {404 : {"description" : "Not found" }},
22+ )
23+
24+
25+ def get_settings_service ():
26+ """Dependency to get settings service instance."""
27+ return SettingsService ()
28+
29+
30+ @router .get ("/" , response_model = SettingsResponse )
31+ async def get_settings (settings_service : SettingsService = Depends (get_settings_service )):
32+ """
33+ Get all system settings.
34+
35+ Returns all settings with secrets masked and organized by sections.
36+ """
37+ try :
38+ # Ensure settings are initialized
39+ if not settings_initializer .ensure_settings_initialized ():
40+ raise HTTPException (
41+ status_code = 500 ,
42+ detail = "Failed to initialize settings database"
43+ )
44+
45+ settings = settings_service .get_all_settings ()
46+ sections = settings_service .get_sections ()
47+
48+ return SettingsResponse (
49+ settings = settings ,
50+ sections = sorted (sections )
51+ )
52+
53+ except Exception as e :
54+ logger .error (f"Error getting settings: { e } " )
55+ raise HTTPException (
56+ status_code = 500 ,
57+ detail = f"Internal server error: { str (e )} "
58+ )
59+
60+
61+ @router .put ("/" , response_model = SettingsUpdateResponse )
62+ async def update_settings (
63+ update_request : SettingsUpdateSchema ,
64+ settings_service : SettingsService = Depends (get_settings_service )
65+ ):
66+ """
67+ Update multiple system settings.
68+
69+ Only read-write settings can be updated. Read-only settings will be rejected.
70+ """
71+ try :
72+ # Ensure settings are initialized
73+ if not settings_initializer .ensure_settings_initialized ():
74+ raise HTTPException (
75+ status_code = 500 ,
76+ detail = "Failed to initialize settings database"
77+ )
78+
79+ successful_updates , failed_updates = settings_service .update_settings (
80+ update_request .settings
81+ )
82+
83+ success = len (failed_updates ) == 0
84+ message = "All settings updated successfully" if success else "Some settings failed to update"
85+
86+ return SettingsUpdateResponse (
87+ success = success ,
88+ message = message ,
89+ updated_settings = successful_updates ,
90+ failed_settings = failed_updates
91+ )
92+
93+ except Exception as e :
94+ logger .error (f"Error updating settings: { e } " )
95+ raise HTTPException (
96+ status_code = 500 ,
97+ detail = f"Internal server error: { str (e )} "
98+ )
99+
100+
101+ @router .post ("/restore-defaults" , response_model = RestoreDefaultsResponse )
102+ async def restore_default_settings (
103+ settings_service : SettingsService = Depends (get_settings_service )
104+ ):
105+ """
106+ Restore all read-write settings to their default values.
107+
108+ This will reset all editable settings to their original default values.
109+ Read-only settings are not affected.
110+ """
111+ try :
112+ # Ensure settings are initialized
113+ if not settings_initializer .ensure_settings_initialized ():
114+ raise HTTPException (
115+ status_code = 500 ,
116+ detail = "Failed to initialize settings database"
117+ )
118+
119+ restored_count = settings_service .restore_defaults ()
120+
121+ return RestoreDefaultsResponse (
122+ success = True ,
123+ message = f"Successfully restored { restored_count } settings to defaults" ,
124+ restored_count = restored_count
125+ )
126+
127+ except Exception as e :
128+ logger .error (f"Error restoring defaults: { e } " )
129+ raise HTTPException (
130+ status_code = 500 ,
131+ detail = f"Internal server error: { str (e )} "
132+ )
0 commit comments