mcli-framework 7.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.

Potentially problematic release.


This version of mcli-framework might be problematic. Click here for more details.

Files changed (186) hide show
  1. mcli/app/chat_cmd.py +42 -0
  2. mcli/app/commands_cmd.py +226 -0
  3. mcli/app/completion_cmd.py +216 -0
  4. mcli/app/completion_helpers.py +288 -0
  5. mcli/app/cron_test_cmd.py +697 -0
  6. mcli/app/logs_cmd.py +419 -0
  7. mcli/app/main.py +492 -0
  8. mcli/app/model/model.py +1060 -0
  9. mcli/app/model_cmd.py +227 -0
  10. mcli/app/redis_cmd.py +269 -0
  11. mcli/app/video/video.py +1114 -0
  12. mcli/app/visual_cmd.py +303 -0
  13. mcli/chat/chat.py +2409 -0
  14. mcli/chat/command_rag.py +514 -0
  15. mcli/chat/enhanced_chat.py +652 -0
  16. mcli/chat/system_controller.py +1010 -0
  17. mcli/chat/system_integration.py +1016 -0
  18. mcli/cli.py +25 -0
  19. mcli/config.toml +20 -0
  20. mcli/lib/api/api.py +586 -0
  21. mcli/lib/api/daemon_client.py +203 -0
  22. mcli/lib/api/daemon_client_local.py +44 -0
  23. mcli/lib/api/daemon_decorator.py +217 -0
  24. mcli/lib/api/mcli_decorators.py +1032 -0
  25. mcli/lib/auth/auth.py +85 -0
  26. mcli/lib/auth/aws_manager.py +85 -0
  27. mcli/lib/auth/azure_manager.py +91 -0
  28. mcli/lib/auth/credential_manager.py +192 -0
  29. mcli/lib/auth/gcp_manager.py +93 -0
  30. mcli/lib/auth/key_manager.py +117 -0
  31. mcli/lib/auth/mcli_manager.py +93 -0
  32. mcli/lib/auth/token_manager.py +75 -0
  33. mcli/lib/auth/token_util.py +1011 -0
  34. mcli/lib/config/config.py +47 -0
  35. mcli/lib/discovery/__init__.py +1 -0
  36. mcli/lib/discovery/command_discovery.py +274 -0
  37. mcli/lib/erd/erd.py +1345 -0
  38. mcli/lib/erd/generate_graph.py +453 -0
  39. mcli/lib/files/files.py +76 -0
  40. mcli/lib/fs/fs.py +109 -0
  41. mcli/lib/lib.py +29 -0
  42. mcli/lib/logger/logger.py +611 -0
  43. mcli/lib/performance/optimizer.py +409 -0
  44. mcli/lib/performance/rust_bridge.py +502 -0
  45. mcli/lib/performance/uvloop_config.py +154 -0
  46. mcli/lib/pickles/pickles.py +50 -0
  47. mcli/lib/search/cached_vectorizer.py +479 -0
  48. mcli/lib/services/data_pipeline.py +460 -0
  49. mcli/lib/services/lsh_client.py +441 -0
  50. mcli/lib/services/redis_service.py +387 -0
  51. mcli/lib/shell/shell.py +137 -0
  52. mcli/lib/toml/toml.py +33 -0
  53. mcli/lib/ui/styling.py +47 -0
  54. mcli/lib/ui/visual_effects.py +634 -0
  55. mcli/lib/watcher/watcher.py +185 -0
  56. mcli/ml/api/app.py +215 -0
  57. mcli/ml/api/middleware.py +224 -0
  58. mcli/ml/api/routers/admin_router.py +12 -0
  59. mcli/ml/api/routers/auth_router.py +244 -0
  60. mcli/ml/api/routers/backtest_router.py +12 -0
  61. mcli/ml/api/routers/data_router.py +12 -0
  62. mcli/ml/api/routers/model_router.py +302 -0
  63. mcli/ml/api/routers/monitoring_router.py +12 -0
  64. mcli/ml/api/routers/portfolio_router.py +12 -0
  65. mcli/ml/api/routers/prediction_router.py +267 -0
  66. mcli/ml/api/routers/trade_router.py +12 -0
  67. mcli/ml/api/routers/websocket_router.py +76 -0
  68. mcli/ml/api/schemas.py +64 -0
  69. mcli/ml/auth/auth_manager.py +425 -0
  70. mcli/ml/auth/models.py +154 -0
  71. mcli/ml/auth/permissions.py +302 -0
  72. mcli/ml/backtesting/backtest_engine.py +502 -0
  73. mcli/ml/backtesting/performance_metrics.py +393 -0
  74. mcli/ml/cache.py +400 -0
  75. mcli/ml/cli/main.py +398 -0
  76. mcli/ml/config/settings.py +394 -0
  77. mcli/ml/configs/dvc_config.py +230 -0
  78. mcli/ml/configs/mlflow_config.py +131 -0
  79. mcli/ml/configs/mlops_manager.py +293 -0
  80. mcli/ml/dashboard/app.py +532 -0
  81. mcli/ml/dashboard/app_integrated.py +738 -0
  82. mcli/ml/dashboard/app_supabase.py +560 -0
  83. mcli/ml/dashboard/app_training.py +615 -0
  84. mcli/ml/dashboard/cli.py +51 -0
  85. mcli/ml/data_ingestion/api_connectors.py +501 -0
  86. mcli/ml/data_ingestion/data_pipeline.py +567 -0
  87. mcli/ml/data_ingestion/stream_processor.py +512 -0
  88. mcli/ml/database/migrations/env.py +94 -0
  89. mcli/ml/database/models.py +667 -0
  90. mcli/ml/database/session.py +200 -0
  91. mcli/ml/experimentation/ab_testing.py +845 -0
  92. mcli/ml/features/ensemble_features.py +607 -0
  93. mcli/ml/features/political_features.py +676 -0
  94. mcli/ml/features/recommendation_engine.py +809 -0
  95. mcli/ml/features/stock_features.py +573 -0
  96. mcli/ml/features/test_feature_engineering.py +346 -0
  97. mcli/ml/logging.py +85 -0
  98. mcli/ml/mlops/data_versioning.py +518 -0
  99. mcli/ml/mlops/experiment_tracker.py +377 -0
  100. mcli/ml/mlops/model_serving.py +481 -0
  101. mcli/ml/mlops/pipeline_orchestrator.py +614 -0
  102. mcli/ml/models/base_models.py +324 -0
  103. mcli/ml/models/ensemble_models.py +675 -0
  104. mcli/ml/models/recommendation_models.py +474 -0
  105. mcli/ml/models/test_models.py +487 -0
  106. mcli/ml/monitoring/drift_detection.py +676 -0
  107. mcli/ml/monitoring/metrics.py +45 -0
  108. mcli/ml/optimization/portfolio_optimizer.py +834 -0
  109. mcli/ml/preprocessing/data_cleaners.py +451 -0
  110. mcli/ml/preprocessing/feature_extractors.py +491 -0
  111. mcli/ml/preprocessing/ml_pipeline.py +382 -0
  112. mcli/ml/preprocessing/politician_trading_preprocessor.py +569 -0
  113. mcli/ml/preprocessing/test_preprocessing.py +294 -0
  114. mcli/ml/scripts/populate_sample_data.py +200 -0
  115. mcli/ml/tasks.py +400 -0
  116. mcli/ml/tests/test_integration.py +429 -0
  117. mcli/ml/tests/test_training_dashboard.py +387 -0
  118. mcli/public/oi/oi.py +15 -0
  119. mcli/public/public.py +4 -0
  120. mcli/self/self_cmd.py +1246 -0
  121. mcli/workflow/daemon/api_daemon.py +800 -0
  122. mcli/workflow/daemon/async_command_database.py +681 -0
  123. mcli/workflow/daemon/async_process_manager.py +591 -0
  124. mcli/workflow/daemon/client.py +530 -0
  125. mcli/workflow/daemon/commands.py +1196 -0
  126. mcli/workflow/daemon/daemon.py +905 -0
  127. mcli/workflow/daemon/daemon_api.py +59 -0
  128. mcli/workflow/daemon/enhanced_daemon.py +571 -0
  129. mcli/workflow/daemon/process_cli.py +244 -0
  130. mcli/workflow/daemon/process_manager.py +439 -0
  131. mcli/workflow/daemon/test_daemon.py +275 -0
  132. mcli/workflow/dashboard/dashboard_cmd.py +113 -0
  133. mcli/workflow/docker/docker.py +0 -0
  134. mcli/workflow/file/file.py +100 -0
  135. mcli/workflow/gcloud/config.toml +21 -0
  136. mcli/workflow/gcloud/gcloud.py +58 -0
  137. mcli/workflow/git_commit/ai_service.py +328 -0
  138. mcli/workflow/git_commit/commands.py +430 -0
  139. mcli/workflow/lsh_integration.py +355 -0
  140. mcli/workflow/model_service/client.py +594 -0
  141. mcli/workflow/model_service/download_and_run_efficient_models.py +288 -0
  142. mcli/workflow/model_service/lightweight_embedder.py +397 -0
  143. mcli/workflow/model_service/lightweight_model_server.py +714 -0
  144. mcli/workflow/model_service/lightweight_test.py +241 -0
  145. mcli/workflow/model_service/model_service.py +1955 -0
  146. mcli/workflow/model_service/ollama_efficient_runner.py +425 -0
  147. mcli/workflow/model_service/pdf_processor.py +386 -0
  148. mcli/workflow/model_service/test_efficient_runner.py +234 -0
  149. mcli/workflow/model_service/test_example.py +315 -0
  150. mcli/workflow/model_service/test_integration.py +131 -0
  151. mcli/workflow/model_service/test_new_features.py +149 -0
  152. mcli/workflow/openai/openai.py +99 -0
  153. mcli/workflow/politician_trading/commands.py +1790 -0
  154. mcli/workflow/politician_trading/config.py +134 -0
  155. mcli/workflow/politician_trading/connectivity.py +490 -0
  156. mcli/workflow/politician_trading/data_sources.py +395 -0
  157. mcli/workflow/politician_trading/database.py +410 -0
  158. mcli/workflow/politician_trading/demo.py +248 -0
  159. mcli/workflow/politician_trading/models.py +165 -0
  160. mcli/workflow/politician_trading/monitoring.py +413 -0
  161. mcli/workflow/politician_trading/scrapers.py +966 -0
  162. mcli/workflow/politician_trading/scrapers_california.py +412 -0
  163. mcli/workflow/politician_trading/scrapers_eu.py +377 -0
  164. mcli/workflow/politician_trading/scrapers_uk.py +350 -0
  165. mcli/workflow/politician_trading/scrapers_us_states.py +438 -0
  166. mcli/workflow/politician_trading/supabase_functions.py +354 -0
  167. mcli/workflow/politician_trading/workflow.py +852 -0
  168. mcli/workflow/registry/registry.py +180 -0
  169. mcli/workflow/repo/repo.py +223 -0
  170. mcli/workflow/scheduler/commands.py +493 -0
  171. mcli/workflow/scheduler/cron_parser.py +238 -0
  172. mcli/workflow/scheduler/job.py +182 -0
  173. mcli/workflow/scheduler/monitor.py +139 -0
  174. mcli/workflow/scheduler/persistence.py +324 -0
  175. mcli/workflow/scheduler/scheduler.py +679 -0
  176. mcli/workflow/sync/sync_cmd.py +437 -0
  177. mcli/workflow/sync/test_cmd.py +314 -0
  178. mcli/workflow/videos/videos.py +242 -0
  179. mcli/workflow/wakatime/wakatime.py +11 -0
  180. mcli/workflow/workflow.py +37 -0
  181. mcli_framework-7.0.0.dist-info/METADATA +479 -0
  182. mcli_framework-7.0.0.dist-info/RECORD +186 -0
  183. mcli_framework-7.0.0.dist-info/WHEEL +5 -0
  184. mcli_framework-7.0.0.dist-info/entry_points.txt +7 -0
  185. mcli_framework-7.0.0.dist-info/licenses/LICENSE +21 -0
  186. mcli_framework-7.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,47 @@
