mcli-framework 7.1.0__py3-none-any.whl → 7.1.2__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 (94) hide show
  1. mcli/app/completion_cmd.py +59 -49
  2. mcli/app/completion_helpers.py +60 -138
  3. mcli/app/logs_cmd.py +46 -13
  4. mcli/app/main.py +17 -14
  5. mcli/app/model_cmd.py +19 -4
  6. mcli/chat/chat.py +3 -2
  7. mcli/lib/search/cached_vectorizer.py +1 -0
  8. mcli/lib/services/data_pipeline.py +12 -5
  9. mcli/lib/services/lsh_client.py +69 -58
  10. mcli/ml/api/app.py +28 -36
  11. mcli/ml/api/middleware.py +8 -16
  12. mcli/ml/api/routers/admin_router.py +3 -1
  13. mcli/ml/api/routers/auth_router.py +32 -56
  14. mcli/ml/api/routers/backtest_router.py +3 -1
  15. mcli/ml/api/routers/data_router.py +3 -1
  16. mcli/ml/api/routers/model_router.py +35 -74
  17. mcli/ml/api/routers/monitoring_router.py +3 -1
  18. mcli/ml/api/routers/portfolio_router.py +3 -1
  19. mcli/ml/api/routers/prediction_router.py +60 -65
  20. mcli/ml/api/routers/trade_router.py +6 -2
  21. mcli/ml/api/routers/websocket_router.py +12 -9
  22. mcli/ml/api/schemas.py +10 -2
  23. mcli/ml/auth/auth_manager.py +49 -114
  24. mcli/ml/auth/models.py +30 -15
  25. mcli/ml/auth/permissions.py +12 -19
  26. mcli/ml/backtesting/backtest_engine.py +134 -108
  27. mcli/ml/backtesting/performance_metrics.py +142 -108
  28. mcli/ml/cache.py +12 -18
  29. mcli/ml/cli/main.py +37 -23
  30. mcli/ml/config/settings.py +29 -12
  31. mcli/ml/dashboard/app.py +122 -130
  32. mcli/ml/dashboard/app_integrated.py +283 -152
  33. mcli/ml/dashboard/app_supabase.py +176 -108
  34. mcli/ml/dashboard/app_training.py +212 -206
  35. mcli/ml/dashboard/cli.py +14 -5
  36. mcli/ml/data_ingestion/api_connectors.py +51 -81
  37. mcli/ml/data_ingestion/data_pipeline.py +127 -125
  38. mcli/ml/data_ingestion/stream_processor.py +72 -80
  39. mcli/ml/database/migrations/env.py +3 -2
  40. mcli/ml/database/models.py +112 -79
  41. mcli/ml/database/session.py +6 -5
  42. mcli/ml/experimentation/ab_testing.py +149 -99
  43. mcli/ml/features/ensemble_features.py +9 -8
  44. mcli/ml/features/political_features.py +6 -5
  45. mcli/ml/features/recommendation_engine.py +15 -14
  46. mcli/ml/features/stock_features.py +7 -6
  47. mcli/ml/features/test_feature_engineering.py +8 -7
  48. mcli/ml/logging.py +10 -15
  49. mcli/ml/mlops/data_versioning.py +57 -64
  50. mcli/ml/mlops/experiment_tracker.py +49 -41
  51. mcli/ml/mlops/model_serving.py +59 -62
  52. mcli/ml/mlops/pipeline_orchestrator.py +203 -149
  53. mcli/ml/models/base_models.py +8 -7
  54. mcli/ml/models/ensemble_models.py +6 -5
  55. mcli/ml/models/recommendation_models.py +7 -6
  56. mcli/ml/models/test_models.py +18 -14
  57. mcli/ml/monitoring/drift_detection.py +95 -74
  58. mcli/ml/monitoring/metrics.py +10 -22
  59. mcli/ml/optimization/portfolio_optimizer.py +172 -132
  60. mcli/ml/predictions/prediction_engine.py +235 -0
  61. mcli/ml/preprocessing/data_cleaners.py +6 -5
  62. mcli/ml/preprocessing/feature_extractors.py +7 -6
  63. mcli/ml/preprocessing/ml_pipeline.py +3 -2
  64. mcli/ml/preprocessing/politician_trading_preprocessor.py +11 -10
  65. mcli/ml/preprocessing/test_preprocessing.py +4 -4
  66. mcli/ml/scripts/populate_sample_data.py +36 -16
  67. mcli/ml/tasks.py +82 -83
  68. mcli/ml/tests/test_integration.py +86 -76
  69. mcli/ml/tests/test_training_dashboard.py +169 -142
  70. mcli/mygroup/test_cmd.py +2 -1
  71. mcli/self/self_cmd.py +38 -18
  72. mcli/self/test_cmd.py +2 -1
  73. mcli/workflow/dashboard/dashboard_cmd.py +13 -6
  74. mcli/workflow/lsh_integration.py +46 -58
  75. mcli/workflow/politician_trading/commands.py +576 -427
  76. mcli/workflow/politician_trading/config.py +7 -7
  77. mcli/workflow/politician_trading/connectivity.py +35 -33
  78. mcli/workflow/politician_trading/data_sources.py +72 -71
  79. mcli/workflow/politician_trading/database.py +18 -16
  80. mcli/workflow/politician_trading/demo.py +4 -3
  81. mcli/workflow/politician_trading/models.py +5 -5
  82. mcli/workflow/politician_trading/monitoring.py +13 -13
  83. mcli/workflow/politician_trading/scrapers.py +332 -224
  84. mcli/workflow/politician_trading/scrapers_california.py +116 -94
  85. mcli/workflow/politician_trading/scrapers_eu.py +70 -71
  86. mcli/workflow/politician_trading/scrapers_uk.py +118 -90
  87. mcli/workflow/politician_trading/scrapers_us_states.py +125 -92
  88. mcli/workflow/politician_trading/workflow.py +98 -71
  89. {mcli_framework-7.1.0.dist-info → mcli_framework-7.1.2.dist-info}/METADATA +2 -2
  90. {mcli_framework-7.1.0.dist-info → mcli_framework-7.1.2.dist-info}/RECORD +94 -93
  91. {mcli_framework-7.1.0.dist-info → mcli_framework-7.1.2.dist-info}/WHEEL +0 -0
  92. {mcli_framework-7.1.0.dist-info → mcli_framework-7.1.2.dist-info}/entry_points.txt +0 -0
  93. {mcli_framework-7.1.0.dist-info → mcli_framework-7.1.2.dist-info}/licenses/LICENSE +0 -0
  94. {mcli_framework-7.1.0.dist-info → mcli_framework-7.1.2.dist-info}/top_level.txt +0 -0
