Skip to content

Commit 0d69f91

Browse files
authored
Merge pull request lightspeed-core#940 from tisnik/lcore-1092-better-docstrings
LCORE-1092: better docstrings
2 parents 23dc4d1 + 2201ca6 commit 0d69f91

5 files changed

Lines changed: 285 additions & 29 deletions

File tree

src/client.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,28 @@ class AsyncLlamaStackClientHolder(metaclass=Singleton):
2121
_lsc: Optional[AsyncLlamaStackClient] = None
2222

2323
async def load(self, llama_stack_config: LlamaStackConfiguration) -> None:
24-
"""Retrieve Async Llama stack client according to configuration."""
24+
"""
25+
Load and initialize the holder's AsyncLlamaStackClient according to the provided config.
26+
27+
If `llama_stack_config.use_as_library_client` is set to True, a
28+
library-mode client is created using
29+
`llama_stack_config.library_client_config_path` and initialized before
30+
being stored.
31+
32+
Otherwise, a service-mode client is created using
33+
`llama_stack_config.url` and optional `llama_stack_config.api_key`.
34+
The created client is stored on the instance for later retrieval via
35+
`get_client()`.
36+
37+
Parameters:
38+
llama_stack_config (LlamaStackConfiguration): Configuration that
39+
selects client mode and provides either a library client config
40+
path or service connection details (URL and optional API key).
41+
42+
Raises:
43+
ValueError: If `use_as_library_client` is True but
44+
`library_client_config_path` is not set.
45+
"""
2546
if llama_stack_config.use_as_library_client is True:
2647
if llama_stack_config.library_client_config_path is not None:
2748
logger.info("Using Llama stack as library client")
@@ -47,7 +68,15 @@ async def load(self, llama_stack_config: LlamaStackConfiguration) -> None:
4768
)
4869

