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/lib/ui/styling.py
CHANGED
mcli/lib/ui/visual_effects.py
CHANGED
|
@@ -3,18 +3,13 @@
|
|
|
3
3
|
Provides stunning visual elements, animations, and rich formatting for the CLI
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
-
import random
|
|
7
|
-
import sys
|
|
8
6
|
import threading
|
|
9
7
|
import time
|
|
10
|
-
from typing import Any, Dict
|
|
8
|
+
from typing import Any, Dict
|
|
11
9
|
|
|
12
10
|
from rich.align import Align
|
|
13
|
-
from rich.box import
|
|
14
|
-
from rich.columns import Columns
|
|
11
|
+
from rich.box import DOUBLE, HEAVY, ROUNDED
|
|
15
12
|
from rich.console import Console
|
|
16
|
-
from rich.live import Live
|
|
17
|
-
from rich.markdown import Markdown
|
|
18
13
|
from rich.panel import Panel
|
|
19
14
|
from rich.progress import (
|
|
20
15
|
BarColumn,
|
|
@@ -26,16 +21,14 @@ from rich.progress import (
|
|
|
26
21
|
TimeRemainingColumn,
|
|
27
22
|
)
|
|
28
23
|
from rich.rule import Rule
|
|
29
|
-
from rich.syntax import Syntax
|
|
30
24
|
from rich.table import Table
|
|
31
25
|
from rich.text import Text
|
|
32
|
-
from rich.tree import Tree
|
|
33
26
|
|
|
34
27
|
console = Console()
|
|
35
28
|
|
|
36
29
|
|
|
37
30
|
class MCLIBanner:
|
|
38
|
-
"""Stunning ASCII art banners for MCLI"""
|
|
31
|
+
"""Stunning ASCII art banners for MCLI."""
|
|
39
32
|
|
|
40
33
|
MAIN_BANNER = """
|
|
41
34
|
╔════════════════════════════════════════════════════════════════╗
|
|
@@ -78,7 +71,7 @@ class MCLIBanner:
|
|
|
78
71
|
|
|
79
72
|
@classmethod
|
|
80
73
|
def show_main_banner(cls, subtitle: str = "Powered by Rust"):
|
|
81
|
-
"""Display the main MCLI banner with gradient colors"""
|
|
74
|
+
"""Display the main MCLI banner with gradient colors."""
|
|
82
75
|
console.print()
|
|
83
76
|
|
|
84
77
|
# Create gradient text effect
|
|
@@ -100,7 +93,7 @@ class MCLIBanner:
|
|
|
100
93
|
|
|
101
94
|
@classmethod
|
|
102
95
|
def show_performance_banner(cls):
|
|
103
|
-
"""Display performance optimization banner"""
|
|
96
|
+
"""Display performance optimization banner."""
|
|
104
97
|
console.print()
|
|
105
98
|
|
|
106
99
|
banner_text = Text(cls.PERFORMANCE_BANNER)
|
|
@@ -119,7 +112,7 @@ class MCLIBanner:
|
|
|
119
112
|
|
|
120
113
|
@classmethod
|
|
121
114
|
def show_rust_banner(cls):
|
|
122
|
-
"""Display Rust extensions banner"""
|
|
115
|
+
"""Display Rust extensions banner."""
|
|
123
116
|
console.print()
|
|
124
117
|
|
|
125
118
|
banner_text = Text(cls.RUST_BANNER)
|
|
@@ -138,7 +131,7 @@ class MCLIBanner:
|
|
|
138
131
|
|
|
139
132
|
|
|
140
133
|
class AnimatedSpinner:
|
|
141
|
-
"""Fancy animated spinners and loading indicators"""
|
|
134
|
+
"""Fancy animated spinners and loading indicators."""
|
|
142
135
|
|
|
143
136
|
SPINNERS = {
|
|
144
137
|
"rocket": ["🚀", "🌟", "⭐", "✨", "💫", "🌠"],
|
|
@@ -157,14 +150,14 @@ class AnimatedSpinner:
|
|
|
157
150
|
self.thread = None
|
|
158
151
|
|
|
159
152
|
def start(self, message: str = "Loading..."):
|
|
160
|
-
"""Start the animated spinner"""
|
|
153
|
+
"""Start the animated spinner."""
|
|
161
154
|
self.running = True
|
|
162
155
|
self.thread = threading.Thread(target=self._animate, args=(message,))
|
|
163
156
|
self.thread.daemon = True
|
|
164
157
|
self.thread.start()
|
|
165
158
|
|
|
166
159
|
def stop(self):
|
|
167
|
-
"""Stop the spinner"""
|
|
160
|
+
"""Stop the spinner."""
|
|
168
161
|
self.running = False
|
|
169
162
|
if self.thread:
|
|
170
163
|
self.thread.join()
|
|
@@ -172,7 +165,7 @@ class AnimatedSpinner:
|
|
|
172
165
|
console.print("\r" + " " * 80 + "\r", end="")
|
|
173
166
|
|
|
174
167
|
def _animate(self, message: str):
|
|
175
|
-
"""Animation loop"""
|
|
168
|
+
"""Animation loop."""
|
|
176
169
|
frame_idx = 0
|
|
177
170
|
while self.running:
|
|
178
171
|
frame = self.frames[frame_idx % len(self.frames)]
|
|
@@ -182,11 +175,11 @@ class AnimatedSpinner:
|
|
|
182
175
|
|
|
183
176
|
|
|
184
177
|
class MCLIProgressBar:
|
|
185
|
-
"""Enhanced progress bars with visual flair"""
|
|
178
|
+
"""Enhanced progress bars with visual flair."""
|
|
186
179
|
|
|
187
180
|
@staticmethod
|
|
188
181
|
def create_fancy_progress():
|
|
189
|
-
"""Create a fancy progress bar with multiple columns"""
|
|
182
|
+
"""Create a fancy progress bar with multiple columns."""
|
|
190
183
|
return Progress(
|
|
191
184
|
SpinnerColumn("dots"),
|
|
192
185
|
TextColumn("[progress.description]{task.description}"),
|
|
@@ -201,7 +194,7 @@ class MCLIProgressBar:
|
|
|
201
194
|
|
|
202
195
|
@staticmethod
|
|
203
196
|
def show_rust_compilation_progress():
|
|
204
|
-
"""Simulate Rust compilation with progress"""
|
|
197
|
+
"""Simulate Rust compilation with progress."""
|
|
205
198
|
progress = MCLIProgressBar.create_fancy_progress()
|
|
206
199
|
|
|
207
200
|
with progress:
|
|
@@ -220,7 +213,7 @@ class MCLIProgressBar:
|
|
|
220
213
|
for stage_name, duration in stages:
|
|
221
214
|
task = progress.add_task(f"🦀 {stage_name}...", total=duration)
|
|
222
215
|
|
|
223
|
-
for
|
|
216
|
+
for _i in range(duration):
|
|
224
217
|
progress.update(task, advance=1)
|
|
225
218
|
time.sleep(0.1)
|
|
226
219
|
|
|
@@ -228,11 +221,11 @@ class MCLIProgressBar:
|
|
|
228
221
|
|
|
229
222
|
|
|
230
223
|
class VisualTable:
|
|
231
|
-
"""Enhanced tables with visual styling"""
|
|
224
|
+
"""Enhanced tables with visual styling."""
|
|
232
225
|
|
|
233
226
|
@staticmethod
|
|
234
227
|
def create_performance_table(data: Dict[str, Any]) -> Table:
|
|
235
|
-
"""Create a beautiful performance status table"""
|
|
228
|
+
"""Create a beautiful performance status table."""
|
|
236
229
|
table = Table(
|
|
237
230
|
title="🚀 Performance Optimization Status",
|
|
238
231
|
box=ROUNDED,
|
|
@@ -275,7 +268,7 @@ class VisualTable:
|
|
|
275
268
|
|
|
276
269
|
@staticmethod
|
|
277
270
|
def create_rust_extensions_table(extensions: Dict[str, bool]) -> Table:
|
|
278
|
-
"""Create a table showing Rust extension status"""
|
|
271
|
+
"""Create a table showing Rust extension status."""
|
|
279
272
|
table = Table(
|
|
280
273
|
title="🦀 Rust Extensions Status",
|
|
281
274
|
box=HEAVY,
|
|
@@ -318,14 +311,14 @@ class VisualTable:
|
|
|
318
311
|
|
|
319
312
|
|
|
320
313
|
class LiveDashboard:
|
|
321
|
-
"""Live updating dashboard for system status"""
|
|
314
|
+
"""Live updating dashboard for system status."""
|
|
322
315
|
|
|
323
316
|
def __init__(self):
|
|
324
317
|
self.console = Console()
|
|
325
318
|
self.running = False
|
|
326
319
|
|
|
327
320
|
def create_system_overview(self) -> Panel:
|
|
328
|
-
"""Create a live system overview panel"""
|
|
321
|
+
"""Create a live system overview panel."""
|
|
329
322
|
try:
|
|
330
323
|
import psutil
|
|
331
324
|
|
|
@@ -354,7 +347,7 @@ class LiveDashboard:
|
|
|
354
347
|
)
|
|
355
348
|
|
|
356
349
|
def create_mcli_status_panel(self) -> Panel:
|
|
357
|
-
"""Create MCLI status overview panel"""
|
|
350
|
+
"""Create MCLI status overview panel."""
|
|
358
351
|
try:
|
|
359
352
|
import platform
|
|
360
353
|
|
|
@@ -396,7 +389,7 @@ class LiveDashboard:
|
|
|
396
389
|
)
|
|
397
390
|
|
|
398
391
|
def create_services_panel(self) -> Panel:
|
|
399
|
-
"""Create services status panel"""
|
|
392
|
+
"""Create services status panel."""
|
|
400
393
|
services = Text()
|
|
401
394
|
services.append("🔧 Services Status\n\n", style="bold yellow")
|
|
402
395
|
|
|
@@ -427,7 +420,7 @@ class LiveDashboard:
|
|
|
427
420
|
return Panel(services, box=ROUNDED, border_style="bright_yellow", padding=(1, 2))
|
|
428
421
|
|
|
429
422
|
def create_recent_activity_panel(self) -> Panel:
|
|
430
|
-
"""Create recent activity panel"""
|
|
423
|
+
"""Create recent activity panel."""
|
|
431
424
|
activity = Text()
|
|
432
425
|
activity.append("📊 Recent Activity\n\n", style="bold blue")
|
|
433
426
|
|
|
@@ -440,7 +433,7 @@ class LiveDashboard:
|
|
|
440
433
|
return Panel(activity, box=ROUNDED, border_style="bright_blue", padding=(1, 2))
|
|
441
434
|
|
|
442
435
|
def create_full_dashboard(self):
|
|
443
|
-
"""Create a complete dashboard layout"""
|
|
436
|
+
"""Create a complete dashboard layout."""
|
|
444
437
|
from rich.layout import Layout
|
|
445
438
|
|
|
446
439
|
layout = Layout()
|
|
@@ -476,8 +469,7 @@ class LiveDashboard:
|
|
|
476
469
|
return layout
|
|
477
470
|
|
|
478
471
|
def start_live_dashboard(self, refresh_interval: float = 2.0):
|
|
479
|
-
"""Start the live updating dashboard"""
|
|
480
|
-
import threading
|
|
472
|
+
"""Start the live updating dashboard."""
|
|
481
473
|
import time
|
|
482
474
|
|
|
483
475
|
self.running = True
|
|
@@ -506,34 +498,34 @@ class LiveDashboard:
|
|
|
506
498
|
self.running = False
|
|
507
499
|
|
|
508
500
|
def stop_dashboard(self):
|
|
509
|
-
"""Stop the live dashboard"""
|
|
501
|
+
"""Stop the live dashboard."""
|
|
510
502
|
self.running = False
|
|
511
503
|
|
|
512
504
|
|
|
513
505
|
class ColorfulOutput:
|
|
514
|
-
"""Enhanced colorful output utilities"""
|
|
506
|
+
"""Enhanced colorful output utilities."""
|
|
515
507
|
|
|
516
508
|
@staticmethod
|
|
517
509
|
def success(message: str, icon: str = "✅"):
|
|
518
|
-
"""Display a success message with style"""
|
|
510
|
+
"""Display a success message with style."""
|
|
519
511
|
panel = Panel(f"{icon} {message}", box=ROUNDED, border_style="bright_green", padding=(0, 1))
|
|
520
512
|
console.print(panel)
|
|
521
513
|
|
|
522
514
|
@staticmethod
|
|
523
515
|
def error(message: str, icon: str = "❌"):
|
|
524
|
-
"""Display an error message with style"""
|
|
516
|
+
"""Display an error message with style."""
|
|
525
517
|
panel = Panel(f"{icon} {message}", box=HEAVY, border_style="bright_red", padding=(0, 1))
|
|
526
518
|
console.print(panel)
|
|
527
519
|
|
|
528
520
|
@staticmethod
|
|
529
521
|
def info(message: str, icon: str = "ℹ️"):
|
|
530
|
-
"""Display an info message with style"""
|
|
522
|
+
"""Display an info message with style."""
|
|
531
523
|
panel = Panel(f"{icon} {message}", box=ROUNDED, border_style="bright_cyan", padding=(0, 1))
|
|
532
524
|
console.print(panel)
|
|
533
525
|
|
|
534
526
|
@staticmethod
|
|
535
527
|
def warning(message: str, icon: str = "⚠️"):
|
|
536
|
-
"""Display a warning message with style"""
|
|
528
|
+
"""Display a warning message with style."""
|
|
537
529
|
panel = Panel(
|
|
538
530
|
f"{icon} {message}", box=ROUNDED, border_style="bright_yellow", padding=(0, 1)
|
|
539
531
|
)
|
|
@@ -541,11 +533,11 @@ class ColorfulOutput:
|
|
|
541
533
|
|
|
542
534
|
|
|
543
535
|
class StartupSequence:
|
|
544
|
-
"""Fancy startup sequence with animations"""
|
|
536
|
+
"""Fancy startup sequence with animations."""
|
|
545
537
|
|
|
546
538
|
@staticmethod
|
|
547
539
|
def run_startup_animation():
|
|
548
|
-
"""Run the full startup sequence"""
|
|
540
|
+
"""Run the full startup sequence."""
|
|
549
541
|
console.clear()
|
|
550
542
|
|
|
551
543
|
# Show main banner
|
|
@@ -581,7 +573,7 @@ class StartupSequence:
|
|
|
581
573
|
|
|
582
574
|
|
|
583
575
|
def demo_visual_effects():
|
|
584
|
-
"""Demonstrate all visual effects"""
|
|
576
|
+
"""Demonstrate all visual effects."""
|
|
585
577
|
console.clear()
|
|
586
578
|
|
|
587
579
|
# Show banners
|
mcli/lib/watcher/watcher.py
CHANGED
mcli/ml/__init__.py
CHANGED
mcli/ml/api/__init__.py
CHANGED
mcli/ml/api/app.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
"""FastAPI application factory and configuration"""
|
|
1
|
+
"""FastAPI application factory and configuration."""
|
|
2
2
|
|
|
3
3
|
from contextlib import asynccontextmanager
|
|
4
|
-
from typing import Any, Dict
|
|
5
4
|
|
|
6
5
|
import uvicorn
|
|
7
6
|
from fastapi import FastAPI, Request, Response
|
|
@@ -35,7 +34,7 @@ logger = get_logger(__name__)
|
|
|
35
34
|
|
|
36
35
|
@asynccontextmanager
|
|
37
36
|
async def lifespan(app: FastAPI):
|
|
38
|
-
"""Application lifespan manager"""
|
|
37
|
+
"""Application lifespan manager."""
|
|
39
38
|
# Startup
|
|
40
39
|
logger.info("Starting ML API server...")
|
|
41
40
|
|
|
@@ -70,7 +69,7 @@ async def lifespan(app: FastAPI):
|
|
|
70
69
|
|
|
71
70
|
|
|
72
71
|
def create_app() -> FastAPI:
|
|
73
|
-
"""Create FastAPI application with all configurations"""
|
|
72
|
+
"""Create FastAPI application with all configurations."""
|
|
74
73
|
|
|
75
74
|
# Setup logging
|
|
76
75
|
setup_logging()
|
|
@@ -126,13 +125,13 @@ def create_app() -> FastAPI:
|
|
|
126
125
|
# Health check endpoint
|
|
127
126
|
@app.get("/health", tags=["Health"])
|
|
128
127
|
async def health_check():
|
|
129
|
-
"""Health check endpoint"""
|
|
128
|
+
"""Health check endpoint."""
|
|
130
129
|
return {"status": "healthy", "environment": settings.environment, "version": "1.0.0"}
|
|
131
130
|
|
|
132
131
|
# Ready check endpoint
|
|
133
132
|
@app.get("/ready", tags=["Health"])
|
|
134
133
|
async def ready_check():
|
|
135
|
-
"""Readiness check endpoint"""
|
|
134
|
+
"""Readiness check endpoint."""
|
|
136
135
|
from mcli.ml.cache import check_cache_health
|
|
137
136
|
from mcli.ml.database.session import check_database_health
|
|
138
137
|
|
|
@@ -154,7 +153,7 @@ def create_app() -> FastAPI:
|
|
|
154
153
|
# Metrics endpoint (Prometheus format)
|
|
155
154
|
@app.get("/metrics", tags=["Monitoring"])
|
|
156
155
|
async def metrics():
|
|
157
|
-
"""Prometheus metrics endpoint"""
|
|
156
|
+
"""Prometheus metrics endpoint."""
|
|
158
157
|
from mcli.ml.monitoring.metrics import get_metrics
|
|
159
158
|
|
|
160
159
|
return Response(content=get_metrics(), media_type="text/plain")
|
|
@@ -162,7 +161,7 @@ def create_app() -> FastAPI:
|
|
|
162
161
|
# Root endpoint
|
|
163
162
|
@app.get("/")
|
|
164
163
|
async def root():
|
|
165
|
-
"""Root endpoint"""
|
|
164
|
+
"""Root endpoint."""
|
|
166
165
|
return {
|
|
167
166
|
"message": "MCLI ML System API",
|
|
168
167
|
"version": "1.0.0",
|
|
@@ -183,7 +182,7 @@ def create_app() -> FastAPI:
|
|
|
183
182
|
|
|
184
183
|
|
|
185
184
|
def get_application() -> FastAPI:
|
|
186
|
-
"""Get configured FastAPI application"""
|
|
185
|
+
"""Get configured FastAPI application."""
|
|
187
186
|
return create_app()
|
|
188
187
|
|
|
189
188
|
|
mcli/ml/api/middleware.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Custom middleware for API"""
|
|
1
|
+
"""Custom middleware for API."""
|
|
2
2
|
|
|
3
3
|
import time
|
|
4
4
|
import uuid
|
|
@@ -17,7 +17,7 @@ logger = get_logger(__name__)
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
class RequestLoggingMiddleware(BaseHTTPMiddleware):
|
|
20
|
-
"""Log all incoming requests and responses"""
|
|
20
|
+
"""Log all incoming requests and responses."""
|
|
21
21
|
|
|
22
22
|
async def dispatch(self, request: Request, call_next: Callable) -> Response:
|
|
23
23
|
# Generate request ID
|
|
@@ -45,7 +45,7 @@ class RequestLoggingMiddleware(BaseHTTPMiddleware):
|
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
class RateLimitMiddleware(BaseHTTPMiddleware):
|
|
48
|
-
"""Rate limiting middleware"""
|
|
48
|
+
"""Rate limiting middleware."""
|
|
49
49
|
|
|
50
50
|
def __init__(self, app: ASGIApp, requests_per_minute: int = 60):
|
|
51
51
|
super().__init__(app)
|
|
@@ -86,7 +86,7 @@ class RateLimitMiddleware(BaseHTTPMiddleware):
|
|
|
86
86
|
|
|
87
87
|
|
|
88
88
|
class ErrorHandlingMiddleware(BaseHTTPMiddleware):
|
|
89
|
-
"""Global error handling middleware"""
|
|
89
|
+
"""Global error handling middleware."""
|
|
90
90
|
|
|
91
91
|
async def dispatch(self, request: Request, call_next: Callable) -> Response:
|
|
92
92
|
try:
|
|
@@ -110,7 +110,7 @@ class ErrorHandlingMiddleware(BaseHTTPMiddleware):
|
|
|
110
110
|
|
|
111
111
|
|
|
112
112
|
class CompressionMiddleware(BaseHTTPMiddleware):
|
|
113
|
-
"""Response compression middleware"""
|
|
113
|
+
"""Response compression middleware."""
|
|
114
114
|
|
|
115
115
|
async def dispatch(self, request: Request, call_next: Callable) -> Response:
|
|
116
116
|
response = await call_next(request)
|
|
@@ -125,7 +125,7 @@ class CompressionMiddleware(BaseHTTPMiddleware):
|
|
|
125
125
|
|
|
126
126
|
|
|
127
127
|
class CacheControlMiddleware(BaseHTTPMiddleware):
|
|
128
|
-
"""Add cache control headers"""
|
|
128
|
+
"""Add cache control headers."""
|
|
129
129
|
|
|
130
130
|
def __init__(self, app: ASGIApp, max_age: int = 0):
|
|
131
131
|
super().__init__(app)
|
|
@@ -137,7 +137,7 @@ class CacheControlMiddleware(BaseHTTPMiddleware):
|
|
|
137
137
|
# Add cache control headers based on endpoint
|
|
138
138
|
if request.url.path.startswith("/api/v1/data"):
|
|
139
139
|
# Cache data endpoints
|
|
140
|
-
response.headers["Cache-Control"] =
|
|
140
|
+
response.headers["Cache-Control"] = "public, max-age=300"
|
|
141
141
|
elif request.url.path.startswith("/api/v1/predictions"):
|
|
142
142
|
# Don't cache predictions
|
|
143
143
|
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
|
|
@@ -149,7 +149,7 @@ class CacheControlMiddleware(BaseHTTPMiddleware):
|
|
|
149
149
|
|
|
150
150
|
|
|
151
151
|
class SecurityHeadersMiddleware(BaseHTTPMiddleware):
|
|
152
|
-
"""Add security headers to responses"""
|
|
152
|
+
"""Add security headers to responses."""
|
|
153
153
|
|
|
154
154
|
async def dispatch(self, request: Request, call_next: Callable) -> Response:
|
|
155
155
|
response = await call_next(request)
|
|
@@ -175,7 +175,7 @@ class SecurityHeadersMiddleware(BaseHTTPMiddleware):
|
|
|
175
175
|
|
|
176
176
|
|
|
177
177
|
class MetricsMiddleware(BaseHTTPMiddleware):
|
|
178
|
-
"""Collect metrics for monitoring"""
|
|
178
|
+
"""Collect metrics for monitoring."""
|
|
179
179
|
|
|
180
180
|
def __init__(self, app: ASGIApp):
|
|
181
181
|
super().__init__(app)
|
|
@@ -202,7 +202,7 @@ class MetricsMiddleware(BaseHTTPMiddleware):
|
|
|
202
202
|
return response
|
|
203
203
|
|
|
204
204
|
def get_metrics(self) -> dict:
|
|
205
|
-
"""Get collected metrics"""
|
|
205
|
+
"""Get collected metrics."""
|
|
206
206
|
metrics = {}
|
|
207
207
|
for endpoint, count in self.request_count.items():
|
|
208
208
|
durations = self.request_duration[endpoint]
|
mcli/ml/api/routers/__init__.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"""Admin API routes"""
|
|
1
|
+
"""Admin API routes."""
|
|
2
2
|
|
|
3
3
|
from fastapi import APIRouter, Depends
|
|
4
4
|
|
|
5
|
-
from mcli.ml.auth import
|
|
5
|
+
from mcli.ml.auth import require_role
|
|
6
6
|
from mcli.ml.database.models import User, UserRole
|
|
7
7
|
|
|
8
8
|
router = APIRouter()
|
|
@@ -10,5 +10,5 @@ router = APIRouter()
|
|
|
10
10
|
|
|
11
11
|
@router.get("/users")
|
|
12
12
|
async def list_users(current_user: User = Depends(require_role(UserRole.ADMIN))):
|
|
13
|
-
"""List all users"""
|
|
13
|
+
"""List all users."""
|
|
14
14
|
return {"users": []}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
"""Authentication API routes"""
|
|
1
|
+
"""Authentication API routes."""
|
|
2
2
|
|
|
3
3
|
from datetime import datetime
|
|
4
4
|
from typing import Optional
|
|
5
5
|
|
|
6
|
-
from fastapi import APIRouter, Depends, HTTPException,
|
|
7
|
-
from fastapi.security import
|
|
6
|
+
from fastapi import APIRouter, Depends, HTTPException, status
|
|
7
|
+
from fastapi.security import HTTPBearer
|
|
8
8
|
from sqlalchemy.orm import Session
|
|
9
9
|
|
|
10
10
|
from mcli.ml.auth import (
|
|
@@ -17,7 +17,6 @@ from mcli.ml.auth import (
|
|
|
17
17
|
UserResponse,
|
|
18
18
|
check_rate_limit,
|
|
19
19
|
get_current_active_user,
|
|
20
|
-
get_current_user,
|
|
21
20
|
)
|
|
22
21
|
from mcli.ml.database.models import User
|
|
23
22
|
from mcli.ml.database.session import get_db
|
|
@@ -31,7 +30,7 @@ security = HTTPBearer()
|
|
|
31
30
|
async def register(
|
|
32
31
|
user_data: UserCreate, db: Session = Depends(get_db), _: bool = Depends(check_rate_limit)
|
|
33
32
|
):
|
|
34
|
-
"""Register a new user"""
|
|
33
|
+
"""Register a new user."""
|
|
35
34
|
try:
|
|
36
35
|
user = await auth_manager.register_user(user_data, db)
|
|
37
36
|
return UserResponse.from_orm(user)
|
|
@@ -45,26 +44,26 @@ async def register(
|
|
|
45
44
|
async def login(
|
|
46
45
|
login_data: UserLogin, db: Session = Depends(get_db), _: bool = Depends(check_rate_limit)
|
|
47
46
|
):
|
|
48
|
-
"""Login and receive access token"""
|
|
47
|
+
"""Login and receive access token."""
|
|
49
48
|
return await auth_manager.login(login_data, db)
|
|
50
49
|
|
|
51
50
|
|
|
52
51
|
@router.post("/refresh", response_model=TokenResponse)
|
|
53
52
|
async def refresh_token(refresh_token: str, db: Session = Depends(get_db)):
|
|
54
|
-
"""Refresh access token using refresh token"""
|
|
53
|
+
"""Refresh access token using refresh token."""
|
|
55
54
|
return await auth_manager.refresh_access_token(refresh_token, db)
|
|
56
55
|
|
|
57
56
|
|
|
58
57
|
@router.post("/logout")
|
|
59
58
|
async def logout(current_user: User = Depends(get_current_active_user)):
|
|
60
|
-
"""Logout current user"""
|
|
59
|
+
"""Logout current user."""
|
|
61
60
|
# In a real implementation, you might want to blacklist the token
|
|
62
61
|
return {"message": "Successfully logged out"}
|
|
63
62
|
|
|
64
63
|
|
|
65
64
|
@router.get("/me", response_model=UserResponse)
|
|
66
65
|
async def get_current_user_info(current_user: User = Depends(get_current_active_user)):
|
|
67
|
-
"""Get current user information"""
|
|
66
|
+
"""Get current user information."""
|
|
68
67
|
return UserResponse.from_orm(current_user)
|
|
69
68
|
|
|
70
69
|
|
|
@@ -74,7 +73,7 @@ async def update_current_user(
|
|
|
74
73
|
current_user: User = Depends(get_current_active_user),
|
|
75
74
|
db: Session = Depends(get_db),
|
|
76
75
|
):
|
|
77
|
-
"""Update current user information"""
|
|
76
|
+
"""Update current user information."""
|
|
78
77
|
# Update allowed fields
|
|
79
78
|
allowed_fields = ["first_name", "last_name", "email"]
|
|
80
79
|
for field in allowed_fields:
|
|
@@ -92,7 +91,7 @@ async def change_password(
|
|
|
92
91
|
current_user: User = Depends(get_current_active_user),
|
|
93
92
|
db: Session = Depends(get_db),
|
|
94
93
|
):
|
|
95
|
-
"""Change current user's password"""
|
|
94
|
+
"""Change current user's password."""
|
|
96
95
|
# Verify current password
|
|
97
96
|
if not auth_manager.verify_password(password_data.current_password, current_user.password_hash):
|
|
98
97
|
raise HTTPException(
|
|
@@ -110,7 +109,7 @@ async def change_password(
|
|
|
110
109
|
async def reset_password_request(
|
|
111
110
|
reset_data: PasswordReset, db: Session = Depends(get_db), _: bool = Depends(check_rate_limit)
|
|
112
111
|
):
|
|
113
|
-
"""Request password reset"""
|
|
112
|
+
"""Request password reset."""
|
|
114
113
|
# Find user by email
|
|
115
114
|
user = db.query(User).filter(User.email == reset_data.email).first()
|
|
116
115
|
|
|
@@ -125,7 +124,7 @@ async def reset_password_request(
|
|
|
125
124
|
|
|
126
125
|
@router.post("/verify-email/{token}")
|
|
127
126
|
async def verify_email(token: str, db: Session = Depends(get_db)):
|
|
128
|
-
"""Verify email address"""
|
|
127
|
+
"""Verify email address."""
|
|
129
128
|
# In a real implementation, verify the token and update user
|
|
130
129
|
return {"message": "Email verified successfully"}
|
|
131
130
|
|
|
@@ -134,7 +133,7 @@ async def verify_email(token: str, db: Session = Depends(get_db)):
|
|
|
134
133
|
async def get_user_sessions(
|
|
135
134
|
current_user: User = Depends(get_current_active_user), db: Session = Depends(get_db)
|
|
136
135
|
):
|
|
137
|
-
"""Get all active sessions for current user"""
|
|
136
|
+
"""Get all active sessions for current user."""
|
|
138
137
|
# In a real implementation, return active sessions from database
|
|
139
138
|
return {
|
|
140
139
|
"sessions": [
|
|
@@ -155,7 +154,7 @@ async def revoke_session(
|
|
|
155
154
|
current_user: User = Depends(get_current_active_user),
|
|
156
155
|
db: Session = Depends(get_db),
|
|
157
156
|
):
|
|
158
|
-
"""Revoke a specific session"""
|
|
157
|
+
"""Revoke a specific session."""
|
|
159
158
|
# In a real implementation, revoke the session
|
|
160
159
|
return {"message": f"Session {session_id} revoked successfully"}
|
|
161
160
|
|
|
@@ -167,7 +166,7 @@ async def create_api_key(
|
|
|
167
166
|
current_user: User = Depends(get_current_active_user),
|
|
168
167
|
db: Session = Depends(get_db),
|
|
169
168
|
):
|
|
170
|
-
"""Create a new API key"""
|
|
169
|
+
"""Create a new API key."""
|
|
171
170
|
import secrets
|
|
172
171
|
from datetime import timedelta
|
|
173
172
|
|
|
@@ -194,7 +193,7 @@ async def create_api_key(
|
|
|
194
193
|
|
|
195
194
|
@router.get("/api-keys")
|
|
196
195
|
async def list_api_keys(current_user: User = Depends(get_current_active_user)):
|
|
197
|
-
"""List all API keys for current user"""
|
|
196
|
+
"""List all API keys for current user."""
|
|
198
197
|
# In a real implementation, return API keys from database
|
|
199
198
|
return {
|
|
200
199
|
"api_keys": [
|
|
@@ -215,6 +214,6 @@ async def revoke_api_key(
|
|
|
215
214
|
current_user: User = Depends(get_current_active_user),
|
|
216
215
|
db: Session = Depends(get_db),
|
|
217
216
|
):
|
|
218
|
-
"""Revoke an API key"""
|
|
217
|
+
"""Revoke an API key."""
|
|
219
218
|
# In a real implementation, revoke the API key
|
|
220
219
|
return {"message": f"API key {key_id} revoked successfully"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Backtesting API routes"""
|
|
1
|
+
"""Backtesting API routes."""
|
|
2
2
|
|
|
3
3
|
from fastapi import APIRouter, Depends
|
|
4
4
|
|
|
@@ -10,5 +10,5 @@ router = APIRouter()
|
|
|
10
10
|
|
|
11
11
|
@router.post("/run")
|
|
12
12
|
async def run_backtest(current_user: User = Depends(get_current_active_user)):
|
|
13
|
-
"""Run backtest"""
|
|
13
|
+
"""Run backtest."""
|
|
14
14
|
return {"status": "started"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Data API routes"""
|
|
1
|
+
"""Data API routes."""
|
|
2
2
|
|
|
3
3
|
from fastapi import APIRouter, Depends
|
|
4
4
|
|
|
@@ -10,5 +10,5 @@ router = APIRouter()
|
|
|
10
10
|
|
|
11
11
|
@router.get("/stocks/{ticker}")
|
|
12
12
|
async def get_stock_data(ticker: str, current_user: User = Depends(get_current_active_user)):
|
|
13
|
-
"""Get stock data"""
|
|
13
|
+
"""Get stock data."""
|
|
14
14
|
return {"ticker": ticker, "data": {}}
|