mcli-framework 7.12.2__py3-none-any.whl → 7.12.4__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/__init__.py +0 -2
- mcli/app/commands_cmd.py +30 -26
- mcli/app/completion_helpers.py +5 -5
- mcli/app/init_cmd.py +10 -10
- mcli/app/lock_cmd.py +29 -24
- mcli/app/main.py +2 -8
- mcli/app/model/model.py +5 -10
- mcli/app/store_cmd.py +8 -8
- mcli/app/video/__init__.py +0 -2
- mcli/app/video/video.py +1 -14
- mcli/chat/chat.py +90 -108
- mcli/chat/command_rag.py +0 -4
- mcli/chat/enhanced_chat.py +32 -41
- mcli/chat/system_controller.py +37 -37
- mcli/chat/system_integration.py +4 -5
- mcli/cli.py +2 -3
- mcli/lib/api/api.py +4 -9
- mcli/lib/api/daemon_client.py +19 -20
- mcli/lib/api/daemon_client_local.py +1 -3
- mcli/lib/api/daemon_decorator.py +6 -6
- mcli/lib/api/mcli_decorators.py +4 -8
- mcli/lib/auth/__init__.py +0 -1
- mcli/lib/auth/auth.py +4 -5
- mcli/lib/auth/mcli_manager.py +7 -12
- mcli/lib/auth/token_util.py +5 -5
- mcli/lib/config/__init__.py +29 -1
- mcli/lib/config/config.py +0 -1
- mcli/lib/custom_commands.py +1 -1
- mcli/lib/discovery/command_discovery.py +15 -15
- mcli/lib/erd/erd.py +7 -7
- mcli/lib/files/files.py +1 -1
- mcli/lib/fs/__init__.py +31 -1
- mcli/lib/fs/fs.py +12 -13
- mcli/lib/lib.py +0 -1
- mcli/lib/logger/logger.py +7 -10
- mcli/lib/performance/optimizer.py +25 -27
- mcli/lib/performance/rust_bridge.py +22 -27
- mcli/lib/performance/uvloop_config.py +0 -1
- mcli/lib/pickles/__init__.py +0 -1
- mcli/lib/pickles/pickles.py +0 -2
- mcli/lib/secrets/commands.py +0 -2
- mcli/lib/secrets/manager.py +0 -1
- mcli/lib/secrets/repl.py +2 -3
- mcli/lib/secrets/store.py +1 -2
- mcli/lib/services/data_pipeline.py +34 -34
- mcli/lib/services/lsh_client.py +38 -40
- mcli/lib/shell/shell.py +2 -2
- mcli/lib/toml/__init__.py +0 -1
- mcli/lib/ui/styling.py +0 -1
- mcli/lib/ui/visual_effects.py +33 -41
- mcli/lib/watcher/watcher.py +0 -1
- mcli/ml/__init__.py +1 -1
- mcli/ml/api/__init__.py +1 -1
- mcli/ml/api/app.py +8 -9
- mcli/ml/api/middleware.py +10 -10
- mcli/ml/api/routers/__init__.py +1 -1
- mcli/ml/api/routers/admin_router.py +3 -3
- mcli/ml/api/routers/auth_router.py +17 -18
- mcli/ml/api/routers/backtest_router.py +2 -2
- mcli/ml/api/routers/data_router.py +2 -2
- mcli/ml/api/routers/model_router.py +14 -15
- mcli/ml/api/routers/monitoring_router.py +2 -2
- mcli/ml/api/routers/portfolio_router.py +2 -2
- mcli/ml/api/routers/prediction_router.py +10 -9
- mcli/ml/api/routers/trade_router.py +2 -2
- mcli/ml/api/routers/websocket_router.py +6 -7
- mcli/ml/api/schemas.py +2 -2
- mcli/ml/auth/__init__.py +1 -1
- mcli/ml/auth/auth_manager.py +22 -23
- mcli/ml/auth/models.py +17 -17
- mcli/ml/auth/permissions.py +17 -17
- mcli/ml/backtesting/__init__.py +1 -1
- mcli/ml/backtesting/backtest_engine.py +31 -35
- mcli/ml/backtesting/performance_metrics.py +12 -14
- mcli/ml/backtesting/run.py +1 -2
- mcli/ml/cache.py +35 -36
- mcli/ml/cli/__init__.py +1 -1
- mcli/ml/cli/main.py +21 -24
- mcli/ml/config/__init__.py +1 -1
- mcli/ml/config/settings.py +28 -29
- mcli/ml/configs/__init__.py +1 -1
- mcli/ml/configs/dvc_config.py +14 -15
- mcli/ml/configs/mlflow_config.py +12 -13
- mcli/ml/configs/mlops_manager.py +19 -21
- mcli/ml/dashboard/__init__.py +4 -4
- mcli/ml/dashboard/app.py +20 -30
- mcli/ml/dashboard/app_supabase.py +16 -19
- mcli/ml/dashboard/app_training.py +11 -14
- mcli/ml/dashboard/cli.py +2 -2
- mcli/ml/dashboard/common.py +2 -3
- mcli/ml/dashboard/components/__init__.py +1 -1
- mcli/ml/dashboard/components/charts.py +13 -11
- mcli/ml/dashboard/components/metrics.py +7 -7
- mcli/ml/dashboard/components/tables.py +12 -9
- mcli/ml/dashboard/overview.py +2 -2
- mcli/ml/dashboard/pages/__init__.py +1 -1
- mcli/ml/dashboard/pages/cicd.py +15 -18
- mcli/ml/dashboard/pages/debug_dependencies.py +7 -7
- mcli/ml/dashboard/pages/monte_carlo_predictions.py +11 -18
- mcli/ml/dashboard/pages/predictions_enhanced.py +24 -32
- mcli/ml/dashboard/pages/scrapers_and_logs.py +22 -24
- mcli/ml/dashboard/pages/test_portfolio.py +3 -6
- mcli/ml/dashboard/pages/trading.py +16 -18
- mcli/ml/dashboard/pages/workflows.py +20 -30
- mcli/ml/dashboard/utils.py +9 -9
- mcli/ml/dashboard/warning_suppression.py +3 -3
- mcli/ml/data_ingestion/__init__.py +1 -1
- mcli/ml/data_ingestion/api_connectors.py +41 -46
- mcli/ml/data_ingestion/data_pipeline.py +36 -46
- mcli/ml/data_ingestion/stream_processor.py +43 -46
- mcli/ml/database/__init__.py +1 -1
- mcli/ml/database/migrations/env.py +2 -2
- mcli/ml/database/models.py +22 -24
- mcli/ml/database/session.py +14 -14
- mcli/ml/experimentation/__init__.py +1 -1
- mcli/ml/experimentation/ab_testing.py +45 -46
- mcli/ml/features/__init__.py +1 -1
- mcli/ml/features/ensemble_features.py +22 -27
- mcli/ml/features/recommendation_engine.py +30 -30
- mcli/ml/features/stock_features.py +29 -32
- mcli/ml/features/test_feature_engineering.py +10 -11
- mcli/ml/logging.py +4 -4
- mcli/ml/mlops/__init__.py +1 -1
- mcli/ml/mlops/data_versioning.py +29 -30
- mcli/ml/mlops/experiment_tracker.py +24 -24
- mcli/ml/mlops/model_serving.py +31 -34
- mcli/ml/mlops/pipeline_orchestrator.py +27 -35
- mcli/ml/models/__init__.py +5 -6
- mcli/ml/models/base_models.py +23 -23
- mcli/ml/models/ensemble_models.py +31 -31
- mcli/ml/models/recommendation_models.py +18 -19
- mcli/ml/models/test_models.py +14 -16
- mcli/ml/monitoring/__init__.py +1 -1
- mcli/ml/monitoring/drift_detection.py +32 -36
- mcli/ml/monitoring/metrics.py +2 -2
- mcli/ml/optimization/__init__.py +1 -1
- mcli/ml/optimization/optimize.py +1 -2
- mcli/ml/optimization/portfolio_optimizer.py +30 -32
- mcli/ml/predictions/__init__.py +1 -1
- mcli/ml/preprocessing/__init__.py +1 -1
- mcli/ml/preprocessing/data_cleaners.py +22 -23
- mcli/ml/preprocessing/feature_extractors.py +23 -26
- mcli/ml/preprocessing/ml_pipeline.py +23 -23
- mcli/ml/preprocessing/test_preprocessing.py +7 -8
- mcli/ml/scripts/populate_sample_data.py +0 -4
- mcli/ml/serving/serve.py +1 -2
- mcli/ml/tasks.py +17 -17
- mcli/ml/tests/test_integration.py +29 -30
- mcli/ml/tests/test_training_dashboard.py +21 -21
- mcli/ml/trading/__init__.py +1 -1
- mcli/ml/trading/migrations.py +5 -5
- mcli/ml/trading/models.py +21 -23
- mcli/ml/trading/paper_trading.py +16 -13
- mcli/ml/trading/risk_management.py +17 -18
- mcli/ml/trading/trading_service.py +25 -28
- mcli/ml/training/__init__.py +1 -1
- mcli/ml/training/train.py +0 -1
- mcli/public/oi/oi.py +1 -2
- mcli/self/completion_cmd.py +6 -10
- mcli/self/logs_cmd.py +19 -24
- mcli/self/migrate_cmd.py +22 -20
- mcli/self/redis_cmd.py +10 -11
- mcli/self/self_cmd.py +10 -18
- mcli/self/store_cmd.py +10 -12
- mcli/self/visual_cmd.py +9 -14
- mcli/self/zsh_cmd.py +2 -4
- mcli/workflow/daemon/async_command_database.py +23 -24
- mcli/workflow/daemon/async_process_manager.py +27 -29
- mcli/workflow/daemon/client.py +27 -33
- mcli/workflow/daemon/daemon.py +32 -36
- mcli/workflow/daemon/enhanced_daemon.py +24 -33
- mcli/workflow/daemon/process_cli.py +11 -12
- mcli/workflow/daemon/process_manager.py +23 -26
- mcli/workflow/daemon/test_daemon.py +4 -5
- mcli/workflow/dashboard/dashboard_cmd.py +0 -1
- mcli/workflow/doc_convert.py +15 -17
- mcli/workflow/gcloud/__init__.py +0 -1
- mcli/workflow/gcloud/gcloud.py +11 -8
- mcli/workflow/git_commit/ai_service.py +14 -15
- mcli/workflow/lsh_integration.py +9 -11
- mcli/workflow/model_service/client.py +26 -31
- mcli/workflow/model_service/download_and_run_efficient_models.py +10 -14
- mcli/workflow/model_service/lightweight_embedder.py +25 -35
- mcli/workflow/model_service/lightweight_model_server.py +26 -32
- mcli/workflow/model_service/lightweight_test.py +7 -10
- mcli/workflow/model_service/model_service.py +80 -91
- mcli/workflow/model_service/ollama_efficient_runner.py +14 -18
- mcli/workflow/model_service/openai_adapter.py +23 -23
- mcli/workflow/model_service/pdf_processor.py +21 -26
- mcli/workflow/model_service/test_efficient_runner.py +12 -16
- mcli/workflow/model_service/test_example.py +11 -13
- mcli/workflow/model_service/test_integration.py +3 -5
- mcli/workflow/model_service/test_new_features.py +7 -8
- mcli/workflow/notebook/converter.py +1 -1
- mcli/workflow/notebook/notebook_cmd.py +5 -6
- mcli/workflow/notebook/schema.py +0 -1
- mcli/workflow/notebook/validator.py +7 -3
- mcli/workflow/openai/openai.py +1 -2
- mcli/workflow/registry/registry.py +4 -1
- mcli/workflow/repo/repo.py +6 -7
- mcli/workflow/scheduler/cron_parser.py +16 -19
- mcli/workflow/scheduler/job.py +10 -10
- mcli/workflow/scheduler/monitor.py +15 -15
- mcli/workflow/scheduler/persistence.py +17 -18
- mcli/workflow/scheduler/scheduler.py +37 -38
- mcli/workflow/secrets/__init__.py +1 -1
- mcli/workflow/sync/test_cmd.py +0 -1
- mcli/workflow/wakatime/__init__.py +5 -9
- mcli/workflow/wakatime/wakatime.py +1 -2
- {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/METADATA +1 -1
- mcli_framework-7.12.4.dist-info/RECORD +279 -0
- mcli_framework-7.12.2.dist-info/RECORD +0 -279
- {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/WHEEL +0 -0
- {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/entry_points.txt +0 -0
- {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/licenses/LICENSE +0 -0
- {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/top_level.txt +0 -0
mcli/ml/configs/dvc_config.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
"""DVC Configuration for Data Versioning and Pipeline Management"""
|
|
1
|
+
"""DVC Configuration for Data Versioning and Pipeline Management."""
|
|
2
2
|
|
|
3
|
-
import os
|
|
4
3
|
import subprocess
|
|
5
4
|
from pathlib import Path
|
|
6
5
|
from typing import Any, Dict, List, Optional
|
|
@@ -9,7 +8,7 @@ import yaml
|
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
class DVCConfig:
|
|
12
|
-
"""Configuration class for DVC data versioning and pipeline management"""
|
|
11
|
+
"""Configuration class for DVC data versioning and pipeline management."""
|
|
13
12
|
|
|
14
13
|
def __init__(self, project_root: Optional[Path] = None):
|
|
15
14
|
self.project_root = project_root or Path(__file__).parent.parent.parent.parent.parent
|
|
@@ -18,7 +17,7 @@ class DVCConfig:
|
|
|
18
17
|
self.models_dir = self.project_root / "models"
|
|
19
18
|
|
|
20
19
|
def setup_data_directories(self) -> None:
|
|
21
|
-
"""Create and configure data directories for DVC tracking"""
|
|
20
|
+
"""Create and configure data directories for DVC tracking."""
|
|
22
21
|
directories = [
|
|
23
22
|
self.data_dir / "raw",
|
|
24
23
|
self.data_dir / "processed",
|
|
@@ -33,7 +32,7 @@ class DVCConfig:
|
|
|
33
32
|
print(f"Created directory: {directory}")
|
|
34
33
|
|
|
35
34
|
def add_data_to_dvc(self, data_path: Path, message: Optional[str] = None) -> None:
|
|
36
|
-
"""Add data file or directory to DVC tracking"""
|
|
35
|
+
"""Add data file or directory to DVC tracking."""
|
|
37
36
|
try:
|
|
38
37
|
# Add to DVC
|
|
39
38
|
cmd = ["dvc", "add", str(data_path)]
|
|
@@ -64,7 +63,7 @@ class DVCConfig:
|
|
|
64
63
|
parameters: Optional[Dict[str, Any]] = None,
|
|
65
64
|
metrics: Optional[List[str]] = None,
|
|
66
65
|
) -> None:
|
|
67
|
-
"""Create a DVC pipeline stage"""
|
|
66
|
+
"""Create a DVC pipeline stage."""
|
|
68
67
|
try:
|
|
69
68
|
cmd = [
|
|
70
69
|
"dvc",
|
|
@@ -99,7 +98,7 @@ class DVCConfig:
|
|
|
99
98
|
raise
|
|
100
99
|
|
|
101
100
|
def run_pipeline(self, stage_name: Optional[str] = None) -> None:
|
|
102
|
-
"""Run DVC pipeline or specific stage"""
|
|
101
|
+
"""Run DVC pipeline or specific stage."""
|
|
103
102
|
try:
|
|
104
103
|
cmd = ["dvc", "repro"]
|
|
105
104
|
if stage_name:
|
|
@@ -110,7 +109,7 @@ class DVCConfig:
|
|
|
110
109
|
if result.returncode != 0:
|
|
111
110
|
raise Exception(f"DVC pipeline run failed: {result.stderr}")
|
|
112
111
|
|
|
113
|
-
print(
|
|
112
|
+
print("DVC pipeline completed successfully")
|
|
114
113
|
if result.stdout:
|
|
115
114
|
print(result.stdout)
|
|
116
115
|
|
|
@@ -119,7 +118,7 @@ class DVCConfig:
|
|
|
119
118
|
raise
|
|
120
119
|
|
|
121
120
|
def get_data_version(self, data_path: Path) -> Optional[str]:
|
|
122
|
-
"""Get the current version hash of a data file"""
|
|
121
|
+
"""Get the current version hash of a data file."""
|
|
123
122
|
try:
|
|
124
123
|
dvc_file = data_path.with_suffix(data_path.suffix + ".dvc")
|
|
125
124
|
if not dvc_file.exists():
|
|
@@ -134,7 +133,7 @@ class DVCConfig:
|
|
|
134
133
|
return None
|
|
135
134
|
|
|
136
135
|
def pull_data(self, path: Optional[str] = None) -> None:
|
|
137
|
-
"""Pull data from DVC remote storage"""
|
|
136
|
+
"""Pull data from DVC remote storage."""
|
|
138
137
|
try:
|
|
139
138
|
cmd = ["dvc", "pull"]
|
|
140
139
|
if path:
|
|
@@ -152,7 +151,7 @@ class DVCConfig:
|
|
|
152
151
|
raise
|
|
153
152
|
|
|
154
153
|
def push_data(self, path: Optional[str] = None) -> None:
|
|
155
|
-
"""Push data to DVC remote storage"""
|
|
154
|
+
"""Push data to DVC remote storage."""
|
|
156
155
|
try:
|
|
157
156
|
cmd = ["dvc", "push"]
|
|
158
157
|
if path:
|
|
@@ -172,7 +171,7 @@ class DVCConfig:
|
|
|
172
171
|
def configure_remote_storage(
|
|
173
172
|
self, remote_name: str, storage_url: str, default: bool = True
|
|
174
173
|
) -> None:
|
|
175
|
-
"""Configure DVC remote storage"""
|
|
174
|
+
"""Configure DVC remote storage."""
|
|
176
175
|
try:
|
|
177
176
|
# Add remote
|
|
178
177
|
cmd = ["dvc", "remote", "add", remote_name, storage_url]
|
|
@@ -193,7 +192,7 @@ class DVCConfig:
|
|
|
193
192
|
raise
|
|
194
193
|
|
|
195
194
|
def get_pipeline_status(self) -> Dict[str, Any]:
|
|
196
|
-
"""Get status of DVC pipeline"""
|
|
195
|
+
"""Get status of DVC pipeline."""
|
|
197
196
|
try:
|
|
198
197
|
cmd = ["dvc", "status"]
|
|
199
198
|
result = subprocess.run(cmd, capture_output=True, text=True, cwd=self.project_root)
|
|
@@ -214,12 +213,12 @@ dvc_config = DVCConfig()
|
|
|
214
213
|
|
|
215
214
|
|
|
216
215
|
def get_dvc_config() -> DVCConfig:
|
|
217
|
-
"""Get the global DVC configuration instance"""
|
|
216
|
+
"""Get the global DVC configuration instance."""
|
|
218
217
|
return dvc_config
|
|
219
218
|
|
|
220
219
|
|
|
221
220
|
def setup_dvc() -> None:
|
|
222
|
-
"""Setup DVC data directories and configuration"""
|
|
221
|
+
"""Setup DVC data directories and configuration."""
|
|
223
222
|
dvc_config.setup_data_directories()
|
|
224
223
|
print(f"DVC project root: {dvc_config.project_root}")
|
|
225
224
|
print(f"Data directory: {dvc_config.data_dir}")
|
mcli/ml/configs/mlflow_config.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
"""MLflow Configuration for Stock Recommendation System"""
|
|
1
|
+
"""MLflow Configuration for Stock Recommendation System."""
|
|
2
2
|
|
|
3
|
-
import os
|
|
4
3
|
from pathlib import Path
|
|
5
4
|
from typing import Any, Dict, Optional
|
|
6
5
|
|
|
@@ -9,7 +8,7 @@ from mlflow.tracking import MlflowClient
|
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
class MLflowConfig:
|
|
12
|
-
"""Configuration class for MLflow tracking and model registry"""
|
|
11
|
+
"""Configuration class for MLflow tracking and model registry."""
|
|
13
12
|
|
|
14
13
|
def __init__(
|
|
15
14
|
self,
|
|
@@ -23,17 +22,17 @@ class MLflowConfig:
|
|
|
23
22
|
self._client = None
|
|
24
23
|
|
|
25
24
|
def _default_tracking_uri(self) -> str:
|
|
26
|
-
"""Get default MLflow tracking URI"""
|
|
25
|
+
"""Get default MLflow tracking URI."""
|
|
27
26
|
project_root = Path(__file__).parent.parent.parent.parent.parent
|
|
28
27
|
return f"file://{project_root}/mlruns"
|
|
29
28
|
|
|
30
29
|
def _default_artifact_root(self) -> str:
|
|
31
|
-
"""Get default artifact storage location"""
|
|
30
|
+
"""Get default artifact storage location."""
|
|
32
31
|
project_root = Path(__file__).parent.parent.parent.parent.parent
|
|
33
32
|
return f"{project_root}/artifacts"
|
|
34
33
|
|
|
35
34
|
def setup_tracking(self) -> None:
|
|
36
|
-
"""Initialize MLflow tracking configuration"""
|
|
35
|
+
"""Initialize MLflow tracking configuration."""
|
|
37
36
|
mlflow.set_tracking_uri(self.tracking_uri)
|
|
38
37
|
|
|
39
38
|
# Create or get experiment
|
|
@@ -56,17 +55,17 @@ class MLflowConfig:
|
|
|
56
55
|
|
|
57
56
|
@property
|
|
58
57
|
def client(self) -> MlflowClient:
|
|
59
|
-
"""Get MLflow client instance"""
|
|
58
|
+
"""Get MLflow client instance."""
|
|
60
59
|
if self._client is None:
|
|
61
60
|
self._client = MlflowClient(tracking_uri=self.tracking_uri)
|
|
62
61
|
return self._client
|
|
63
62
|
|
|
64
63
|
def get_model_registry_uri(self) -> str:
|
|
65
|
-
"""Get model registry URI"""
|
|
64
|
+
"""Get model registry URI."""
|
|
66
65
|
return self.tracking_uri
|
|
67
66
|
|
|
68
67
|
def log_model_metadata(self, run_id: str, metadata: Dict[str, Any]) -> None:
|
|
69
|
-
"""Log additional metadata for a model"""
|
|
68
|
+
"""Log additional metadata for a model."""
|
|
70
69
|
for key, value in metadata.items():
|
|
71
70
|
self.client.log_param(run_id, key, value)
|
|
72
71
|
|
|
@@ -77,7 +76,7 @@ class MLflowConfig:
|
|
|
77
76
|
tags: Optional[Dict[str, str]] = None,
|
|
78
77
|
description: Optional[str] = None,
|
|
79
78
|
) -> None:
|
|
80
|
-
"""Register a model in MLflow Model Registry"""
|
|
79
|
+
"""Register a model in MLflow Model Registry."""
|
|
81
80
|
try:
|
|
82
81
|
model_version = mlflow.register_model(model_uri=model_uri, name=model_name, tags=tags)
|
|
83
82
|
|
|
@@ -96,7 +95,7 @@ class MLflowConfig:
|
|
|
96
95
|
def transition_model_stage(
|
|
97
96
|
self, model_name: str, version: str, stage: str, archive_existing_versions: bool = False
|
|
98
97
|
) -> None:
|
|
99
|
-
"""Transition model to a different stage"""
|
|
98
|
+
"""Transition model to a different stage."""
|
|
100
99
|
try:
|
|
101
100
|
self.client.transition_model_version_stage(
|
|
102
101
|
name=model_name,
|
|
@@ -116,12 +115,12 @@ mlflow_config = MLflowConfig()
|
|
|
116
115
|
|
|
117
116
|
|
|
118
117
|
def get_mlflow_config() -> MLflowConfig:
|
|
119
|
-
"""Get the global MLflow configuration instance"""
|
|
118
|
+
"""Get the global MLflow configuration instance."""
|
|
120
119
|
return mlflow_config
|
|
121
120
|
|
|
122
121
|
|
|
123
122
|
def setup_mlflow() -> None:
|
|
124
|
-
"""Setup MLflow tracking and experiment"""
|
|
123
|
+
"""Setup MLflow tracking and experiment."""
|
|
125
124
|
mlflow_config.setup_tracking()
|
|
126
125
|
print(f"MLflow tracking URI: {mlflow_config.tracking_uri}")
|
|
127
126
|
print(f"Artifact root: {mlflow_config.artifact_root}")
|
mcli/ml/configs/mlops_manager.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
"""Unified MLOps Manager for Stock Recommendation System"""
|
|
1
|
+
"""Unified MLOps Manager for Stock Recommendation System."""
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
|
-
import os
|
|
5
4
|
import pickle
|
|
6
5
|
from datetime import datetime
|
|
7
6
|
from pathlib import Path
|
|
@@ -11,14 +10,13 @@ import joblib
|
|
|
11
10
|
import mlflow
|
|
12
11
|
import mlflow.pytorch
|
|
13
12
|
import mlflow.sklearn
|
|
14
|
-
from mlflow.tracking import MlflowClient
|
|
15
13
|
|
|
16
14
|
from .dvc_config import DVCConfig, get_dvc_config
|
|
17
15
|
from .mlflow_config import MLflowConfig, get_mlflow_config
|
|
18
16
|
|
|
19
17
|
|
|
20
18
|
class MLOpsManager:
|
|
21
|
-
"""Unified manager for MLflow and DVC operations"""
|
|
19
|
+
"""Unified manager for MLflow and DVC operations."""
|
|
22
20
|
|
|
23
21
|
def __init__(
|
|
24
22
|
self, mlflow_config: Optional[MLflowConfig] = None, dvc_config: Optional[DVCConfig] = None
|
|
@@ -28,7 +26,7 @@ class MLOpsManager:
|
|
|
28
26
|
self._setup_completed = False
|
|
29
27
|
|
|
30
28
|
def setup(self) -> None:
|
|
31
|
-
"""Initialize MLOps infrastructure"""
|
|
29
|
+
"""Initialize MLOps infrastructure."""
|
|
32
30
|
if self._setup_completed:
|
|
33
31
|
return
|
|
34
32
|
|
|
@@ -49,7 +47,7 @@ class MLOpsManager:
|
|
|
49
47
|
tags: Optional[Dict[str, str]] = None,
|
|
50
48
|
description: Optional[str] = None,
|
|
51
49
|
) -> str:
|
|
52
|
-
"""Start a new MLflow experiment run"""
|
|
50
|
+
"""Start a new MLflow experiment run."""
|
|
53
51
|
if not self._setup_completed:
|
|
54
52
|
self.setup()
|
|
55
53
|
|
|
@@ -62,17 +60,17 @@ class MLOpsManager:
|
|
|
62
60
|
return run.info.run_id
|
|
63
61
|
|
|
64
62
|
def log_parameters(self, params: Dict[str, Any]) -> None:
|
|
65
|
-
"""Log parameters to MLflow"""
|
|
63
|
+
"""Log parameters to MLflow."""
|
|
66
64
|
for key, value in params.items():
|
|
67
65
|
mlflow.log_param(key, value)
|
|
68
66
|
|
|
69
67
|
def log_metrics(self, metrics: Dict[str, float], step: Optional[int] = None) -> None:
|
|
70
|
-
"""Log metrics to MLflow"""
|
|
68
|
+
"""Log metrics to MLflow."""
|
|
71
69
|
for key, value in metrics.items():
|
|
72
70
|
mlflow.log_metric(key, value, step=step)
|
|
73
71
|
|
|
74
72
|
def log_artifacts(self, artifact_path: Path, artifact_name: Optional[str] = None) -> None:
|
|
75
|
-
"""Log artifacts to MLflow"""
|
|
73
|
+
"""Log artifacts to MLflow."""
|
|
76
74
|
if artifact_path.is_file():
|
|
77
75
|
mlflow.log_artifact(str(artifact_path), artifact_name)
|
|
78
76
|
else:
|
|
@@ -87,7 +85,7 @@ class MLOpsManager:
|
|
|
87
85
|
input_example: Optional[Any] = None,
|
|
88
86
|
metadata: Optional[Dict[str, Any]] = None,
|
|
89
87
|
) -> str:
|
|
90
|
-
"""Save model locally and log to MLflow"""
|
|
88
|
+
"""Save model locally and log to MLflow."""
|
|
91
89
|
# Create model directory
|
|
92
90
|
model_dir = self.dvc_config.models_dir / model_type / model_name
|
|
93
91
|
model_dir.mkdir(parents=True, exist_ok=True)
|
|
@@ -149,7 +147,7 @@ class MLOpsManager:
|
|
|
149
147
|
description: Optional[str] = None,
|
|
150
148
|
tags: Optional[Dict[str, str]] = None,
|
|
151
149
|
) -> str:
|
|
152
|
-
"""Register model in MLflow Model Registry"""
|
|
150
|
+
"""Register model in MLflow Model Registry."""
|
|
153
151
|
# Get the current run
|
|
154
152
|
run = mlflow.active_run()
|
|
155
153
|
if not run:
|
|
@@ -173,7 +171,7 @@ class MLOpsManager:
|
|
|
173
171
|
def load_model(
|
|
174
172
|
self, model_name: str, version: Optional[str] = None, stage: Optional[str] = None
|
|
175
173
|
) -> Any:
|
|
176
|
-
"""Load model from MLflow Model Registry"""
|
|
174
|
+
"""Load model from MLflow Model Registry."""
|
|
177
175
|
if version:
|
|
178
176
|
model_uri = f"models:/{model_name}/{version}"
|
|
179
177
|
elif stage:
|
|
@@ -184,11 +182,11 @@ class MLOpsManager:
|
|
|
184
182
|
return mlflow.pytorch.load_model(model_uri)
|
|
185
183
|
|
|
186
184
|
def end_run(self, status: str = "FINISHED") -> None:
|
|
187
|
-
"""End the current MLflow run"""
|
|
185
|
+
"""End the current MLflow run."""
|
|
188
186
|
mlflow.end_run(status=status)
|
|
189
187
|
|
|
190
188
|
def version_data(self, data_path: Path, message: Optional[str] = None) -> str:
|
|
191
|
-
"""Version data using DVC"""
|
|
189
|
+
"""Version data using DVC."""
|
|
192
190
|
self.dvc_config.add_data_to_dvc(data_path, message)
|
|
193
191
|
return self.dvc_config.get_data_version(data_path) or "unknown"
|
|
194
192
|
|
|
@@ -200,7 +198,7 @@ class MLOpsManager:
|
|
|
200
198
|
outputs: List[str],
|
|
201
199
|
parameters: Optional[List[str]] = None,
|
|
202
200
|
) -> None:
|
|
203
|
-
"""Create a DVC pipeline stage for ML workflow"""
|
|
201
|
+
"""Create a DVC pipeline stage for ML workflow."""
|
|
204
202
|
command = f"python {script_path}"
|
|
205
203
|
|
|
206
204
|
self.dvc_config.create_pipeline_stage(
|
|
@@ -212,11 +210,11 @@ class MLOpsManager:
|
|
|
212
210
|
)
|
|
213
211
|
|
|
214
212
|
def run_ml_pipeline(self, stage_name: Optional[str] = None) -> None:
|
|
215
|
-
"""Run DVC ML pipeline"""
|
|
213
|
+
"""Run DVC ML pipeline."""
|
|
216
214
|
self.dvc_config.run_pipeline(stage_name)
|
|
217
215
|
|
|
218
216
|
def get_experiment_metrics(self, experiment_name: str) -> List[Dict[str, Any]]:
|
|
219
|
-
"""Get metrics from all runs in an experiment"""
|
|
217
|
+
"""Get metrics from all runs in an experiment."""
|
|
220
218
|
experiment = mlflow.get_experiment_by_name(experiment_name)
|
|
221
219
|
if not experiment:
|
|
222
220
|
return []
|
|
@@ -227,7 +225,7 @@ class MLOpsManager:
|
|
|
227
225
|
def compare_models(
|
|
228
226
|
self, model_names: List[str], metric_name: str = "accuracy"
|
|
229
227
|
) -> Dict[str, Any]:
|
|
230
|
-
"""Compare models by a specific metric"""
|
|
228
|
+
"""Compare models by a specific metric."""
|
|
231
229
|
comparison = {}
|
|
232
230
|
|
|
233
231
|
for model_name in model_names:
|
|
@@ -252,13 +250,13 @@ class MLOpsManager:
|
|
|
252
250
|
return comparison
|
|
253
251
|
|
|
254
252
|
def cleanup_old_runs(self, days_old: int = 30) -> None:
|
|
255
|
-
"""Clean up old experiment runs"""
|
|
253
|
+
"""Clean up old experiment runs."""
|
|
256
254
|
# This would implement cleanup logic for old runs
|
|
257
255
|
# For now, just a placeholder
|
|
258
256
|
print(f"Cleanup of runs older than {days_old} days would be implemented here")
|
|
259
257
|
|
|
260
258
|
def get_system_info(self) -> Dict[str, Any]:
|
|
261
|
-
"""Get MLOps system information"""
|
|
259
|
+
"""Get MLOps system information."""
|
|
262
260
|
return {
|
|
263
261
|
"mlflow_tracking_uri": self.mlflow_config.tracking_uri,
|
|
264
262
|
"mlflow_experiment": self.mlflow_config.experiment_name,
|
|
@@ -275,7 +273,7 @@ mlops_manager = MLOpsManager()
|
|
|
275
273
|
|
|
276
274
|
|
|
277
275
|
def get_mlops_manager() -> MLOpsManager:
|
|
278
|
-
"""Get the global MLOps manager instance"""
|
|
276
|
+
"""Get the global MLOps manager instance."""
|
|
279
277
|
return mlops_manager
|
|
280
278
|
|
|
281
279
|
|
mcli/ml/dashboard/__init__.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
"""ML Dashboard for real-time monitoring"""
|
|
1
|
+
"""ML Dashboard for real-time monitoring."""
|
|
2
2
|
|
|
3
|
-
from .app import main
|
|
3
|
+
from .app import main as app_main
|
|
4
4
|
from .cli import app as cli_app
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def main():
|
|
8
|
-
"""Main entry point for dashboard CLI"""
|
|
8
|
+
"""Main entry point for dashboard CLI."""
|
|
9
9
|
cli_app()
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
__all__ = ["main", "cli_app"]
|
|
12
|
+
__all__ = ["main", "cli_app", "app_main"]
|
mcli/ml/dashboard/app.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
"""Streamlit dashboard for ML system monitoring"""
|
|
1
|
+
"""Streamlit dashboard for ML system monitoring."""
|
|
2
2
|
|
|
3
|
-
import asyncio
|
|
4
3
|
import time
|
|
5
4
|
from datetime import datetime, timedelta
|
|
6
5
|
|
|
@@ -16,16 +15,7 @@ from mcli.ml.cache import cache_manager
|
|
|
16
15
|
from mcli.ml.config import settings
|
|
17
16
|
from mcli.ml.dashboard.common import setup_page_config
|
|
18
17
|
from mcli.ml.dashboard.styles import apply_dashboard_styles
|
|
19
|
-
from mcli.ml.database.models import
|
|
20
|
-
BacktestResult,
|
|
21
|
-
Model,
|
|
22
|
-
ModelStatus,
|
|
23
|
-
Portfolio,
|
|
24
|
-
Prediction,
|
|
25
|
-
StockData,
|
|
26
|
-
Trade,
|
|
27
|
-
User,
|
|
28
|
-
)
|
|
18
|
+
from mcli.ml.database.models import Model, ModelStatus, Portfolio, Prediction, User
|
|
29
19
|
from mcli.ml.database.session import SessionLocal
|
|
30
20
|
|
|
31
21
|
# Page config - must be first
|
|
@@ -37,7 +27,7 @@ apply_dashboard_styles()
|
|
|
37
27
|
|
|
38
28
|
@st.cache_data(ttl=30)
|
|
39
29
|
def get_system_metrics():
|
|
40
|
-
"""Get real-time system metrics"""
|
|
30
|
+
"""Get real-time system metrics."""
|
|
41
31
|
db = SessionLocal()
|
|
42
32
|
|
|
43
33
|
try:
|
|
@@ -62,7 +52,7 @@ def get_system_metrics():
|
|
|
62
52
|
)
|
|
63
53
|
|
|
64
54
|
# Portfolio metrics
|
|
65
|
-
active_portfolios = db.query(Portfolio).filter(Portfolio.is_active
|
|
55
|
+
active_portfolios = db.query(Portfolio).filter(Portfolio.is_active is True).count()
|
|
66
56
|
|
|
67
57
|
return {
|
|
68
58
|
"total_models": total_models,
|
|
@@ -80,7 +70,7 @@ def get_system_metrics():
|
|
|
80
70
|
|
|
81
71
|
@st.cache_data(ttl=60)
|
|
82
72
|
def get_model_performance():
|
|
83
|
-
"""Get model performance data"""
|
|
73
|
+
"""Get model performance data."""
|
|
84
74
|
db = SessionLocal()
|
|
85
75
|
|
|
86
76
|
try:
|
|
@@ -104,7 +94,7 @@ def get_model_performance():
|
|
|
104
94
|
|
|
105
95
|
@st.cache_data(ttl=30)
|
|
106
96
|
def get_recent_predictions():
|
|
107
|
-
"""Get recent predictions"""
|
|
97
|
+
"""Get recent predictions."""
|
|
108
98
|
db = SessionLocal()
|
|
109
99
|
|
|
110
100
|
try:
|
|
@@ -131,11 +121,11 @@ def get_recent_predictions():
|
|
|
131
121
|
|
|
132
122
|
@st.cache_data(ttl=60)
|
|
133
123
|
def get_portfolio_performance():
|
|
134
|
-
"""Get portfolio performance data"""
|
|
124
|
+
"""Get portfolio performance data."""
|
|
135
125
|
db = SessionLocal()
|
|
136
126
|
|
|
137
127
|
try:
|
|
138
|
-
portfolios = db.query(Portfolio).filter(Portfolio.is_active
|
|
128
|
+
portfolios = db.query(Portfolio).filter(Portfolio.is_active is True).all()
|
|
139
129
|
|
|
140
130
|
data = []
|
|
141
131
|
for portfolio in portfolios:
|
|
@@ -155,25 +145,25 @@ def get_portfolio_performance():
|
|
|
155
145
|
|
|
156
146
|
|
|
157
147
|
def check_api_health():
|
|
158
|
-
"""Check API health"""
|
|
148
|
+
"""Check API health."""
|
|
159
149
|
try:
|
|
160
150
|
response = requests.get(f"http://localhost:{settings.api.port}/health", timeout=5)
|
|
161
151
|
return response.status_code == 200
|
|
162
|
-
except:
|
|
152
|
+
except Exception:
|
|
163
153
|
return False
|
|
164
154
|
|
|
165
155
|
|
|
166
156
|
def check_redis_health():
|
|
167
|
-
"""Check Redis health"""
|
|
157
|
+
"""Check Redis health."""
|
|
168
158
|
try:
|
|
169
159
|
cache_manager.initialize()
|
|
170
160
|
return cache_manager.redis_client.ping() if cache_manager.redis_client else False
|
|
171
|
-
except:
|
|
161
|
+
except Exception:
|
|
172
162
|
return False
|
|
173
163
|
|
|
174
164
|
|
|
175
165
|
def main():
|
|
176
|
-
"""Main dashboard function"""
|
|
166
|
+
"""Main dashboard function."""
|
|
177
167
|
|
|
178
168
|
# Title and header
|
|
179
169
|
st.title("🤖 MCLI ML System Dashboard")
|
|
@@ -213,7 +203,7 @@ def main():
|
|
|
213
203
|
|
|
214
204
|
|
|
215
205
|
def show_overview():
|
|
216
|
-
"""Show overview dashboard"""
|
|
206
|
+
"""Show overview dashboard."""
|
|
217
207
|
st.header("System Overview")
|
|
218
208
|
|
|
219
209
|
# Get metrics
|
|
@@ -268,7 +258,7 @@ def show_overview():
|
|
|
268
258
|
|
|
269
259
|
|
|
270
260
|
def show_models():
|
|
271
|
-
"""Show models dashboard"""
|
|
261
|
+
"""Show models dashboard."""
|
|
272
262
|
st.header("Model Management")
|
|
273
263
|
|
|
274
264
|
# Model performance table
|
|
@@ -288,7 +278,7 @@ def show_models():
|
|
|
288
278
|
|
|
289
279
|
|
|
290
280
|
def show_predictions():
|
|
291
|
-
"""Show predictions dashboard"""
|
|
281
|
+
"""Show predictions dashboard."""
|
|
292
282
|
st.header("Predictions Analysis")
|
|
293
283
|
|
|
294
284
|
pred_data = get_recent_predictions()
|
|
@@ -347,7 +337,7 @@ def show_predictions():
|
|
|
347
337
|
|
|
348
338
|
|
|
349
339
|
def show_portfolios():
|
|
350
|
-
"""Show portfolios dashboard"""
|
|
340
|
+
"""Show portfolios dashboard."""
|
|
351
341
|
st.header("Portfolio Performance")
|
|
352
342
|
|
|
353
343
|
portfolio_data = get_portfolio_performance()
|
|
@@ -382,7 +372,7 @@ def show_portfolios():
|
|
|
382
372
|
|
|
383
373
|
|
|
384
374
|
def show_system_health():
|
|
385
|
-
"""Show system health dashboard"""
|
|
375
|
+
"""Show system health dashboard."""
|
|
386
376
|
st.header("System Health")
|
|
387
377
|
|
|
388
378
|
# Check various system components
|
|
@@ -438,7 +428,7 @@ def show_system_health():
|
|
|
438
428
|
|
|
439
429
|
|
|
440
430
|
def show_live_monitoring():
|
|
441
|
-
"""Show live monitoring with real-time updates"""
|
|
431
|
+
"""Show live monitoring with real-time updates."""
|
|
442
432
|
st.header("Live Monitoring")
|
|
443
433
|
|
|
444
434
|
# Real-time metrics placeholder
|
|
@@ -454,7 +444,7 @@ def show_live_monitoring():
|
|
|
454
444
|
|
|
455
445
|
# Auto-update every 5 seconds
|
|
456
446
|
if st.button("Start Live Monitoring"):
|
|
457
|
-
for
|
|
447
|
+
for _i in range(60): # Run for 5 minutes
|
|
458
448
|
# Update metrics
|
|
459
449
|
metrics = get_system_metrics()
|
|
460
450
|
with metrics_placeholder.container():
|