-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprofile.py
More file actions
120 lines (85 loc) · 3.39 KB
/
Copy pathprofile.py
File metadata and controls
120 lines (85 loc) · 3.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
"""Server profile configuration and parsing.
This module handles the server profile configuration which determines
which API endpoints are enabled (REST, GraphQL).
"""
from functools import lru_cache
from api_server.constants import PROFILE_GRAPHQL, PROFILE_REST
class ProfileManager:
"""Manages server profile configuration state.
This class follows the singleton pattern to maintain active profiles
throughout the application lifecycle.
"""
def __init__(self):
self._active_profiles: set[str] | None = None
def set_active_profiles(self, profiles: set[str]) -> None:
"""Set the active profiles (called during app startup).
Args:
profiles: Set of active profile names
"""
self._active_profiles = profiles
def get_active_profiles(self) -> set[str]:
"""Get the active profiles set.
Returns:
Set of active profile components (REST, GraphQL, MCP)
Note:
If profiles haven't been set yet, returns default (all profiles).
"""
if self._active_profiles is None:
# Fallback: parse from settings if not yet initialized
# Lazy import to avoid circular imports as the codebase grows
from api_server.settings import get_settings
settings = get_settings()
return parse_profile(settings.profiles)
return self._active_profiles
@lru_cache
def get_profile_manager() -> ProfileManager:
"""Get or create the singleton ProfileManager instance.
Returns:
The ProfileManager instance.
"""
return ProfileManager()
def set_active_profiles(profiles: set[str]) -> None:
"""Set the active profiles (called during app startup).
Args:
profiles: Set of active profile names
"""
get_profile_manager().set_active_profiles(profiles)
def get_active_profiles() -> set[str]:
"""Get the active profiles set.
Returns:
Set of active profile components (REST, GraphQL)
Note:
If profiles haven't been set yet, returns default (all profiles).
"""
return get_profile_manager().get_active_profiles()
def parse_profile(config: str | None) -> set[str]:
"""Parse server profile configuration.
Args:
config: Comma-separated profile names (case-insensitive), None, or empty string.
None or empty string enables all profiles.
Returns:
Set of enabled profile components in lowercase (rest, graphql)
Raises:
ValueError: If invalid profile component provided
Examples:
>>> parse_profile(None)
{'rest', 'graphql'}
>>> parse_profile("")
{'rest', 'graphql'}
>>> parse_profile("REST")
{'rest'}
>>> parse_profile("Rest,GraphQL")
{'rest', 'graphql'}
"""
valid_profiles = {PROFILE_REST, PROFILE_GRAPHQL}
# Empty, None, or whitespace-only means all profiles enabled
if not config or not config.strip():
return valid_profiles
# Parse input (case-insensitive), convert to lowercase
profiles = {p.strip().lower() for p in config.split(",") if p.strip()}
# Validate
invalid = profiles - valid_profiles
if invalid:
raise ValueError(f"Invalid profile components: {invalid}. Valid: {', '.join(sorted(valid_profiles))}")
return profiles
__all__ = ["parse_profile", "get_active_profiles", "set_active_profiles", "get_profile_manager"]