4970
def get_client(self) -> AsyncLlamaStackClient:
50-
"""Return an initialised AsyncLlamaStackClient."""
71+
"""
72+
Get the initialized client held by this holder.
73+
74+
Returns:
75+
AsyncLlamaStackClient: The initialized client instance.
76+
77+
Raises:
78+
RuntimeError: If the client has not been initialized; call `load(...)` first.
79+
"""
5180
if not self._lsc:
5281
raise RuntimeError(
5382
"AsyncLlamaStackClient has not been initialised. Ensure 'load(..)' has been called."

src/configuration.py

Lines changed: 141 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -49,74 +49,146 @@ def __new__(cls, *args: Any, **kwargs: Any) -> "AppConfig":
4949
return cls._instance
5050

5151
def __init__(self) -> None:
52-
"""Initialize the class instance."""
52+
"""Initialize the class instance.
53+
54+
Sets placeholders for the loaded configuration and lazily-created
55+
runtime resources (conversation cache, quota limiters, and token usage
56+
history).
57+
"""
5358
self._configuration: Optional[Configuration] = None
5459
self._conversation_cache: Optional[Cache] = None
5560
self._quota_limiters: list[QuotaLimiter] = []
5661
self._token_usage_history: Optional[TokenUsageHistory] = None
5762

5863
def load_configuration(self, filename: str) -> None:
59-
"""Load configuration from YAML file."""
64+
"""Load configuration from YAML file.
65+
66+
Parameters:
67+
filename (str): Path to the YAML configuration file to load.
68+
"""
6069
with open(filename, encoding="utf-8") as fin:
6170
config_dict = yaml.safe_load(fin)
6271
config_dict = replace_env_vars(config_dict)
6372
logger.info("Loaded configuration: %s", config_dict)
6473
self.init_from_dict(config_dict)
6574

6675
def init_from_dict(self, config_dict: dict[Any, Any]) -> None:
67-
"""Initialize configuration from a dictionary."""
76+
"""Initialize configuration from a dictionary.
77+
78+
Parameters:
79+
config_dict (dict[Any, Any]): Mapping of configuration values
80+
(typically parsed from YAML) to construct a new Configuration
81+
instance. The method sets the internal configuration to
82+
Configuration(**config_dict) and clears any cached conversation
83+
cache, quota limiters, and token usage history so they will be
84+
reinitialized on next access.
85+
"""
6886
# clear cached values when configuration changes
6987
self._conversation_cache = None
7088
self._quota_limiters = []
89+
self._token_usage_history = None
7190
# now it is possible to re-read configuration
7291
self._configuration = Configuration(**config_dict)
7392

7493
@property
7594
def configuration(self) -> Configuration:
76-
"""Return the whole configuration."""
95+
"""Return the whole configuration.
96+
97+
Returns:
98+
Configuration: The loaded configuration object.
99+
100+
Raises:
101+
LogicError: If the configuration has not been loaded.
102+
"""
77103
if self._configuration is None:
78104
raise LogicError("logic error: configuration is not loaded")
79105
return self._configuration
80106

81107
@property
82108
def service_configuration(self) -> ServiceConfiguration:
83-
"""Return service configuration."""
109+
"""Return service configuration.
110+
111+
Returns:
112+
ServiceConfiguration: The service configuration stored in the current configuration.
113+
114+
Raises:
115+
LogicError: If the configuration has not been loaded.
116+
"""
84117
if self._configuration is None:
85118
raise LogicError("logic error: configuration is not loaded")
86119
return self._configuration.service
87120

88121
@property
89122
def llama_stack_configuration(self) -> LlamaStackConfiguration:
90-
"""Return Llama stack configuration."""
123+
"""Return Llama stack configuration.
124+
125+
Returns:
126+
LlamaStackConfiguration: The configured Llama stack settings.
127+
128+
Raises:
129+
LogicError: If the application configuration has not been loaded.
130+
"""
91131
if self._configuration is None:
92132
raise LogicError("logic error: configuration is not loaded")
93133
return self._configuration.llama_stack
94134

95135
@property
96136
def user_data_collection_configuration(self) -> UserDataCollection:
97-
"""Return user data collection configuration."""
137+
"""Return user data collection configuration.
138+
139+
Returns:
140+
UserDataCollection: The configured UserDataCollection object from
141+
the loaded configuration.
142+
143+
Raises:
144+
LogicError: If the application configuration has not been loaded.
145+
"""
98146
if self._configuration is None:
99147
raise LogicError("logic error: configuration is not loaded")
100148
return self._configuration.user_data_collection
101149

102150
@property
103151
def mcp_servers(self) -> list[ModelContextProtocolServer]:
104-
"""Return model context protocol servers configuration."""
152+
"""Return model context protocol servers configuration.
153+
154+
Returns:
155+
list[ModelContextProtocolServer]: The list of configured MCP servers.
156+
157+
Raises:
158+
LogicError: If the configuration is not loaded.
159+
"""
105160
if self._configuration is None:
106161
raise LogicError("logic error: configuration is not loaded")
107162
return self._configuration.mcp_servers
108163

109164
@property
110165
def authentication_configuration(self) -> AuthenticationConfiguration:
111-
"""Return authentication configuration."""
166+
"""Return authentication configuration.
167+
168+
Returns:
169+
AuthenticationConfiguration: The authentication configuration from
170+
the loaded application configuration.
171+
172+
Raises:
173+
LogicError: If the configuration has not been loaded.
174+
"""
112175
if self._configuration is None:
113176
raise LogicError("logic error: configuration is not loaded")
114177

115178
return self._configuration.authentication
116179

117180
@property
118181
def authorization_configuration(self) -> AuthorizationConfiguration:
119-
"""Return authorization configuration or default no-op configuration."""
182+
"""Return authorization configuration or default no-op configuration.
183+
184+
Returns:
185+
AuthorizationConfiguration: The configured authorization settings,
186+
or a default no-op AuthorizationConfiguration when none is
187+
configured.
188+
189+
Raises:
190+
LogicError: If the configuration has not been loaded.
191+
"""
120192
if self._configuration is None:
121193
raise LogicError("logic error: configuration is not loaded")
122194

@@ -127,42 +199,87 @@ def authorization_configuration(self) -> AuthorizationConfiguration:
127199

128200
@property
129201
def customization(self) -> Optional[Customization]:
130-
"""Return customization configuration."""
202+
"""Return customization configuration.
203+
204+
Returns:
205+
customization (Optional[Customization]): The customization
206+
configuration if present, otherwise None.
207+
208+
Raises:
209+
LogicError: If the configuration has not been loaded.
210+
"""
131211
if self._configuration is None:
132212
raise LogicError("logic error: configuration is not loaded")
133213
return self._configuration.customization
134214

135215
@property
136216
def inference(self) -> InferenceConfiguration:
137-
"""Return inference configuration."""
217+
"""Return inference configuration.
218+
219+
Returns:
220+
InferenceConfiguration: The inference configuration from the loaded
221+
application configuration.
222+
223+
Raises:
224+
LogicError: If the configuration has not been loaded.
225+
"""
138226
if self._configuration is None:
139227
raise LogicError("logic error: configuration is not loaded")
140228
return self._configuration.inference
141229

142230
@property
143231
def conversation_cache_configuration(self) -> ConversationHistoryConfiguration:
144-
"""Return conversation cache configuration."""
232+
"""Return conversation cache configuration.
233+
234+
Returns:
235+
ConversationHistoryConfiguration: The conversation cache
236+
configuration from the loaded application configuration.
237+
238+
Raises:
239+
LogicError: If the configuration has not been loaded.
240+
"""
145241
if self._configuration is None:
146242
raise LogicError("logic error: configuration is not loaded")
147243
return self._configuration.conversation_cache
148244

149245
@property
150246
def database_configuration(self) -> DatabaseConfiguration:
151-
"""Return database configuration."""
247+
"""Return database configuration.
248+
249+
Returns:
250+
DatabaseConfiguration: The configured database settings.
251+
252+
Raises:
253+
LogicError: If the configuration has not been loaded.
254+
"""
152255
if self._configuration is None:
153256
raise LogicError("logic error: configuration is not loaded")
154257
return self._configuration.database
155258

156259
@property
157260
def quota_handlers_configuration(self) -> QuotaHandlersConfiguration:
158-
"""Return quota handlers configuration."""
261+
"""Return quota handlers configuration.
262+
263+
Returns:
264+
quota_handlers (QuotaHandlersConfiguration): The configured quota handlers.
265+
266+
Raises:
267+
LogicError: If configuration has not been loaded.
268+
"""
159269
if self._configuration is None:
160270
raise LogicError("logic error: configuration is not loaded")
161271
return self._configuration.quota_handlers
162272

163273
@property
164274
def conversation_cache(self) -> Cache:
165-
"""Return the conversation cache."""
275+
"""Return the conversation cache.
276+
277+
Returns:
278+
Cache: The conversation cache instance configured by the loaded configuration.
279+
280+
Raises:
281+
LogicError: If the configuration has not been loaded.
282+
"""
166283
if self._configuration is None:
167284
raise LogicError("logic error: configuration is not loaded")
168285
if self._conversation_cache is None:
@@ -173,7 +290,14 @@ def conversation_cache(self) -> Cache:
173290

174291
@property
175292
def quota_limiters(self) -> list[QuotaLimiter]:
176-
"""Return list of all setup quota limiters."""
293+
"""Return list of all setup quota limiters.
294+
295+
Returns:
296+
list[QuotaLimiter]: The quota limiter instances configured for the application.
297+
298+
Raises:
299+
LogicError: If the configuration has not been loaded.
300+
"""
177301
if self._configuration is None:
178302
raise LogicError("logic error: configuration is not loaded")
179303
if not self._quota_limiters:

src/lightspeed_stack.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,20 @@
2525

2626

2727
def create_argument_parser() -> ArgumentParser:
28-
"""Create and configure argument parser object."""
28+
"""Create and configure argument parser object.
29+
30+
The parser includes these options:
31+
- -v / --verbose: enable verbose output
32+
- -d / --dump-configuration: dump the loaded configuration to JSON and exit
33+
- -c / --config: path to the configuration file (default "lightspeed-stack.yaml")
34+
- -g / --generate-llama-stack-configuration: generate a Llama Stack
35+
configuration from the service configuration
36+
- -i / --input-config-file: Llama Stack input configuration filename (default "run.yaml")
37+
- -o / --output-config-file: Llama Stack output configuration filename (default "run_.yaml")
38+
39+
Returns:
40+
Configured ArgumentParser for parsing the service CLI options.
41+
"""
2942
parser = ArgumentParser()
3043
parser.add_argument(
3144
"-v",
@@ -77,7 +90,23 @@ def create_argument_parser() -> ArgumentParser:
7790

7891

7992
def main() -> None:
80-
"""Entry point to the web service."""
93+
"""Entry point to the web service.
94+
95+
Start the Lightspeed Core Stack service process based on CLI flags and configuration.
96+
97+
Parses command-line arguments, loads the configured settings, and then:
98+
- If --dump-configuration is provided, writes the active configuration to
99+
configuration.json and exits (exits with status 1 on failure).
100+
- If --generate-llama-stack-configuration is provided, generates and stores
101+
the Llama Stack configuration to the specified output file and exits
102+
(exits with status 1 on failure).
103+
- Otherwise, sets LIGHTSPEED_STACK_CONFIG_PATH for worker processes, starts
104+
the quota scheduler, and starts the Uvicorn web service.
105+
106+
Raises:
107+
SystemExit: when configuration dumping or Llama Stack generation fails
108+
(exits with status 1).
109+
"""
81110
logger.info("Lightspeed Core Stack startup")
82111
parser = create_argument_parser()
83112
args = parser.parse_args()

0 commit comments

Comments
 (0)