mcli-framework 7.1.1__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.
- mcli/app/completion_cmd.py +59 -49
- mcli/app/completion_helpers.py +60 -138
- mcli/app/logs_cmd.py +6 -2
- mcli/app/main.py +17 -14
- mcli/app/model_cmd.py +19 -4
- mcli/chat/chat.py +3 -2
- mcli/lib/search/cached_vectorizer.py +1 -0
- mcli/lib/services/data_pipeline.py +12 -5
- mcli/lib/services/lsh_client.py +68 -57
- mcli/ml/api/app.py +28 -36
- mcli/ml/api/middleware.py +8 -16
- mcli/ml/api/routers/admin_router.py +3 -1
- mcli/ml/api/routers/auth_router.py +32 -56
- mcli/ml/api/routers/backtest_router.py +3 -1
- mcli/ml/api/routers/data_router.py +3 -1
- mcli/ml/api/routers/model_router.py +35 -74
- mcli/ml/api/routers/monitoring_router.py +3 -1
- mcli/ml/api/routers/portfolio_router.py +3 -1
- mcli/ml/api/routers/prediction_router.py +60 -65
- mcli/ml/api/routers/trade_router.py +6 -2
- mcli/ml/api/routers/websocket_router.py +12 -9
- mcli/ml/api/schemas.py +10 -2
- mcli/ml/auth/auth_manager.py +49 -114
- mcli/ml/auth/models.py +30 -15
- mcli/ml/auth/permissions.py +12 -19
- mcli/ml/backtesting/backtest_engine.py +134 -108
- mcli/ml/backtesting/performance_metrics.py +142 -108
- mcli/ml/cache.py +12 -18
- mcli/ml/cli/main.py +37 -23
- mcli/ml/config/settings.py +29 -12
- mcli/ml/dashboard/app.py +122 -130
- mcli/ml/dashboard/app_integrated.py +216 -150
- mcli/ml/dashboard/app_supabase.py +176 -108
- mcli/ml/dashboard/app_training.py +212 -206
- mcli/ml/dashboard/cli.py +14 -5
- mcli/ml/data_ingestion/api_connectors.py +51 -81
- mcli/ml/data_ingestion/data_pipeline.py +127 -125
- mcli/ml/data_ingestion/stream_processor.py +72 -80
- mcli/ml/database/migrations/env.py +3 -2
- mcli/ml/database/models.py +112 -79
- mcli/ml/database/session.py +6 -5
- mcli/ml/experimentation/ab_testing.py +149 -99
- mcli/ml/features/ensemble_features.py +9 -8
- mcli/ml/features/political_features.py +6 -5
- mcli/ml/features/recommendation_engine.py +15 -14
- mcli/ml/features/stock_features.py +7 -6
- mcli/ml/features/test_feature_engineering.py +8 -7
- mcli/ml/logging.py +10 -15
- mcli/ml/mlops/data_versioning.py +57 -64
- mcli/ml/mlops/experiment_tracker.py +49 -41
- mcli/ml/mlops/model_serving.py +59 -62
- mcli/ml/mlops/pipeline_orchestrator.py +203 -149
- mcli/ml/models/base_models.py +8 -7
- mcli/ml/models/ensemble_models.py +6 -5
- mcli/ml/models/recommendation_models.py +7 -6
- mcli/ml/models/test_models.py +18 -14
- mcli/ml/monitoring/drift_detection.py +95 -74
- mcli/ml/monitoring/metrics.py +10 -22
- mcli/ml/optimization/portfolio_optimizer.py +172 -132
- mcli/ml/predictions/prediction_engine.py +62 -50
- mcli/ml/preprocessing/data_cleaners.py +6 -5
- mcli/ml/preprocessing/feature_extractors.py +7 -6
- mcli/ml/preprocessing/ml_pipeline.py +3 -2
- mcli/ml/preprocessing/politician_trading_preprocessor.py +11 -10
- mcli/ml/preprocessing/test_preprocessing.py +4 -4
- mcli/ml/scripts/populate_sample_data.py +36 -16
- mcli/ml/tasks.py +82 -83
- mcli/ml/tests/test_integration.py +86 -76
- mcli/ml/tests/test_training_dashboard.py +169 -142
- mcli/mygroup/test_cmd.py +2 -1
- mcli/self/self_cmd.py +31 -16
- mcli/self/test_cmd.py +2 -1
- mcli/workflow/dashboard/dashboard_cmd.py +13 -6
- mcli/workflow/lsh_integration.py +46 -58
- mcli/workflow/politician_trading/commands.py +576 -427
- mcli/workflow/politician_trading/config.py +7 -7
- mcli/workflow/politician_trading/connectivity.py +35 -33
- mcli/workflow/politician_trading/data_sources.py +72 -71
- mcli/workflow/politician_trading/database.py +18 -16
- mcli/workflow/politician_trading/demo.py +4 -3
- mcli/workflow/politician_trading/models.py +5 -5
- mcli/workflow/politician_trading/monitoring.py +13 -13
- mcli/workflow/politician_trading/scrapers.py +332 -224
- mcli/workflow/politician_trading/scrapers_california.py +116 -94
- mcli/workflow/politician_trading/scrapers_eu.py +70 -71
- mcli/workflow/politician_trading/scrapers_uk.py +118 -90
- mcli/workflow/politician_trading/scrapers_us_states.py +125 -92
- mcli/workflow/politician_trading/workflow.py +98 -71
- {mcli_framework-7.1.1.dist-info → mcli_framework-7.1.2.dist-info}/METADATA +1 -1
- {mcli_framework-7.1.1.dist-info → mcli_framework-7.1.2.dist-info}/RECORD +94 -94
- {mcli_framework-7.1.1.dist-info → mcli_framework-7.1.2.dist-info}/WHEEL +0 -0
- {mcli_framework-7.1.1.dist-info → mcli_framework-7.1.2.dist-info}/entry_points.txt +0 -0
- {mcli_framework-7.1.1.dist-info → mcli_framework-7.1.2.dist-info}/licenses/LICENSE +0 -0
- {mcli_framework-7.1.1.dist-info → mcli_framework-7.1.2.dist-info}/top_level.txt +0 -0
mcli/workflow/lsh_integration.py
CHANGED
|
@@ -8,23 +8,22 @@ import json
|
|
|
8
8
|
import os
|
|
9
9
|
import sys
|
|
10
10
|
from pathlib import Path
|
|
11
|
-
from typing import
|
|
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
|
-
|
|
25
|
-
help="
|
|
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(
|
|
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(
|
|
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[
|
|
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(
|
|
89
|
-
name = job.get(
|
|
90
|
-
job_status = job.get(
|
|
91
|
-
job_type = job.get(
|
|
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
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}.get(job_status,
|
|
92
|
+
"running": "green",
|
|
93
|
+
"completed": "blue",
|
|
94
|
+
"failed": "red",
|
|
95
|
+
"pending": "yellow",
|
|
96
|
+
}.get(job_status, "white")
|
|
99
97
|
|
|
100
|
-
mcli.echo(
|
|
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(
|
|
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,
|
|
307
|
+
with open(env_file, "r") as f:
|
|
320
308
|
for line in f:
|
|
321
|
-
if
|
|
322
|
-
key, value = line.strip().split(
|
|
309
|
+
if "=" in line:
|
|
310
|
+
key, value = line.strip().split("=", 1)
|
|
323
311
|
config[key] = value
|
|
324
312
|
|
|
325
|
-
config[
|
|
313
|
+
config["LSH_API_URL"] = set_url
|
|
326
314
|
|
|
327
|
-
with open(env_file,
|
|
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,
|
|
325
|
+
with open(env_file, "r") as f:
|
|
338
326
|
for line in f:
|
|
339
|
-
if
|
|
340
|
-
key, value = line.strip().split(
|
|
327
|
+
if "=" in line:
|
|
328
|
+
key, value = line.strip().split("=", 1)
|
|
341
329
|
config[key] = value
|
|
342
330
|
|
|
343
|
-
config[
|
|
331
|
+
config["LSH_API_KEY"] = set_api_key
|
|
344
332
|
|
|
345
|
-
with open(env_file,
|
|
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
|