@@ -8,23 +8,22 @@ import json
8
8
  import os
9
9
  import sys
10
10
  from pathlib import Path
11
- from typing import Dict, Any, Optional
11
+ from typing import Any, Dict, Optional
12
12
 
13
13
  import click
14
14
 
15
15
  from mcli.lib.api import mcli_decorators as mcli
16
16
  from mcli.lib.logger.logger import get_logger
17
+ from mcli.lib.services.data_pipeline import DataPipelineConfig, LSHDataPipeline
17
18
  from mcli.lib.services.lsh_client import LSHClient, LSHEventProcessor
18
- from mcli.lib.services.data_pipeline import LSHDataPipeline, DataPipelineConfig
19
19
 
20
20
  logger = get_logger(__name__)
21
21
 
22
22
 
23
- @mcli.command(
24
- name="lsh-status",
25
- help="Check LSH daemon connection and status"
23
+ @mcli.command(name="lsh-status", help="Check LSH daemon connection and status")
24
+ @mcli.option(
25
+ "--url", default=None, help="LSH API URL (default: $LSH_API_URL or http://localhost:3030)"
26
26
  )
27
- @mcli.option("--url", default=None, help="LSH API URL (default: $LSH_API_URL or http://localhost:3030)")
28
27
  @mcli.option("--api-key", default=None, help="LSH API key (default: $LSH_API_KEY)")
29
28
  async def lsh_status(url: Optional[str], api_key: Optional[str]):
30
29
  """Check LSH daemon connection and status"""
@@ -43,11 +42,13 @@ async def lsh_status(url: Optional[str], api_key: Optional[str]):
43
42
  mcli.echo(f"URL: {client.base_url}")
44
43
  mcli.echo(f"PID: {status.get('pid', 'unknown')}")
45
44
  mcli.echo(f"Uptime: {status.get('uptime', 0) // 60} minutes")
46
- mcli.echo(f"Memory: {status.get('memoryUsage', {}).get('heapUsed', 0) // 1024 // 1024} MB")
45
+ mcli.echo(
46
+ f"Memory: {status.get('memoryUsage', {}).get('heapUsed', 0) // 1024 // 1024} MB"
47
+ )
47
48
 
48
49
  # Get jobs summary
49
50
  jobs = await client.list_jobs()
50
- running_jobs = [j for j in jobs if j.get('status') == 'running']
51
+ running_jobs = [j for j in jobs if j.get("status") == "running"]
51
52
 
52
53
  mcli.echo(f"Total Jobs: {len(jobs)}")
53
54
  mcli.echo(f"Running Jobs: {len(running_jobs)}")
@@ -57,10 +58,7 @@ async def lsh_status(url: Optional[str], api_key: Optional[str]):
57
58
  sys.exit(1)
58
59
 
59
60
 
60
- @mcli.command(
61
- name="lsh-jobs",
62
- help="List and manage LSH jobs"
63
- )
61
+ @mcli.command(name="lsh-jobs", help="List and manage LSH jobs")
64
62
  @mcli.option("--status", help="Filter by job status")
65
63
  @mcli.option("--format", type=mcli.Choice(["table", "json"]), default="table", help="Output format")
66
64
  @mcli.option("--url", default=None, help="LSH API URL")
@@ -71,7 +69,7 @@ async def lsh_jobs(status: Optional[str], format: str, url: Optional[str], api_k
71
69
  async with LSHClient(base_url=url, api_key=api_key) as client:
72
70
  filter_params = {}
73
71
  if status:
74
- filter_params['status'] = status
72
+ filter_params["status"] = status
75
73
 
76
74
  jobs = await client.list_jobs(filter_params)
77
75
 
@@ -85,29 +83,28 @@ async def lsh_jobs(status: Optional[str], format: str, url: Optional[str], api_k
85
83
  mcli.echo("-" * 80)
86
84
 
87
85
  for job in jobs:
88
- job_id = job.get('id', 'unknown')[:18]
89
- name = job.get('name', 'unknown')[:23]
90
- job_status = job.get('status', 'unknown')
91
- job_type = job.get('type', 'unknown')[:13]
86
+ job_id = job.get("id", "unknown")[:18]
87
+ name = job.get("name", "unknown")[:23]
88
+ job_status = job.get("status", "unknown")
89
+ job_type = job.get("type", "unknown")[:13]
92
90
 
93
91
  status_color = {
94
- 'running': 'green',
95
- 'completed': 'blue',
96
- 'failed': 'red',
97
- 'pending': 'yellow'
98
- }.get(job_status, 'white')
92
+ "running": "green",
93
+ "completed": "blue",
94
+ "failed": "red",
95
+ "pending": "yellow",
96
+ }.get(job_status, "white")
99
97
 
100
- mcli.echo(f"{job_id:<20} {name:<25} {mcli.style(job_status, fg=status_color):<20} {job_type:<15}")
98
+ mcli.echo(
99
+ f"{job_id:<20} {name:<25} {mcli.style(job_status, fg=status_color):<20} {job_type:<15}"
100
+ )
101
101
 
102
102
  except Exception as e:
103
103
  mcli.echo(mcli.style(f"❌ Error listing jobs: {e}", fg="red"))
104
104
  sys.exit(1)
105
105
 
106
106
 
107
- @mcli.command(
108
- name="lsh-create-job",
109
- help="Create a new LSH job"
110
- )
107
+ @mcli.command(name="lsh-create-job", help="Create a new LSH job")
111
108
  @mcli.option("--name", required=True, help="Job name")
112
109
  @mcli.option("--command", required=True, help="Command to execute")
113
110
  @mcli.option("--schedule", help="Cron schedule (e.g., '0 */6 * * *')")
@@ -126,7 +123,7 @@ async def lsh_create_job(
126
123
  tags: Optional[str],
127
124
  database_sync: bool,
128
125
  url: Optional[str],
129
- api_key: Optional[str]
126
+ api_key: Optional[str],
130
127
  ):
131
128
  """Create a new LSH job"""
132
129
  try:
@@ -135,7 +132,7 @@ async def lsh_create_job(
135
132
  "name": name,
136
133
  "command": command,
137
134
  "type": type,
138
- "databaseSync": database_sync
135
+ "databaseSync": database_sync,
139
136
  }
140
137
 
141
138
  if schedule:
@@ -159,10 +156,7 @@ async def lsh_create_job(
159
156
  sys.exit(1)
160
157
 
161
158
 
162
- @mcli.command(
163
- name="lsh-pipeline",
164
- help="Start LSH data pipeline listener"
165
- )
159
+ @mcli.command(name="lsh-pipeline", help="Start LSH data pipeline listener")
166
160
  @mcli.option("--batch-size", default=100, help="Batch size for processing")
167
161
  @mcli.option("--batch-timeout", default=30, help="Batch timeout in seconds")
168
162
  @mcli.option("--output-dir", default="./data/processed", help="Output directory for processed data")
@@ -177,7 +171,7 @@ async def lsh_pipeline(
177
171
  disable_validation: bool,
178
172
  disable_enrichment: bool,
179
173
  url: Optional[str],
180
- api_key: Optional[str]
174
+ api_key: Optional[str],
181
175
  ):
182
176
  """Start LSH data pipeline listener"""
183
177
  try:
@@ -208,6 +202,7 @@ async def lsh_pipeline(
208
202
  sys.exit(0)
209
203
 
210
204
  import signal
205
+
211
206
  signal.signal(signal.SIGINT, signal_handler)
212
207
  signal.signal(signal.SIGTERM, signal_handler)
213
208
 
@@ -221,10 +216,7 @@ async def lsh_pipeline(
221
216
  sys.exit(1)
222
217
 
223
218
 
224
- @mcli.command(
225
- name="lsh-listen",
226
- help="Listen to LSH events (for debugging)"
227
- )
219
+ @mcli.command(name="lsh-listen", help="Listen to LSH events (for debugging)")
228
220
  @mcli.option("--url", default=None, help="LSH API URL")
229
221
  @mcli.option("--api-key", default=None, help="LSH API key")
230
222
  @mcli.option("--filter", help="Event type filter (e.g., 'job:completed')")
@@ -259,15 +251,14 @@ async def lsh_listen(url: Optional[str], api_key: Optional[str], filter: Optiona
259
251
  sys.exit(1)
260
252
 
261
253
 
262
- @mcli.command(
263
- name="lsh-webhook",
264
- help="Manage LSH webhooks"
265
- )
254
+ @mcli.command(name="lsh-webhook", help="Manage LSH webhooks")
266
255
  @mcli.option("--action", type=mcli.Choice(["list", "add"]), required=True, help="Action to perform")
267
256
  @mcli.option("--endpoint", help="Webhook endpoint URL (for add action)")
268
257
  @mcli.option("--url", default=None, help="LSH API URL")
269
258
  @mcli.option("--api-key", default=None, help="LSH API key")
270
- async def lsh_webhook(action: str, endpoint: Optional[str], url: Optional[str], api_key: Optional[str]):
259
+ async def lsh_webhook(
260
+ action: str, endpoint: Optional[str], url: Optional[str], api_key: Optional[str]
261
+ ):
271
262
  """Manage LSH webhooks"""
272
263
  try:
273
264
  async with LSHClient(base_url=url, api_key=api_key) as client:
@@ -293,10 +284,7 @@ async def lsh_webhook(action: str, endpoint: Optional[str], url: Optional[str],
293
284
  sys.exit(1)
294
285
 
295
286
 
296
- @mcli.command(
297
- name="lsh-config",
298
- help="Configure LSH integration settings"
299
- )
287
+ @mcli.command(name="lsh-config", help="Configure LSH integration settings")
300
288
  @mcli.option("--set-url", help="Set LSH API URL")
301
289
  @mcli.option("--set-api-key", help="Set LSH API key")
302
290
  @mcli.option("--show", is_flag=True, help="Show current configuration")
@@ -316,15 +304,15 @@ def lsh_config(set_url: Optional[str], set_api_key: Optional[str], show: bool):
316
304
  # Update env file
317
305
  config = {}
318
306
  if env_file.exists():
319
- with open(env_file, 'r') as f:
307
+ with open(env_file, "r") as f:
320
308
  for line in f:
321
- if '=' in line:
322
- key, value = line.strip().split('=', 1)
309
+ if "=" in line:
310
+ key, value = line.strip().split("=", 1)
323
311
  config[key] = value
324
312
 
325
- config['LSH_API_URL'] = set_url
313
+ config["LSH_API_URL"] = set_url
326
314
 
327
- with open(env_file, 'w') as f:
315
+ with open(env_file, "w") as f:
328
316
  for key, value in config.items():
329
317
  f.write(f"{key}={value}\n")
330
318
 
@@ -334,15 +322,15 @@ def lsh_config(set_url: Optional[str], set_api_key: Optional[str], show: bool):
334
322
  # Update env file
335
323
  config = {}
336
324
  if env_file.exists():
337
- with open(env_file, 'r') as f:
325
+ with open(env_file, "r") as f:
338
326
  for line in f:
339
- if '=' in line:
340
- key, value = line.strip().split('=', 1)
327
+ if "=" in line:
328
+ key, value = line.strip().split("=", 1)
341
329
  config[key] = value
342
330
 
343
- config['LSH_API_KEY'] = set_api_key
331
+ config["LSH_API_KEY"] = set_api_key
344
332
 
345
- with open(env_file, 'w') as f:
333
+ with open(env_file, "w") as f:
346
334
  for key, value in config.items():
347
335
  f.write(f"{key}={value}\n")
348
336
 
@@ -352,4 +340,4 @@ def lsh_config(set_url: Optional[str], set_api_key: Optional[str], show: bool):
352
340
  # Register all commands with mcli
353
341
  def register_lsh_commands():
354
342
  """Register LSH integration commands with mcli"""
355
- pass # Commands are automatically registered via decorators
343
+ pass # Commands are automatically registered via decorators