1
+ from pathlib import Path
2
+
3
+ from mcli.lib.fs import get_user_home
4
+ from mcli.lib.logger.logger import get_logger
5
+ from mcli.lib.toml import read_from_toml
6
+
7
+ logger = get_logger(__name__)
8
+ logger.info("")
9
+
10
+ # Path to root repo. Exclude trailing slash
11
+ # TODO: Needs to be updated for all env variables used in app
12
+ PATH_TO_PACKAGE_REPO = "/Users/lefv/mcli/mclifed-guru/cornea"
13
+
14
+ # Listen to file updates within these packages
15
+ PACKAGES_TO_SYNC = ["mcli_ui_package"]
16
+
17
+ # Exclude trailing slash
18
+ ENDPOINT = ""
19
+
20
+ # Basic auth token for BA:BA
21
+ USER_CONFIG_ROOT = f"{get_user_home()}/.config/mcli/"
22
+ DEV_SECRETS_ROOT = f"{get_user_home()}/.config/mcli/secrets/"
23
+ PRIVATE_KEY_PATH = f"{DEV_SECRETS_ROOT}/keys/private_key.pem"
24
+ USER_INFO_FILE = f"{DEV_SECRETS_ROOT}/user/user_info.json"
25
+
26
+
27
+ def get_config_for_file(file_name: str, config_type: str = "config") -> str:
28
+ """Get the config for a file."""
29
+ return f"{get_config_directory()}/{file_name}/mcli.{file_name}.{config_type}.json"
30
+
31
+
32
+ def get_config_directory() -> str:
33
+ """Get the config directory."""
34
+ return Path(USER_CONFIG_ROOT)
35
+
36
+
37
+ def get_config_file_name(raw_file_name: str) -> str:
38
+ """Get the config file name."""
39
+ return raw_file_name.split("/")[-2]
40
+
41
+
42
+ def get_mcli_rc():
43
+ logger.info(__name__)
44
+ logger.info(__package__)
45
+ # case_state_scrambler = read_from_toml(
46
+
47
+ # )
@@ -0,0 +1 @@
1
+ # Discovery module for MCLI commands
@@ -0,0 +1,274 @@
1
+ import importlib
2
+ import inspect
3
+ import sys
4
+ from dataclasses import dataclass
5
+ from pathlib import Path
6
+ from typing import Any, Dict, List, Optional
7
+
8
+ import click
9
+
10
+ from mcli.lib.logger.logger import get_logger
11
+
12
+ logger = get_logger(__name__)
13
+
14
+
15
+ @dataclass
16
+ class DiscoveredCommand:
17
+ """Represents a discovered Click command"""
18
+
19
+ name: str
20
+ full_name: str # e.g., "workflow.file.oxps_to_pdf"
21
+ module_name: str
22
+ group_name: Optional[str]
23
+ description: str
24
+ callback: callable
25
+ is_group: bool = False
26
+ subcommands: List[str] = None
27
+
28
+
29
+ class ClickCommandDiscovery:
30
+ """Discovers all Click commands in the MCLI application"""
31
+
32
+ def __init__(self, base_path: Optional[Path] = None):
33
+ self.base_path = base_path or Path(__file__).parent.parent.parent
34
+ self.discovered_commands: Dict[str, DiscoveredCommand] = {}
35
+
36
+ def discover_all_commands(self) -> List[DiscoveredCommand]:
37
+ """Discover all Click commands in the application"""
38
+ self.discovered_commands.clear()
39
+
40
+ # Get the included directories from config
41
+ from mcli.lib.toml.toml import read_from_toml
42
+
43
+ config_paths = [Path("config.toml"), self.base_path.parent.parent / "config.toml"]
44
+
45
+ included_dirs = ["workflow", "app", "self"] # Default
46
+
47
+ for config_path in config_paths:
48
+ if config_path.exists():
49
+ try:
50
+ config = read_from_toml(str(config_path), "paths")
51
+ if config and config.get("included_dirs"):
52
+ included_dirs = config["included_dirs"]
53
+ break
54
+ except Exception as e:
55
+ logger.debug(f"Could not load config from {config_path}: {e}")
56
+
57
+ logger.info(f"Discovering commands in directories: {included_dirs}")
58
+
59
+ # Discover commands in each included directory
60
+ for directory in included_dirs:
61
+ self._discover_in_directory(directory)
62
+
63
+ return list(self.discovered_commands.values())
64
+
65
+ def _discover_in_directory(self, directory: str):
66
+ """Discover commands in a specific directory"""
67
+ if "/" in directory:
68
+ # Handle nested paths like "workflow/daemon"
69
+ parts = directory.split("/")
70
+ search_path = self.base_path
71
+ for part in parts:
72
+ search_path = search_path / part
73
+ else:
74
+ search_path = self.base_path / directory
75
+
76
+ if not search_path.exists():
77
+ logger.debug(f"Directory {search_path} does not exist")
78
+ return
79
+
80
+ logger.debug(f"Searching for commands in: {search_path}")
81
+
82
+ # Find all Python files
83
+ for py_file in search_path.rglob("*.py"):
84
+ if py_file.name.startswith("__"):
85
+ continue
86
+
87
+ try:
88
+ self._discover_in_file(py_file, directory)
89
+ except Exception as e:
90
+ logger.debug(f"Error discovering commands in {py_file}: {e}")
91
+
92
+ def _discover_in_file(self, py_file: Path, base_directory: str):
93
+ """Discover commands in a specific Python file"""
94
+ # Convert file path to module name
95
+ relative_path = py_file.relative_to(self.base_path.parent)
96
+ module_name = str(relative_path).replace("/", ".").replace(".py", "")
97
+
98
+ # Skip certain modules
99
+ if any(skip in module_name for skip in ["test_", "__pycache__", ".pyc"]):
100
+ return
101
+
102
+ try:
103
+ # Import the module
104
+ if module_name not in sys.modules:
105
+ module = importlib.import_module(module_name)
106
+ else:
107
+ module = sys.modules[module_name]
108
+
109
+ # Find Click objects
110
+ for name, obj in inspect.getmembers(module):
111
+ if isinstance(obj, click.Group):
112
+ self._register_group(obj, module_name, base_directory)
113
+ elif isinstance(obj, click.Command):
114
+ self._register_command(obj, module_name, base_directory)
115
+
116
+ except Exception as e:
117
+ logger.debug(f"Could not import or inspect module {module_name}: {e}")
118
+
119
+ def _register_group(self, group: click.Group, module_name: str, base_directory: str):
120
+ """Register a Click group and its commands"""
121
+ group_full_name = f"{base_directory}.{group.name}" if group.name else base_directory
122
+
123
+ # Register the group itself
124
+ group_cmd = DiscoveredCommand(
125
+ name=group.name or "unnamed",
126
+ full_name=group_full_name,
127
+ module_name=module_name,
128
+ group_name=None,
129
+ description=group.help or "No description",
130
+ callback=group.callback,
131
+ is_group=True,
132
+ subcommands=[],
133
+ )
134
+
135
+ self.discovered_commands[group_full_name] = group_cmd
136
+
137
+ # Register all commands in the group
138
+ for cmd_name, cmd in group.commands.items():
139
+ cmd_full_name = f"{group_full_name}.{cmd_name}"
140
+
141
+ command = DiscoveredCommand(
142
+ name=cmd_name,
143
+ full_name=cmd_full_name,
144
+ module_name=module_name,
145
+ group_name=group.name,
146
+ description=cmd.help or "No description",
147
+ callback=cmd.callback,
148
+ is_group=isinstance(cmd, click.Group),
149
+ )
150
+
151
+ self.discovered_commands[cmd_full_name] = command
152
+ group_cmd.subcommands.append(cmd_name)
153
+
154
+ # If this command is also a group, recursively register its commands
155
+ if isinstance(cmd, click.Group):
156
+ self._register_group_recursive(cmd, cmd_full_name, module_name)
157
+
158
+ def _register_command(self, command: click.Command, module_name: str, base_directory: str):
159
+ """Register a standalone Click command"""
160
+ cmd_full_name = f"{base_directory}.{command.name}" if command.name else base_directory
161
+
162
+ cmd = DiscoveredCommand(
163
+ name=command.name or "unnamed",
164
+ full_name=cmd_full_name,
165
+ module_name=module_name,
166
+ group_name=None,
167
+ description=command.help or "No description",
168
+ callback=command.callback,
169
+ is_group=False,
170
+ )
171
+
172
+ self.discovered_commands[cmd_full_name] = cmd
173
+
174
+ def _register_group_recursive(self, group: click.Group, parent_name: str, module_name: str):
175
+ """Recursively register nested group commands"""
176
+ for cmd_name, cmd in group.commands.items():
177
+ cmd_full_name = f"{parent_name}.{cmd_name}"
178
+
179
+ command = DiscoveredCommand(
180
+ name=cmd_name,
181
+ full_name=cmd_full_name,
182
+ module_name=module_name,
183
+ group_name=group.name,
184
+ description=cmd.help or "No description",
185
+ callback=cmd.callback,
186
+ is_group=isinstance(cmd, click.Group),
187
+ )
188
+
189
+ self.discovered_commands[cmd_full_name] = command
190
+
191
+ if isinstance(cmd, click.Group):
192
+ self._register_group_recursive(cmd, cmd_full_name, module_name)
193
+
194
+ def get_commands(self, include_groups: bool = True) -> List[Dict[str, Any]]:
195
+ """Get all discovered commands as dictionaries"""
196
+ commands = []
197
+
198
+ for cmd in self.discovered_commands.values():
199
+ if not include_groups and cmd.is_group:
200
+ continue
201
+
202
+ command_dict = {
203
+ "id": cmd.full_name,
204
+ "name": cmd.name,
205
+ "full_name": cmd.full_name,
206
+ "description": cmd.description,
207
+ "module": cmd.module_name,
208
+ "group": cmd.group_name,
209
+ "is_group": cmd.is_group,
210
+ "language": "python",
211
+ "tags": [cmd.group_name] if cmd.group_name else [],
212
+ "is_active": True,
213
+ "execution_count": 0,
214
+ "created_at": None,
215
+ "updated_at": None,
216
+ "last_executed": None,
217
+ }
218
+
219
+ if cmd.subcommands:
220
+ command_dict["subcommands"] = cmd.subcommands
221
+
222
+ commands.append(command_dict)
223
+
224
+ return sorted(commands, key=lambda x: x["full_name"])
225
+
226
+ def search_commands(self, query: str) -> List[Dict[str, Any]]:
227
+ """Search commands by name, description, or module"""
228
+ query = query.lower()
229
+ all_commands = self.get_commands()
230
+
231
+ matching_commands = []
232
+ for cmd in all_commands:
233
+ if (
234
+ query in cmd["name"].lower()
235
+ or query in cmd["description"].lower()
236
+ or query in cmd["module"].lower()
237
+ or query in (cmd["group"] or "").lower()
238
+ ):
239
+ matching_commands.append(cmd)
240
+
241
+ return matching_commands
242
+
243
+ def get_command_by_name(self, name: str) -> Optional[DiscoveredCommand]:
244
+ """Get a command by its name or full name"""
245
+ # First try exact match by full name
246
+ if name in self.discovered_commands:
247
+ return self.discovered_commands[name]
248
+
249
+ # Then try by short name
250
+ for cmd in self.discovered_commands.values():
251
+ if cmd.name == name:
252
+ return cmd
253
+
254
+ return None
255
+
256
+
257
+ # Global instance for caching
258
+ _discovery_instance = None
259
+
260
+
261
+ def get_command_discovery() -> ClickCommandDiscovery:
262
+ """Get a cached command discovery instance"""
263
+ global _discovery_instance
264
+ if _discovery_instance is None:
265
+ _discovery_instance = ClickCommandDiscovery()
266
+ _discovery_instance.discover_all_commands()
267
+ return _discovery_instance
268
+
269
+
270
+ def refresh_command_discovery():
271
+ """Refresh the command discovery cache"""
272
+ global _discovery_instance
273
+ _discovery_instance = None
274
+ return get_command_discovery()