Coverage for src / local_deep_research / web / services / settings_service.py: 81%
30 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-14 23:55 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-14 23:55 +0000
1from typing import Any, Dict, Optional, Union
3from loguru import logger
5from ...database.models import Setting
6from ...utilities.db_utils import get_settings_manager
9def set_setting(
10 key: str, value: Any, commit: bool = True, db_session=None
11) -> bool:
12 """
13 Set a setting value
15 Args:
16 key: Setting key
17 value: Setting value
18 commit: Whether to commit the change
19 db_session: Optional database session
21 Returns:
22 bool: True if successful
23 """
24 manager = get_settings_manager(db_session)
25 return bool(manager.set_setting(key, value, commit))
28def get_all_settings() -> Dict[str, Any]:
29 """
30 Get all settings, optionally filtered by type
32 Returns:
33 Dict[str, Any]: Dictionary of settings
35 """
36 manager = get_settings_manager()
37 return manager.get_all_settings() # type: ignore[no-any-return]
40def create_or_update_setting(
41 setting: Union[Dict[str, Any], Setting],
42 commit: bool = True,
43 db_session=None,
44) -> Optional[Setting]:
45 """
46 Create or update a setting
48 Args:
49 setting: Setting dictionary or object
50 commit: Whether to commit the change
51 db_session: Optional database session
53 Returns:
54 Optional[Setting]: The setting object if successful
55 """
56 manager = get_settings_manager(db_session)
57 return manager.create_or_update_setting(setting, commit) # type: ignore[no-any-return]
60def invalidate_settings_caches(username=None):
61 """Invalidate all settings-related caches after a settings mutation.
63 Call this after any route that creates, updates, or deletes settings
64 so background services pick up changes immediately.
66 Safe to call from anywhere — silently skips caches that aren't initialized.
68 Args:
69 username: If provided, invalidates only that user's scheduler cache.
70 If None, invalidates all users' scheduler caches.
71 """
72 # 1. News scheduler per-user settings cache (TTLCache, 5-min TTL)
73 try:
74 from ...news.subscription_manager.scheduler import get_news_scheduler
76 scheduler = get_news_scheduler()
77 if username is not None: 77 ↛ 80line 77 didn't jump to line 80 because the condition on line 77 was always true
78 scheduler.invalidate_user_settings_cache(username)
79 else:
80 scheduler.invalidate_all_settings_cache()
81 except Exception:
82 logger.debug("Could not invalidate scheduler cache", exc_info=True)
84 # 2. LLM provider cache (functools.cache, no TTL)
85 try:
86 from ...config.llm_config import get_available_providers
88 get_available_providers.cache_clear()
89 except Exception:
90 logger.debug("Could not clear provider cache", exc_info=True)
93def validate_setting(
94 setting: Setting, value: Any
95) -> tuple[bool, Optional[str]]:
96 """
97 Validate a setting value based on its type and constraints
99 Args:
100 setting: The Setting object to validate against
101 value: The value to validate
103 Returns:
104 tuple[bool, Optional[str]]: (is_valid, error_message)
105 """
106 from ..routes.settings_routes import (
107 validate_setting as routes_validate_setting,
108 )
110 return routes_validate_setting(setting, value)