lean-explore 0.3.0__py3-none-any.whl → 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lean_explore/__init__.py +14 -1
- lean_explore/api/__init__.py +12 -1
- lean_explore/api/client.py +64 -176
- lean_explore/cli/__init__.py +10 -1
- lean_explore/cli/data_commands.py +157 -479
- lean_explore/cli/display.py +171 -0
- lean_explore/cli/main.py +51 -608
- lean_explore/config.py +244 -0
- lean_explore/extract/__init__.py +5 -0
- lean_explore/extract/__main__.py +368 -0
- lean_explore/extract/doc_gen4.py +200 -0
- lean_explore/extract/doc_parser.py +499 -0
- lean_explore/extract/embeddings.py +371 -0
- lean_explore/extract/github.py +110 -0
- lean_explore/extract/index.py +317 -0
- lean_explore/extract/informalize.py +653 -0
- lean_explore/extract/package_config.py +59 -0
- lean_explore/extract/package_registry.py +45 -0
- lean_explore/extract/package_utils.py +105 -0
- lean_explore/extract/types.py +25 -0
- lean_explore/mcp/__init__.py +11 -1
- lean_explore/mcp/app.py +14 -46
- lean_explore/mcp/server.py +20 -35
- lean_explore/mcp/tools.py +70 -205
- lean_explore/models/__init__.py +9 -0
- lean_explore/models/search_db.py +76 -0
- lean_explore/models/search_types.py +53 -0
- lean_explore/search/__init__.py +32 -0
- lean_explore/search/engine.py +655 -0
- lean_explore/search/scoring.py +156 -0
- lean_explore/search/service.py +68 -0
- lean_explore/search/tokenization.py +71 -0
- lean_explore/util/__init__.py +28 -0
- lean_explore/util/embedding_client.py +92 -0
- lean_explore/util/logging.py +22 -0
- lean_explore/util/openrouter_client.py +63 -0
- lean_explore/util/reranker_client.py +189 -0
- {lean_explore-0.3.0.dist-info → lean_explore-1.0.0.dist-info}/METADATA +32 -9
- lean_explore-1.0.0.dist-info/RECORD +43 -0
- {lean_explore-0.3.0.dist-info → lean_explore-1.0.0.dist-info}/WHEEL +1 -1
- lean_explore-1.0.0.dist-info/entry_points.txt +2 -0
- lean_explore/cli/agent.py +0 -788
- lean_explore/cli/config_utils.py +0 -481
- lean_explore/defaults.py +0 -114
- lean_explore/local/__init__.py +0 -1
- lean_explore/local/search.py +0 -1050
- lean_explore/local/service.py +0 -479
- lean_explore/shared/__init__.py +0 -1
- lean_explore/shared/models/__init__.py +0 -1
- lean_explore/shared/models/api.py +0 -117
- lean_explore/shared/models/db.py +0 -396
- lean_explore-0.3.0.dist-info/RECORD +0 -26
- lean_explore-0.3.0.dist-info/entry_points.txt +0 -2
- {lean_explore-0.3.0.dist-info → lean_explore-1.0.0.dist-info}/licenses/LICENSE +0 -0
- {lean_explore-0.3.0.dist-info → lean_explore-1.0.0.dist-info}/top_level.txt +0 -0
lean_explore/cli/config_utils.py
DELETED
|
@@ -1,481 +0,0 @@
|
|
|
1
|
-
# src/lean_explore/cli/config_utils.py
|
|
2
|
-
|
|
3
|
-
"""Utilities for managing CLI user configurations, such as API keys.
|
|
4
|
-
|
|
5
|
-
This module provides functions to save and load user-specific settings,
|
|
6
|
-
such as API keys for Lean Explore and OpenAI, from a configuration
|
|
7
|
-
file stored in the user's home directory. It handles file creation,
|
|
8
|
-
parsing, and sets secure permissions for files containing sensitive
|
|
9
|
-
information. It also supports loading API keys from environment
|
|
10
|
-
variables as a fallback if they are not found in the configuration file.
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
import logging
|
|
14
|
-
import os
|
|
15
|
-
import pathlib
|
|
16
|
-
from typing import Any, Dict, Optional
|
|
17
|
-
|
|
18
|
-
import toml
|
|
19
|
-
|
|
20
|
-
logger = logging.getLogger(__name__)
|
|
21
|
-
|
|
22
|
-
# Define the application's configuration directory and file name
|
|
23
|
-
_APP_CONFIG_DIR_NAME: str = "leanexplore"
|
|
24
|
-
_CONFIG_FILENAME: str = "config.toml"
|
|
25
|
-
|
|
26
|
-
# Define keys for Lean Explore API section
|
|
27
|
-
_LEAN_EXPLORE_API_SECTION_NAME: str = "lean_explore_api"
|
|
28
|
-
_LEAN_EXPLORE_API_KEY_NAME: str = "key"
|
|
29
|
-
_LEAN_EXPLORE_API_KEY_ENV_VAR: str = "LEANEXPLORE_API_KEY"
|
|
30
|
-
|
|
31
|
-
# Define keys for OpenAI API section
|
|
32
|
-
_OPENAI_API_SECTION_NAME: str = "openai"
|
|
33
|
-
_OPENAI_API_KEY_NAME: str = "api_key"
|
|
34
|
-
_OPENAI_API_KEY_ENV_VAR: str = "OPENAI_API_KEY"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def get_config_file_path() -> pathlib.Path:
|
|
38
|
-
"""Constructs and returns the absolute path to the configuration file.
|
|
39
|
-
|
|
40
|
-
The path is typically ~/.config/leanexplore/config.toml.
|
|
41
|
-
|
|
42
|
-
Returns:
|
|
43
|
-
pathlib.Path: The absolute path to the configuration file.
|
|
44
|
-
"""
|
|
45
|
-
config_dir = (
|
|
46
|
-
pathlib.Path(os.path.expanduser("~")) / ".config" / _APP_CONFIG_DIR_NAME
|
|
47
|
-
)
|
|
48
|
-
return config_dir / _CONFIG_FILENAME
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
def _ensure_config_dir_exists() -> None:
|
|
52
|
-
"""Ensures that the configuration directory exists.
|
|
53
|
-
|
|
54
|
-
Creates the directory if it's not already present.
|
|
55
|
-
|
|
56
|
-
Raises:
|
|
57
|
-
OSError: If the directory cannot be created due to permission issues
|
|
58
|
-
or other OS-level errors.
|
|
59
|
-
"""
|
|
60
|
-
config_file_path = get_config_file_path()
|
|
61
|
-
config_dir = config_file_path.parent
|
|
62
|
-
try:
|
|
63
|
-
config_dir.mkdir(parents=True, exist_ok=True)
|
|
64
|
-
except OSError as e:
|
|
65
|
-
logger.error(f"Failed to create configuration directory {config_dir}: {e}")
|
|
66
|
-
raise
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def _load_config_data(config_file_path: pathlib.Path) -> Dict[str, Any]:
|
|
70
|
-
"""Loads configuration data from a TOML file.
|
|
71
|
-
|
|
72
|
-
Args:
|
|
73
|
-
config_file_path: Path to the configuration file.
|
|
74
|
-
|
|
75
|
-
Returns:
|
|
76
|
-
A dictionary containing the configuration data. Returns an empty
|
|
77
|
-
dictionary if the file does not exist or is corrupted.
|
|
78
|
-
"""
|
|
79
|
-
config_data: Dict[str, Any] = {}
|
|
80
|
-
if config_file_path.exists() and config_file_path.is_file():
|
|
81
|
-
try:
|
|
82
|
-
with open(config_file_path, encoding="utf-8") as f:
|
|
83
|
-
config_data = toml.load(f)
|
|
84
|
-
except toml.TomlDecodeError:
|
|
85
|
-
logger.warning(
|
|
86
|
-
"Configuration file %s is corrupted. Treating as empty.",
|
|
87
|
-
config_file_path,
|
|
88
|
-
)
|
|
89
|
-
except Exception as e:
|
|
90
|
-
logger.error(
|
|
91
|
-
"Error reading existing config file %s: %s",
|
|
92
|
-
config_file_path,
|
|
93
|
-
e,
|
|
94
|
-
exc_info=True,
|
|
95
|
-
)
|
|
96
|
-
return config_data
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
def _save_config_data(
|
|
100
|
-
config_file_path: pathlib.Path, config_data: Dict[str, Any]
|
|
101
|
-
) -> bool:
|
|
102
|
-
"""Saves configuration data to a TOML file with secure permissions.
|
|
103
|
-
|
|
104
|
-
Args:
|
|
105
|
-
config_file_path: Path to the configuration file.
|
|
106
|
-
config_data: Dictionary containing the configuration data to save.
|
|
107
|
-
|
|
108
|
-
Returns:
|
|
109
|
-
True if saving was successful, False otherwise.
|
|
110
|
-
"""
|
|
111
|
-
try:
|
|
112
|
-
with open(config_file_path, "w", encoding="utf-8") as f:
|
|
113
|
-
toml.dump(config_data, f)
|
|
114
|
-
os.chmod(config_file_path, 0o600) # Set user read/write only
|
|
115
|
-
return True
|
|
116
|
-
except OSError as e:
|
|
117
|
-
logger.error(
|
|
118
|
-
"OS error saving configuration to %s: %s",
|
|
119
|
-
config_file_path,
|
|
120
|
-
e,
|
|
121
|
-
exc_info=True,
|
|
122
|
-
)
|
|
123
|
-
except Exception as e:
|
|
124
|
-
logger.error(
|
|
125
|
-
"Unexpected error saving configuration to %s: %s",
|
|
126
|
-
config_file_path,
|
|
127
|
-
e,
|
|
128
|
-
exc_info=True,
|
|
129
|
-
)
|
|
130
|
-
return False
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
# --- Lean Explore API Key Management ---
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
def save_api_key(api_key: str) -> bool:
|
|
137
|
-
"""Saves the Lean Explore API key to the user's configuration file.
|
|
138
|
-
|
|
139
|
-
Args:
|
|
140
|
-
api_key: The Lean Explore API key string to save.
|
|
141
|
-
|
|
142
|
-
Returns:
|
|
143
|
-
bool: True if the API key was saved successfully, False otherwise.
|
|
144
|
-
"""
|
|
145
|
-
if not api_key or not isinstance(api_key, str):
|
|
146
|
-
logger.error("Attempted to save an invalid or empty Lean Explore API key.")
|
|
147
|
-
return False
|
|
148
|
-
|
|
149
|
-
config_file_path = get_config_file_path()
|
|
150
|
-
try:
|
|
151
|
-
_ensure_config_dir_exists()
|
|
152
|
-
config_data = _load_config_data(config_file_path)
|
|
153
|
-
|
|
154
|
-
if _LEAN_EXPLORE_API_SECTION_NAME not in config_data or not isinstance(
|
|
155
|
-
config_data[_LEAN_EXPLORE_API_SECTION_NAME], dict
|
|
156
|
-
):
|
|
157
|
-
config_data[_LEAN_EXPLORE_API_SECTION_NAME] = {}
|
|
158
|
-
|
|
159
|
-
config_data[_LEAN_EXPLORE_API_SECTION_NAME][_LEAN_EXPLORE_API_KEY_NAME] = (
|
|
160
|
-
api_key
|
|
161
|
-
)
|
|
162
|
-
|
|
163
|
-
if _save_config_data(config_file_path, config_data):
|
|
164
|
-
logger.info("Lean Explore API key saved to %s", config_file_path)
|
|
165
|
-
return True
|
|
166
|
-
except Exception as e:
|
|
167
|
-
logger.error(
|
|
168
|
-
"General error during Lean Explore API key saving process: %s",
|
|
169
|
-
e,
|
|
170
|
-
exc_info=True,
|
|
171
|
-
)
|
|
172
|
-
return False
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
def load_api_key() -> Optional[str]:
|
|
176
|
-
"""Loads the Lean Explore API key.
|
|
177
|
-
|
|
178
|
-
It first checks the user's configuration file (typically
|
|
179
|
-
~/.config/leanexplore/config.toml under the section
|
|
180
|
-
`lean_explore_api` with key `key`). If a valid, non-empty API key
|
|
181
|
-
is found there, it is returned.
|
|
182
|
-
|
|
183
|
-
If the API key is not found in the configuration file, is empty,
|
|
184
|
-
or is not a string, this function then checks the environment
|
|
185
|
-
variable `LEAN_EXPLORE_API_KEY`. If this environment variable is
|
|
186
|
-
set to a non-empty string, its value is returned.
|
|
187
|
-
|
|
188
|
-
If the API key is not found or is invalid in both locations,
|
|
189
|
-
None is returned.
|
|
190
|
-
|
|
191
|
-
Returns:
|
|
192
|
-
Optional[str]: The Lean Explore API key string if found and valid,
|
|
193
|
-
otherwise None.
|
|
194
|
-
"""
|
|
195
|
-
config_file_path = get_config_file_path()
|
|
196
|
-
|
|
197
|
-
# 1. Try loading from config file
|
|
198
|
-
if config_file_path.exists() and config_file_path.is_file():
|
|
199
|
-
try:
|
|
200
|
-
config_data = _load_config_data(config_file_path)
|
|
201
|
-
key_value = config_data.get(_LEAN_EXPLORE_API_SECTION_NAME, {}).get(
|
|
202
|
-
_LEAN_EXPLORE_API_KEY_NAME
|
|
203
|
-
)
|
|
204
|
-
|
|
205
|
-
if isinstance(key_value, str) and key_value: # Non-empty string
|
|
206
|
-
logger.debug(
|
|
207
|
-
"Lean Explore API key loaded from configuration file %s",
|
|
208
|
-
config_file_path,
|
|
209
|
-
)
|
|
210
|
-
return key_value
|
|
211
|
-
elif key_value is not None: # Present but not a valid non-empty string
|
|
212
|
-
logger.warning(
|
|
213
|
-
"Lean Explore API key found in %s but is not a valid "
|
|
214
|
-
"non-empty string. "
|
|
215
|
-
"Will check environment variable %s.",
|
|
216
|
-
config_file_path,
|
|
217
|
-
_LEAN_EXPLORE_API_KEY_ENV_VAR,
|
|
218
|
-
)
|
|
219
|
-
except Exception as e: # Catch unexpected errors during config processing
|
|
220
|
-
logger.error(
|
|
221
|
-
"Error processing configuration file %s for Lean Explore API key: %s. "
|
|
222
|
-
"Will check environment variable %s.",
|
|
223
|
-
config_file_path,
|
|
224
|
-
e,
|
|
225
|
-
_LEAN_EXPLORE_API_KEY_ENV_VAR,
|
|
226
|
-
exc_info=True,
|
|
227
|
-
)
|
|
228
|
-
else:
|
|
229
|
-
logger.debug(
|
|
230
|
-
"Configuration file %s not found. Will check environment "
|
|
231
|
-
"variable %s for Lean Explore API key.",
|
|
232
|
-
config_file_path,
|
|
233
|
-
_LEAN_EXPLORE_API_KEY_ENV_VAR,
|
|
234
|
-
)
|
|
235
|
-
|
|
236
|
-
# 2. Try loading from environment variable
|
|
237
|
-
api_key_from_env = os.getenv(_LEAN_EXPLORE_API_KEY_ENV_VAR)
|
|
238
|
-
|
|
239
|
-
if isinstance(api_key_from_env, str) and api_key_from_env: # Non-empty string
|
|
240
|
-
logger.debug(
|
|
241
|
-
"Lean Explore API key loaded from environment variable %s",
|
|
242
|
-
_LEAN_EXPLORE_API_KEY_ENV_VAR,
|
|
243
|
-
)
|
|
244
|
-
return api_key_from_env
|
|
245
|
-
elif api_key_from_env is not None: # Env var exists but is empty string
|
|
246
|
-
logger.debug(
|
|
247
|
-
"Environment variable %s for Lean Explore API key is set but empty.",
|
|
248
|
-
_LEAN_EXPLORE_API_KEY_ENV_VAR,
|
|
249
|
-
)
|
|
250
|
-
|
|
251
|
-
logger.debug(
|
|
252
|
-
"Lean Explore API key not found in configuration file or "
|
|
253
|
-
"valid in environment variable %s.",
|
|
254
|
-
_LEAN_EXPLORE_API_KEY_ENV_VAR,
|
|
255
|
-
)
|
|
256
|
-
return None
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
def delete_api_key() -> bool:
|
|
260
|
-
"""Deletes the Lean Explore API key from the user's configuration file.
|
|
261
|
-
|
|
262
|
-
Returns:
|
|
263
|
-
bool: True if the API key was successfully removed or if it did not exist;
|
|
264
|
-
False if an error occurred.
|
|
265
|
-
"""
|
|
266
|
-
config_file_path = get_config_file_path()
|
|
267
|
-
if not config_file_path.exists():
|
|
268
|
-
logger.info(
|
|
269
|
-
"No Lean Explore API key to delete: configuration file does not exist."
|
|
270
|
-
)
|
|
271
|
-
return True
|
|
272
|
-
|
|
273
|
-
try:
|
|
274
|
-
config_data = _load_config_data(config_file_path)
|
|
275
|
-
api_section = config_data.get(_LEAN_EXPLORE_API_SECTION_NAME)
|
|
276
|
-
|
|
277
|
-
if (
|
|
278
|
-
api_section
|
|
279
|
-
and isinstance(api_section, dict)
|
|
280
|
-
and _LEAN_EXPLORE_API_KEY_NAME in api_section
|
|
281
|
-
):
|
|
282
|
-
del api_section[_LEAN_EXPLORE_API_KEY_NAME]
|
|
283
|
-
logger.info("Lean Explore API key removed from configuration data.")
|
|
284
|
-
|
|
285
|
-
if not api_section: # If the section is now empty
|
|
286
|
-
del config_data[_LEAN_EXPLORE_API_SECTION_NAME]
|
|
287
|
-
logger.info(
|
|
288
|
-
"Empty '%s' section removed.", _LEAN_EXPLORE_API_SECTION_NAME
|
|
289
|
-
)
|
|
290
|
-
|
|
291
|
-
if _save_config_data(config_file_path, config_data):
|
|
292
|
-
logger.info("Lean Explore API key deleted from %s", config_file_path)
|
|
293
|
-
return True
|
|
294
|
-
return False # Save failed
|
|
295
|
-
else:
|
|
296
|
-
logger.info(
|
|
297
|
-
"Lean Explore API key not found in %s, no deletion performed.",
|
|
298
|
-
config_file_path,
|
|
299
|
-
)
|
|
300
|
-
return True
|
|
301
|
-
|
|
302
|
-
except Exception as e:
|
|
303
|
-
logger.error(
|
|
304
|
-
"Unexpected error deleting Lean Explore API key from %s: %s",
|
|
305
|
-
config_file_path,
|
|
306
|
-
e,
|
|
307
|
-
exc_info=True,
|
|
308
|
-
)
|
|
309
|
-
return False
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
# --- OpenAI API Key Management ---
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
def save_openai_api_key(api_key: str) -> bool:
|
|
316
|
-
"""Saves the OpenAI API key to the user's configuration file.
|
|
317
|
-
|
|
318
|
-
The API key is stored in the same TOML formatted file as other configurations,
|
|
319
|
-
under a distinct section. File permissions are set securely.
|
|
320
|
-
|
|
321
|
-
Args:
|
|
322
|
-
api_key: The OpenAI API key string to save.
|
|
323
|
-
|
|
324
|
-
Returns:
|
|
325
|
-
bool: True if the API key was saved successfully, False otherwise.
|
|
326
|
-
"""
|
|
327
|
-
if not api_key or not isinstance(api_key, str):
|
|
328
|
-
logger.error("Attempted to save an invalid or empty OpenAI API key.")
|
|
329
|
-
return False
|
|
330
|
-
|
|
331
|
-
config_file_path = get_config_file_path()
|
|
332
|
-
try:
|
|
333
|
-
_ensure_config_dir_exists()
|
|
334
|
-
config_data = _load_config_data(config_file_path)
|
|
335
|
-
|
|
336
|
-
if _OPENAI_API_SECTION_NAME not in config_data or not isinstance(
|
|
337
|
-
config_data[_OPENAI_API_SECTION_NAME], dict
|
|
338
|
-
):
|
|
339
|
-
config_data[_OPENAI_API_SECTION_NAME] = {}
|
|
340
|
-
|
|
341
|
-
config_data[_OPENAI_API_SECTION_NAME][_OPENAI_API_KEY_NAME] = api_key
|
|
342
|
-
|
|
343
|
-
if _save_config_data(config_file_path, config_data):
|
|
344
|
-
logger.info("OpenAI API key saved to %s", config_file_path)
|
|
345
|
-
return True
|
|
346
|
-
except Exception as e:
|
|
347
|
-
logger.error(
|
|
348
|
-
"General error during OpenAI API key saving process: %s", e, exc_info=True
|
|
349
|
-
)
|
|
350
|
-
return False
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
def load_openai_api_key() -> Optional[str]:
|
|
354
|
-
"""Loads the OpenAI API key.
|
|
355
|
-
|
|
356
|
-
It first checks the user's configuration file (typically
|
|
357
|
-
~/.config/leanexplore/config.toml under the section
|
|
358
|
-
`openai` with key `api_key`). If a valid, non-empty API key
|
|
359
|
-
is found there, it is returned.
|
|
360
|
-
|
|
361
|
-
If the API key is not found in the configuration file, is empty,
|
|
362
|
-
or is not a string, this function then checks the environment
|
|
363
|
-
variable `OPENAI_API_KEY`. If this environment variable is
|
|
364
|
-
set to a non-empty string, its value is returned.
|
|
365
|
-
|
|
366
|
-
If the API key is not found or is invalid in both locations,
|
|
367
|
-
None is returned.
|
|
368
|
-
|
|
369
|
-
Returns:
|
|
370
|
-
Optional[str]: The OpenAI API key string if found and valid, otherwise None.
|
|
371
|
-
"""
|
|
372
|
-
config_file_path = get_config_file_path()
|
|
373
|
-
|
|
374
|
-
# 1. Try loading from config file
|
|
375
|
-
if config_file_path.exists() and config_file_path.is_file():
|
|
376
|
-
try:
|
|
377
|
-
config_data = _load_config_data(config_file_path)
|
|
378
|
-
key_value = config_data.get(_OPENAI_API_SECTION_NAME, {}).get(
|
|
379
|
-
_OPENAI_API_KEY_NAME
|
|
380
|
-
)
|
|
381
|
-
|
|
382
|
-
if isinstance(key_value, str) and key_value: # Non-empty string
|
|
383
|
-
logger.debug(
|
|
384
|
-
"OpenAI API key loaded from configuration file %s",
|
|
385
|
-
config_file_path,
|
|
386
|
-
)
|
|
387
|
-
return key_value
|
|
388
|
-
elif key_value is not None: # Present but not a valid non-empty string
|
|
389
|
-
logger.warning(
|
|
390
|
-
"OpenAI API key found in %s but is not a valid non-empty string. "
|
|
391
|
-
"Will check environment variable %s.",
|
|
392
|
-
config_file_path,
|
|
393
|
-
_OPENAI_API_KEY_ENV_VAR,
|
|
394
|
-
)
|
|
395
|
-
except Exception as e: # Catch unexpected errors during config processing
|
|
396
|
-
logger.error(
|
|
397
|
-
"Error processing configuration file %s for OpenAI API key: %s. "
|
|
398
|
-
"Will check environment variable %s.",
|
|
399
|
-
config_file_path,
|
|
400
|
-
e,
|
|
401
|
-
_OPENAI_API_KEY_ENV_VAR,
|
|
402
|
-
exc_info=True,
|
|
403
|
-
)
|
|
404
|
-
else:
|
|
405
|
-
logger.debug(
|
|
406
|
-
"Configuration file %s not found. Will check environment "
|
|
407
|
-
"variable %s for OpenAI API key.",
|
|
408
|
-
config_file_path,
|
|
409
|
-
_OPENAI_API_KEY_ENV_VAR,
|
|
410
|
-
)
|
|
411
|
-
|
|
412
|
-
# 2. Try loading from environment variable
|
|
413
|
-
api_key_from_env = os.getenv(_OPENAI_API_KEY_ENV_VAR)
|
|
414
|
-
|
|
415
|
-
if isinstance(api_key_from_env, str) and api_key_from_env: # Non-empty string
|
|
416
|
-
logger.debug(
|
|
417
|
-
"OpenAI API key loaded from environment variable %s",
|
|
418
|
-
_OPENAI_API_KEY_ENV_VAR,
|
|
419
|
-
)
|
|
420
|
-
return api_key_from_env
|
|
421
|
-
elif api_key_from_env is not None: # Env var exists but is empty string
|
|
422
|
-
logger.debug(
|
|
423
|
-
"Environment variable %s for OpenAI API key is set but empty.",
|
|
424
|
-
_OPENAI_API_KEY_ENV_VAR,
|
|
425
|
-
)
|
|
426
|
-
|
|
427
|
-
logger.debug(
|
|
428
|
-
"OpenAI API key not found in configuration file or valid in "
|
|
429
|
-
"environment variable %s.",
|
|
430
|
-
_OPENAI_API_KEY_ENV_VAR,
|
|
431
|
-
)
|
|
432
|
-
return None
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
def delete_openai_api_key() -> bool:
|
|
436
|
-
"""Deletes the OpenAI API key from the user's configuration file.
|
|
437
|
-
|
|
438
|
-
Returns:
|
|
439
|
-
bool: True if the API key was successfully removed or if it did not exist;
|
|
440
|
-
False if an error occurred.
|
|
441
|
-
"""
|
|
442
|
-
config_file_path = get_config_file_path()
|
|
443
|
-
if not config_file_path.exists():
|
|
444
|
-
logger.info("No OpenAI API key to delete: configuration file does not exist.")
|
|
445
|
-
return True
|
|
446
|
-
|
|
447
|
-
try:
|
|
448
|
-
config_data = _load_config_data(config_file_path)
|
|
449
|
-
api_section = config_data.get(_OPENAI_API_SECTION_NAME)
|
|
450
|
-
|
|
451
|
-
if (
|
|
452
|
-
api_section
|
|
453
|
-
and isinstance(api_section, dict)
|
|
454
|
-
and _OPENAI_API_KEY_NAME in api_section
|
|
455
|
-
):
|
|
456
|
-
del api_section[_OPENAI_API_KEY_NAME]
|
|
457
|
-
logger.info("OpenAI API key removed from configuration data.")
|
|
458
|
-
|
|
459
|
-
if not api_section: # If the section is now empty
|
|
460
|
-
del config_data[_OPENAI_API_SECTION_NAME]
|
|
461
|
-
logger.info("Empty '%s' section removed.", _OPENAI_API_SECTION_NAME)
|
|
462
|
-
|
|
463
|
-
if _save_config_data(config_file_path, config_data):
|
|
464
|
-
logger.info("OpenAI API key deleted from %s", config_file_path)
|
|
465
|
-
return True
|
|
466
|
-
return False # Save failed
|
|
467
|
-
else:
|
|
468
|
-
logger.info(
|
|
469
|
-
"OpenAI API key not found in %s, no deletion performed.",
|
|
470
|
-
config_file_path,
|
|
471
|
-
)
|
|
472
|
-
return True
|
|
473
|
-
|
|
474
|
-
except Exception as e:
|
|
475
|
-
logger.error(
|
|
476
|
-
"Unexpected error deleting OpenAI API key from %s: %s",
|
|
477
|
-
config_file_path,
|
|
478
|
-
e,
|
|
479
|
-
exc_info=True,
|
|
480
|
-
)
|
|
481
|
-
return False
|
lean_explore/defaults.py
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
# src/lean_explore/defaults.py
|
|
2
|
-
|
|
3
|
-
"""Provides default paths and configuration parameters for the lean_explore package.
|
|
4
|
-
|
|
5
|
-
This module centralizes default values. The defined paths point to
|
|
6
|
-
a user-specific data directory where downloaded assets (database,
|
|
7
|
-
FAISS index, etc.) for a specific toolchain version are expected to reside.
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
import os
|
|
11
|
-
import pathlib
|
|
12
|
-
from typing import Final
|
|
13
|
-
|
|
14
|
-
# --- User-Specific Data Directory ---
|
|
15
|
-
# Define a base directory within the user's home folder to store
|
|
16
|
-
# downloaded data assets for lean_explore.
|
|
17
|
-
# Example: ~/.lean_explore/data/
|
|
18
|
-
USER_HOME_DIR: Final[pathlib.Path] = pathlib.Path(os.path.expanduser("~"))
|
|
19
|
-
LEAN_EXPLORE_USER_DATA_DIR: Final[pathlib.Path] = (
|
|
20
|
-
USER_HOME_DIR / ".lean_explore" / "data"
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
# --- Toolchain Specific Paths ---
|
|
24
|
-
# Directory within the user data directory to store versioned toolchain data.
|
|
25
|
-
# Example: ~/.lean_explore/data/toolchains/
|
|
26
|
-
LEAN_EXPLORE_TOOLCHAINS_BASE_DIR: Final[pathlib.Path] = (
|
|
27
|
-
LEAN_EXPLORE_USER_DATA_DIR / "toolchains"
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
# Default active toolchain version.
|
|
31
|
-
# In future enhancements, this could be determined dynamically
|
|
32
|
-
# or from user configuration.
|
|
33
|
-
# For now, it's set to the initial version of data provided ("0.1.0").
|
|
34
|
-
DEFAULT_ACTIVE_TOOLCHAIN_VERSION: Final[str] = "0.2.0"
|
|
35
|
-
|
|
36
|
-
# Path to the data directory for the currently active toolchain version.
|
|
37
|
-
# Example: ~/.lean_explore/data/toolchains/0.1.0/
|
|
38
|
-
_ACTIVE_TOOLCHAIN_VERSION_DATA_PATH: Final[pathlib.Path] = (
|
|
39
|
-
LEAN_EXPLORE_TOOLCHAINS_BASE_DIR / DEFAULT_ACTIVE_TOOLCHAIN_VERSION
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
# --- Default Filenames (names of the asset files themselves) ---
|
|
43
|
-
DEFAULT_DB_FILENAME: Final[str] = "lean_explore_data.db"
|
|
44
|
-
DEFAULT_FAISS_INDEX_FILENAME: Final[str] = "main_faiss.index"
|
|
45
|
-
DEFAULT_FAISS_MAP_FILENAME: Final[str] = "faiss_ids_map.json"
|
|
46
|
-
|
|
47
|
-
# --- Default Full Paths (to be used by the application for the active toolchain) ---
|
|
48
|
-
# These paths indicate where the package will look for its data files
|
|
49
|
-
# for the currently active toolchain version. The data management component
|
|
50
|
-
# will be responsible for downloading files to these versioned locations.
|
|
51
|
-
|
|
52
|
-
DEFAULT_DB_PATH: Final[pathlib.Path] = (
|
|
53
|
-
_ACTIVE_TOOLCHAIN_VERSION_DATA_PATH / DEFAULT_DB_FILENAME
|
|
54
|
-
)
|
|
55
|
-
DEFAULT_FAISS_INDEX_PATH: Final[pathlib.Path] = (
|
|
56
|
-
_ACTIVE_TOOLCHAIN_VERSION_DATA_PATH / DEFAULT_FAISS_INDEX_FILENAME
|
|
57
|
-
)
|
|
58
|
-
DEFAULT_FAISS_MAP_PATH: Final[pathlib.Path] = (
|
|
59
|
-
_ACTIVE_TOOLCHAIN_VERSION_DATA_PATH / DEFAULT_FAISS_MAP_FILENAME
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
# For SQLAlchemy, the database URL needs to be a string.
|
|
63
|
-
# We construct the SQLite URL string from the Path object.
|
|
64
|
-
DEFAULT_DB_URL: Final[str] = f"sqlite:///{DEFAULT_DB_PATH.resolve()}"
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
# --- Remote Data Asset Defaults ---
|
|
68
|
-
# These constants are used by the data management commands to locate and
|
|
69
|
-
# manage remote toolchain data assets.
|
|
70
|
-
|
|
71
|
-
# Default URL for the master manifest file on R2.
|
|
72
|
-
R2_MANIFEST_DEFAULT_URL: Final[str] = (
|
|
73
|
-
"https://pub-48b75babc4664808b15520033423c765.r2.dev/manifest.json"
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
# Base URL for accessing assets on R2. Specific file paths from the manifest
|
|
77
|
-
# will be appended to this base.
|
|
78
|
-
R2_ASSETS_BASE_URL: Final[str] = "https://pub-48b75babc4664808b15520033423c765.r2.dev/"
|
|
79
|
-
|
|
80
|
-
# Filename for storing the currently selected active toolchain version.
|
|
81
|
-
# This file will reside in LEAN_EXPLORE_USER_DATA_DIR.
|
|
82
|
-
# Example: ~/.lean_explore/data/active_toolchain.txt
|
|
83
|
-
ACTIVE_TOOLCHAIN_CONFIG_FILENAME: Final[str] = "active_toolchain.txt"
|
|
84
|
-
|
|
85
|
-
# Full path to the active toolchain configuration file.
|
|
86
|
-
ACTIVE_TOOLCHAIN_CONFIG_FILE_PATH: Final[pathlib.Path] = (
|
|
87
|
-
LEAN_EXPLORE_USER_DATA_DIR / ACTIVE_TOOLCHAIN_CONFIG_FILENAME
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
# --- Default Embedding Model ---
|
|
92
|
-
DEFAULT_EMBEDDING_MODEL_NAME: Final[str] = "BAAI/bge-base-en-v1.5"
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
# --- Default Search Parameters ---
|
|
96
|
-
# These values are based on the previously discussed config.yml and search.py fallbacks.
|
|
97
|
-
|
|
98
|
-
# FAISS Search Parameters
|
|
99
|
-
DEFAULT_FAISS_K: Final[int] = 100 # Number of nearest neighbors from FAISS
|
|
100
|
-
DEFAULT_FAISS_NPROBE: Final[int] = 200 # For IVF-type FAISS indexes
|
|
101
|
-
DEFAULT_FAISS_OVERSAMPLING_FACTOR: Final[int] = (
|
|
102
|
-
3 # Factor to multiply faiss_k by when package filters are active.
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
# Scoring and Ranking Parameters
|
|
106
|
-
DEFAULT_SEM_SIM_THRESHOLD: Final[float] = 0.525
|
|
107
|
-
DEFAULT_PAGERANK_WEIGHT: Final[float] = 0.2
|
|
108
|
-
DEFAULT_TEXT_RELEVANCE_WEIGHT: Final[float] = 1.0
|
|
109
|
-
DEFAULT_NAME_MATCH_WEIGHT: Final[float] = 1.0 # Ensuring float for consistency
|
|
110
|
-
|
|
111
|
-
# Output Parameters
|
|
112
|
-
DEFAULT_RESULTS_LIMIT: Final[int] = (
|
|
113
|
-
50 # Default number of final results to display/return
|
|
114
|
-
)
|
lean_explore/local/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"""Local package for lean explore."""
|