mcli-framework 7.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mcli-framework might be problematic. Click here for more details.
- mcli/app/chat_cmd.py +42 -0
- mcli/app/commands_cmd.py +226 -0
- mcli/app/completion_cmd.py +216 -0
- mcli/app/completion_helpers.py +288 -0
- mcli/app/cron_test_cmd.py +697 -0
- mcli/app/logs_cmd.py +419 -0
- mcli/app/main.py +492 -0
- mcli/app/model/model.py +1060 -0
- mcli/app/model_cmd.py +227 -0
- mcli/app/redis_cmd.py +269 -0
- mcli/app/video/video.py +1114 -0
- mcli/app/visual_cmd.py +303 -0
- mcli/chat/chat.py +2409 -0
- mcli/chat/command_rag.py +514 -0
- mcli/chat/enhanced_chat.py +652 -0
- mcli/chat/system_controller.py +1010 -0
- mcli/chat/system_integration.py +1016 -0
- mcli/cli.py +25 -0
- mcli/config.toml +20 -0
- mcli/lib/api/api.py +586 -0
- mcli/lib/api/daemon_client.py +203 -0
- mcli/lib/api/daemon_client_local.py +44 -0
- mcli/lib/api/daemon_decorator.py +217 -0
- mcli/lib/api/mcli_decorators.py +1032 -0
- mcli/lib/auth/auth.py +85 -0
- mcli/lib/auth/aws_manager.py +85 -0
- mcli/lib/auth/azure_manager.py +91 -0
- mcli/lib/auth/credential_manager.py +192 -0
- mcli/lib/auth/gcp_manager.py +93 -0
- mcli/lib/auth/key_manager.py +117 -0
- mcli/lib/auth/mcli_manager.py +93 -0
- mcli/lib/auth/token_manager.py +75 -0
- mcli/lib/auth/token_util.py +1011 -0
- mcli/lib/config/config.py +47 -0
- mcli/lib/discovery/__init__.py +1 -0
- mcli/lib/discovery/command_discovery.py +274 -0
- mcli/lib/erd/erd.py +1345 -0
- mcli/lib/erd/generate_graph.py +453 -0
- mcli/lib/files/files.py +76 -0
- mcli/lib/fs/fs.py +109 -0
- mcli/lib/lib.py +29 -0
- mcli/lib/logger/logger.py +611 -0
- mcli/lib/performance/optimizer.py +409 -0
- mcli/lib/performance/rust_bridge.py +502 -0
- mcli/lib/performance/uvloop_config.py +154 -0
- mcli/lib/pickles/pickles.py +50 -0
- mcli/lib/search/cached_vectorizer.py +479 -0
- mcli/lib/services/data_pipeline.py +460 -0
- mcli/lib/services/lsh_client.py +441 -0
- mcli/lib/services/redis_service.py +387 -0
- mcli/lib/shell/shell.py +137 -0
- mcli/lib/toml/toml.py +33 -0
- mcli/lib/ui/styling.py +47 -0
- mcli/lib/ui/visual_effects.py +634 -0
- mcli/lib/watcher/watcher.py +185 -0
- mcli/ml/api/app.py +215 -0
- mcli/ml/api/middleware.py +224 -0
- mcli/ml/api/routers/admin_router.py +12 -0
- mcli/ml/api/routers/auth_router.py +244 -0
- mcli/ml/api/routers/backtest_router.py +12 -0
- mcli/ml/api/routers/data_router.py +12 -0
- mcli/ml/api/routers/model_router.py +302 -0
- mcli/ml/api/routers/monitoring_router.py +12 -0
- mcli/ml/api/routers/portfolio_router.py +12 -0
- mcli/ml/api/routers/prediction_router.py +267 -0
- mcli/ml/api/routers/trade_router.py +12 -0
- mcli/ml/api/routers/websocket_router.py +76 -0
- mcli/ml/api/schemas.py +64 -0
- mcli/ml/auth/auth_manager.py +425 -0
- mcli/ml/auth/models.py +154 -0
- mcli/ml/auth/permissions.py +302 -0
- mcli/ml/backtesting/backtest_engine.py +502 -0
- mcli/ml/backtesting/performance_metrics.py +393 -0
- mcli/ml/cache.py +400 -0
- mcli/ml/cli/main.py +398 -0
- mcli/ml/config/settings.py +394 -0
- mcli/ml/configs/dvc_config.py +230 -0
- mcli/ml/configs/mlflow_config.py +131 -0
- mcli/ml/configs/mlops_manager.py +293 -0
- mcli/ml/dashboard/app.py +532 -0
- mcli/ml/dashboard/app_integrated.py +738 -0
- mcli/ml/dashboard/app_supabase.py +560 -0
- mcli/ml/dashboard/app_training.py +615 -0
- mcli/ml/dashboard/cli.py +51 -0
- mcli/ml/data_ingestion/api_connectors.py +501 -0
- mcli/ml/data_ingestion/data_pipeline.py +567 -0
- mcli/ml/data_ingestion/stream_processor.py +512 -0
- mcli/ml/database/migrations/env.py +94 -0
- mcli/ml/database/models.py +667 -0
- mcli/ml/database/session.py +200 -0
- mcli/ml/experimentation/ab_testing.py +845 -0
- mcli/ml/features/ensemble_features.py +607 -0
- mcli/ml/features/political_features.py +676 -0
- mcli/ml/features/recommendation_engine.py +809 -0
- mcli/ml/features/stock_features.py +573 -0
- mcli/ml/features/test_feature_engineering.py +346 -0
- mcli/ml/logging.py +85 -0
- mcli/ml/mlops/data_versioning.py +518 -0
- mcli/ml/mlops/experiment_tracker.py +377 -0
- mcli/ml/mlops/model_serving.py +481 -0
- mcli/ml/mlops/pipeline_orchestrator.py +614 -0
- mcli/ml/models/base_models.py +324 -0
- mcli/ml/models/ensemble_models.py +675 -0
- mcli/ml/models/recommendation_models.py +474 -0
- mcli/ml/models/test_models.py +487 -0
- mcli/ml/monitoring/drift_detection.py +676 -0
- mcli/ml/monitoring/metrics.py +45 -0
- mcli/ml/optimization/portfolio_optimizer.py +834 -0
- mcli/ml/preprocessing/data_cleaners.py +451 -0
- mcli/ml/preprocessing/feature_extractors.py +491 -0
- mcli/ml/preprocessing/ml_pipeline.py +382 -0
- mcli/ml/preprocessing/politician_trading_preprocessor.py +569 -0
- mcli/ml/preprocessing/test_preprocessing.py +294 -0
- mcli/ml/scripts/populate_sample_data.py +200 -0
- mcli/ml/tasks.py +400 -0
- mcli/ml/tests/test_integration.py +429 -0
- mcli/ml/tests/test_training_dashboard.py +387 -0
- mcli/public/oi/oi.py +15 -0
- mcli/public/public.py +4 -0
- mcli/self/self_cmd.py +1246 -0
- mcli/workflow/daemon/api_daemon.py +800 -0
- mcli/workflow/daemon/async_command_database.py +681 -0
- mcli/workflow/daemon/async_process_manager.py +591 -0
- mcli/workflow/daemon/client.py +530 -0
- mcli/workflow/daemon/commands.py +1196 -0
- mcli/workflow/daemon/daemon.py +905 -0
- mcli/workflow/daemon/daemon_api.py +59 -0
- mcli/workflow/daemon/enhanced_daemon.py +571 -0
- mcli/workflow/daemon/process_cli.py +244 -0
- mcli/workflow/daemon/process_manager.py +439 -0
- mcli/workflow/daemon/test_daemon.py +275 -0
- mcli/workflow/dashboard/dashboard_cmd.py +113 -0
- mcli/workflow/docker/docker.py +0 -0
- mcli/workflow/file/file.py +100 -0
- mcli/workflow/gcloud/config.toml +21 -0
- mcli/workflow/gcloud/gcloud.py +58 -0
- mcli/workflow/git_commit/ai_service.py +328 -0
- mcli/workflow/git_commit/commands.py +430 -0
- mcli/workflow/lsh_integration.py +355 -0
- mcli/workflow/model_service/client.py +594 -0
- mcli/workflow/model_service/download_and_run_efficient_models.py +288 -0
- mcli/workflow/model_service/lightweight_embedder.py +397 -0
- mcli/workflow/model_service/lightweight_model_server.py +714 -0
- mcli/workflow/model_service/lightweight_test.py +241 -0
- mcli/workflow/model_service/model_service.py +1955 -0
- mcli/workflow/model_service/ollama_efficient_runner.py +425 -0
- mcli/workflow/model_service/pdf_processor.py +386 -0
- mcli/workflow/model_service/test_efficient_runner.py +234 -0
- mcli/workflow/model_service/test_example.py +315 -0
- mcli/workflow/model_service/test_integration.py +131 -0
- mcli/workflow/model_service/test_new_features.py +149 -0
- mcli/workflow/openai/openai.py +99 -0
- mcli/workflow/politician_trading/commands.py +1790 -0
- mcli/workflow/politician_trading/config.py +134 -0
- mcli/workflow/politician_trading/connectivity.py +490 -0
- mcli/workflow/politician_trading/data_sources.py +395 -0
- mcli/workflow/politician_trading/database.py +410 -0
- mcli/workflow/politician_trading/demo.py +248 -0
- mcli/workflow/politician_trading/models.py +165 -0
- mcli/workflow/politician_trading/monitoring.py +413 -0
- mcli/workflow/politician_trading/scrapers.py +966 -0
- mcli/workflow/politician_trading/scrapers_california.py +412 -0
- mcli/workflow/politician_trading/scrapers_eu.py +377 -0
- mcli/workflow/politician_trading/scrapers_uk.py +350 -0
- mcli/workflow/politician_trading/scrapers_us_states.py +438 -0
- mcli/workflow/politician_trading/supabase_functions.py +354 -0
- mcli/workflow/politician_trading/workflow.py +852 -0
- mcli/workflow/registry/registry.py +180 -0
- mcli/workflow/repo/repo.py +223 -0
- mcli/workflow/scheduler/commands.py +493 -0
- mcli/workflow/scheduler/cron_parser.py +238 -0
- mcli/workflow/scheduler/job.py +182 -0
- mcli/workflow/scheduler/monitor.py +139 -0
- mcli/workflow/scheduler/persistence.py +324 -0
- mcli/workflow/scheduler/scheduler.py +679 -0
- mcli/workflow/sync/sync_cmd.py +437 -0
- mcli/workflow/sync/test_cmd.py +314 -0
- mcli/workflow/videos/videos.py +242 -0
- mcli/workflow/wakatime/wakatime.py +11 -0
- mcli/workflow/workflow.py +37 -0
- mcli_framework-7.0.0.dist-info/METADATA +479 -0
- mcli_framework-7.0.0.dist-info/RECORD +186 -0
- mcli_framework-7.0.0.dist-info/WHEEL +5 -0
- mcli_framework-7.0.0.dist-info/entry_points.txt +7 -0
- mcli_framework-7.0.0.dist-info/licenses/LICENSE +21 -0
- mcli_framework-7.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Test script for the MCLI Daemon Service.
|
|
4
|
+
|
|
5
|
+
This script demonstrates the daemon functionality by creating and executing
|
|
6
|
+
example commands in different programming languages.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
import subprocess
|
|
11
|
+
import tempfile
|
|
12
|
+
import time
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def create_test_scripts():
|
|
17
|
+
"""Create test scripts for different languages"""
|
|
18
|
+
scripts = {}
|
|
19
|
+
|
|
20
|
+
# Python script
|
|
21
|
+
python_script = '''#!/usr/bin/env python3
|
|
22
|
+
import sys
|
|
23
|
+
import json
|
|
24
|
+
|
|
25
|
+
def process_data(input_data):
|
|
26
|
+
"""Process input data and return result"""
|
|
27
|
+
try:
|
|
28
|
+
data = json.loads(input_data)
|
|
29
|
+
result = {
|
|
30
|
+
"processed": True,
|
|
31
|
+
"count": len(data),
|
|
32
|
+
"sum": sum(data) if isinstance(data, list) else 0,
|
|
33
|
+
"timestamp": time.time()
|
|
34
|
+
}
|
|
35
|
+
return json.dumps(result)
|
|
36
|
+
except Exception as e:
|
|
37
|
+
return json.dumps({"error": str(e)})
|
|
38
|
+
|
|
39
|
+
if __name__ == "__main__":
|
|
40
|
+
import time
|
|
41
|
+
input_data = sys.argv[1] if len(sys.argv) > 1 else '[1, 2, 3, 4, 5]'
|
|
42
|
+
result = process_data(input_data)
|
|
43
|
+
print(result)
|
|
44
|
+
'''
|
|
45
|
+
scripts["python"] = python_script
|
|
46
|
+
|
|
47
|
+
# Node.js script
|
|
48
|
+
node_script = """#!/usr/bin/env node
|
|
49
|
+
const fs = require('fs');
|
|
50
|
+
|
|
51
|
+
function processFile(filename) {
|
|
52
|
+
try {
|
|
53
|
+
const content = fs.readFileSync(filename, 'utf8');
|
|
54
|
+
const lines = content.split('\\n').filter(line => line.trim());
|
|
55
|
+
const result = {
|
|
56
|
+
filename: filename,
|
|
57
|
+
lineCount: lines.length,
|
|
58
|
+
wordCount: content.split('\\s+').filter(word => word.trim()).length,
|
|
59
|
+
timestamp: new Date().toISOString()
|
|
60
|
+
};
|
|
61
|
+
console.log(JSON.stringify(result, null, 2));
|
|
62
|
+
} catch (error) {
|
|
63
|
+
console.error(JSON.stringify({error: error.message}));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const filename = process.argv[2] || __filename;
|
|
68
|
+
processFile(filename);
|
|
69
|
+
"""
|
|
70
|
+
scripts["node"] = node_script
|
|
71
|
+
|
|
72
|
+
# Shell script
|
|
73
|
+
shell_script = """#!/bin/bash
|
|
74
|
+
|
|
75
|
+
# Simple system info script
|
|
76
|
+
echo "=== System Information ==="
|
|
77
|
+
echo "Hostname: $(hostname)"
|
|
78
|
+
echo "OS: $(uname -s)"
|
|
79
|
+
echo "Architecture: $(uname -m)"
|
|
80
|
+
echo "Uptime: $(uptime)"
|
|
81
|
+
echo "Memory: $(free -h | grep Mem | awk '{print $2}')"
|
|
82
|
+
echo "Disk Usage: $(df -h / | tail -1 | awk '{print $5}')"
|
|
83
|
+
echo "=== End ==="
|
|
84
|
+
"""
|
|
85
|
+
scripts["shell"] = shell_script
|
|
86
|
+
|
|
87
|
+
return scripts
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def test_daemon_functionality():
|
|
91
|
+
"""Test the daemon functionality"""
|
|
92
|
+
print("🧪 Testing MCLI Daemon Service")
|
|
93
|
+
print("=" * 50)
|
|
94
|
+
|
|
95
|
+
# Create test scripts
|
|
96
|
+
scripts = create_test_scripts()
|
|
97
|
+
|
|
98
|
+
# Create temporary directory for test scripts
|
|
99
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
100
|
+
temp_path = Path(temp_dir)
|
|
101
|
+
|
|
102
|
+
# Write test scripts
|
|
103
|
+
script_files = {}
|
|
104
|
+
for lang, script in scripts.items():
|
|
105
|
+
if lang == "python":
|
|
106
|
+
filename = temp_path / "test_script.py"
|
|
107
|
+
elif lang == "node":
|
|
108
|
+
filename = temp_path / "test_script.js"
|
|
109
|
+
elif lang == "shell":
|
|
110
|
+
filename = temp_path / "test_script.sh"
|
|
111
|
+
|
|
112
|
+
with open(filename, "w") as f:
|
|
113
|
+
f.write(script)
|
|
114
|
+
|
|
115
|
+
# Make shell script executable
|
|
116
|
+
if lang == "shell":
|
|
117
|
+
os.chmod(filename, 0o755)
|
|
118
|
+
|
|
119
|
+
script_files[lang] = filename
|
|
120
|
+
|
|
121
|
+
print("✅ Test scripts created")
|
|
122
|
+
|
|
123
|
+
# Test daemon commands
|
|
124
|
+
try:
|
|
125
|
+
# Test daemon status
|
|
126
|
+
print("\n📊 Testing daemon status...")
|
|
127
|
+
result = subprocess.run(
|
|
128
|
+
["mcli", "workflow", "daemon", "status"], capture_output=True, text=True
|
|
129
|
+
)
|
|
130
|
+
print(f"Status: {result.stdout.strip()}")
|
|
131
|
+
|
|
132
|
+
# Test adding commands
|
|
133
|
+
print("\n➕ Testing command addition...")
|
|
134
|
+
for lang, script_file in script_files.items():
|
|
135
|
+
print(f"Adding {lang} command...")
|
|
136
|
+
result = subprocess.run(
|
|
137
|
+
[
|
|
138
|
+
"mcli",
|
|
139
|
+
"workflow",
|
|
140
|
+
"daemon",
|
|
141
|
+
"client",
|
|
142
|
+
"add-file",
|
|
143
|
+
f"test-{lang}",
|
|
144
|
+
str(script_file),
|
|
145
|
+
"--description",
|
|
146
|
+
f"Test {lang} script",
|
|
147
|
+
"--language",
|
|
148
|
+
lang,
|
|
149
|
+
"--group",
|
|
150
|
+
"test",
|
|
151
|
+
"--tags",
|
|
152
|
+
f"test,{lang},demo",
|
|
153
|
+
],
|
|
154
|
+
capture_output=True,
|
|
155
|
+
text=True,
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
if result.returncode == 0:
|
|
159
|
+
print(f"✅ {lang} command added successfully")
|
|
160
|
+
else:
|
|
161
|
+
print(f"❌ Failed to add {lang} command: {result.stderr}")
|
|
162
|
+
|
|
163
|
+
# Test listing commands
|
|
164
|
+
print("\n📋 Testing command listing...")
|
|
165
|
+
result = subprocess.run(
|
|
166
|
+
["mcli", "workflow", "daemon", "client", "list"], capture_output=True, text=True
|
|
167
|
+
)
|
|
168
|
+
print(result.stdout)
|
|
169
|
+
|
|
170
|
+
# Test searching commands
|
|
171
|
+
print("\n🔍 Testing command search...")
|
|
172
|
+
result = subprocess.run(
|
|
173
|
+
["mcli", "workflow", "daemon", "client", "search", "test"],
|
|
174
|
+
capture_output=True,
|
|
175
|
+
text=True,
|
|
176
|
+
)
|
|
177
|
+
print(result.stdout)
|
|
178
|
+
|
|
179
|
+
# Test command execution (if we can get command IDs)
|
|
180
|
+
print("\n⚡ Testing command execution...")
|
|
181
|
+
# Note: In a real scenario, you'd get the command ID from the add command output
|
|
182
|
+
# For this test, we'll just show the command structure
|
|
183
|
+
print("Command execution would be tested with:")
|
|
184
|
+
print("mcli workflow daemon client execute <command-id> [args...]")
|
|
185
|
+
|
|
186
|
+
except Exception as e:
|
|
187
|
+
print(f"❌ Error during testing: {e}")
|
|
188
|
+
|
|
189
|
+
print("\n✅ Daemon functionality test completed!")
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def show_usage_examples():
|
|
193
|
+
"""Show usage examples"""
|
|
194
|
+
print("\n📚 Usage Examples")
|
|
195
|
+
print("=" * 50)
|
|
196
|
+
|
|
197
|
+
examples = [
|
|
198
|
+
{
|
|
199
|
+
"title": "Start the daemon",
|
|
200
|
+
"command": "mcli workflow daemon start",
|
|
201
|
+
"description": "Start the background daemon service",
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"title": "Add a Python command",
|
|
205
|
+
"command": "mcli workflow daemon client add-file my-script script.py --language python --group utils",
|
|
206
|
+
"description": "Add a Python script as a command",
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"title": "Add command interactively",
|
|
210
|
+
"command": "mcli workflow daemon client add-interactive",
|
|
211
|
+
"description": "Interactive command creation with prompts",
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"title": "Search for commands",
|
|
215
|
+
"command": "mcli workflow daemon client search 'data processing'",
|
|
216
|
+
"description": "Search for commands by name, description, or tags",
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"title": "Execute a command",
|
|
220
|
+
"command": "mcli workflow daemon client execute <command-id> arg1 arg2",
|
|
221
|
+
"description": "Execute a stored command with arguments",
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
"title": "List all commands",
|
|
225
|
+
"command": "mcli workflow daemon client list",
|
|
226
|
+
"description": "List all stored commands",
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
"title": "Show command details",
|
|
230
|
+
"command": "mcli workflow daemon client show <command-id>",
|
|
231
|
+
"description": "Show detailed information about a command",
|
|
232
|
+
},
|
|
233
|
+
]
|
|
234
|
+
|
|
235
|
+
for i, example in enumerate(examples, 1):
|
|
236
|
+
print(f"\n{i}. {example['title']}")
|
|
237
|
+
print(f" Command: {example['command']}")
|
|
238
|
+
print(f" Description: {example['description']}")
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def main():
|
|
242
|
+
"""Main test function"""
|
|
243
|
+
print("🚀 MCLI Daemon Service Test Suite")
|
|
244
|
+
print("=" * 60)
|
|
245
|
+
|
|
246
|
+
# Check if mcli is available
|
|
247
|
+
try:
|
|
248
|
+
result = subprocess.run(["mcli", "--version"], capture_output=True, text=True)
|
|
249
|
+
if result.returncode != 0:
|
|
250
|
+
print("❌ MCLI not found or not working properly")
|
|
251
|
+
return
|
|
252
|
+
except FileNotFoundError:
|
|
253
|
+
print("❌ MCLI command not found in PATH")
|
|
254
|
+
return
|
|
255
|
+
|
|
256
|
+
print("✅ MCLI is available")
|
|
257
|
+
|
|
258
|
+
# Show usage examples
|
|
259
|
+
show_usage_examples()
|
|
260
|
+
|
|
261
|
+
# Ask if user wants to run tests
|
|
262
|
+
print("\n" + "=" * 60)
|
|
263
|
+
response = input("Would you like to run the daemon functionality tests? (y/n): ")
|
|
264
|
+
|
|
265
|
+
if response.lower() in ["y", "yes"]:
|
|
266
|
+
test_daemon_functionality()
|
|
267
|
+
else:
|
|
268
|
+
print("Skipping tests. You can run them manually using the examples above.")
|
|
269
|
+
|
|
270
|
+
print("\n🎉 Test suite completed!")
|
|
271
|
+
print("\nFor more information, see: src/mcli/workflow/daemon/README.md")
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
if __name__ == "__main__":
|
|
275
|
+
main()
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"""ML Dashboard commands for mcli."""
|
|
2
|
+
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
import click
|
|
8
|
+
|
|
9
|
+
from mcli.lib.logger.logger import get_logger
|
|
10
|
+
|
|
11
|
+
logger = get_logger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@click.group(name="dashboard")
|
|
15
|
+
def dashboard():
|
|
16
|
+
"""ML monitoring dashboard commands."""
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dashboard.command()
|
|
21
|
+
@click.option("--port", "-p", default=8501, help="Port to run dashboard on")
|
|
22
|
+
@click.option("--host", "-h", default="localhost", help="Host to bind to")
|
|
23
|
+
@click.option("--debug", is_flag=True, help="Run in debug mode")
|
|
24
|
+
def launch(port, host, debug):
|
|
25
|
+
"""Launch the ML monitoring dashboard."""
|
|
26
|
+
|
|
27
|
+
click.echo(f"🚀 Starting ML Dashboard on http://{host}:{port}")
|
|
28
|
+
|
|
29
|
+
# Get the dashboard app path - use Supabase version to avoid joblib issues
|
|
30
|
+
dashboard_path = Path(__file__).parent.parent.parent / "ml" / "dashboard" / "app_supabase.py"
|
|
31
|
+
|
|
32
|
+
if not dashboard_path.exists():
|
|
33
|
+
click.echo("❌ Dashboard app not found!")
|
|
34
|
+
logger.error(f"Dashboard app not found at {dashboard_path}")
|
|
35
|
+
sys.exit(1)
|
|
36
|
+
|
|
37
|
+
# Build streamlit command
|
|
38
|
+
cmd = [
|
|
39
|
+
sys.executable, "-m", "streamlit", "run",
|
|
40
|
+
str(dashboard_path),
|
|
41
|
+
"--server.port", str(port),
|
|
42
|
+
"--server.address", host,
|
|
43
|
+
"--browser.gatherUsageStats", "false"
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
if debug:
|
|
47
|
+
cmd.extend(["--logger.level", "debug"])
|
|
48
|
+
|
|
49
|
+
click.echo("📊 Dashboard is starting...")
|
|
50
|
+
click.echo("Press Ctrl+C to stop")
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
subprocess.run(cmd, check=True)
|
|
54
|
+
except KeyboardInterrupt:
|
|
55
|
+
click.echo("\n⏹️ Dashboard stopped")
|
|
56
|
+
except subprocess.CalledProcessError as e:
|
|
57
|
+
click.echo(f"❌ Failed to start dashboard: {e}")
|
|
58
|
+
logger.error(f"Dashboard failed to start: {e}")
|
|
59
|
+
sys.exit(1)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@dashboard.command()
|
|
63
|
+
def info():
|
|
64
|
+
"""Show dashboard information and status."""
|
|
65
|
+
|
|
66
|
+
click.echo("📊 ML Dashboard Information")
|
|
67
|
+
click.echo("━" * 40)
|
|
68
|
+
|
|
69
|
+
# Check if dependencies are installed
|
|
70
|
+
try:
|
|
71
|
+
import streamlit
|
|
72
|
+
import plotly
|
|
73
|
+
|
|
74
|
+
click.echo("✅ Dashboard dependencies installed")
|
|
75
|
+
click.echo(f" Streamlit version: {streamlit.__version__}")
|
|
76
|
+
click.echo(f" Plotly version: {plotly.__version__}")
|
|
77
|
+
except ImportError as e:
|
|
78
|
+
click.echo(f"❌ Missing dependencies: {e}")
|
|
79
|
+
click.echo(" Run: uv sync --extra dashboard")
|
|
80
|
+
|
|
81
|
+
# Check database connection
|
|
82
|
+
try:
|
|
83
|
+
from mcli.ml.config import settings
|
|
84
|
+
click.echo(f"\n📁 Database URL: {settings.database.url}")
|
|
85
|
+
click.echo(f"📍 Redis URL: {settings.redis.url}")
|
|
86
|
+
except Exception as e:
|
|
87
|
+
click.echo(f"⚠️ Configuration not available: {e}")
|
|
88
|
+
|
|
89
|
+
click.echo("\n💡 Quick start:")
|
|
90
|
+
click.echo(" mcli workflow dashboard launch")
|
|
91
|
+
click.echo(" mcli workflow dashboard launch --port 8502 --host 0.0.0.0")
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@dashboard.command()
|
|
95
|
+
@click.argument("action", type=click.Choice(["start", "stop", "restart"]))
|
|
96
|
+
def service(action):
|
|
97
|
+
"""Manage dashboard as a background service."""
|
|
98
|
+
|
|
99
|
+
if action == "start":
|
|
100
|
+
click.echo("🚀 Starting dashboard service...")
|
|
101
|
+
# Could implement systemd or pm2 integration here
|
|
102
|
+
click.echo("⚠️ Service mode not yet implemented")
|
|
103
|
+
click.echo(" Use 'mcli workflow dashboard launch' instead")
|
|
104
|
+
elif action == "stop":
|
|
105
|
+
click.echo("⏹️ Stopping dashboard service...")
|
|
106
|
+
click.echo("⚠️ Service mode not yet implemented")
|
|
107
|
+
elif action == "restart":
|
|
108
|
+
click.echo("🔄 Restarting dashboard service...")
|
|
109
|
+
click.echo("⚠️ Service mode not yet implemented")
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
if __name__ == "__main__":
|
|
113
|
+
dashboard()
|
|
File without changes
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import click
|
|
2
|
+
import fitz # PyMuPDF
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@click.group(name="file")
|
|
6
|
+
def file():
|
|
7
|
+
"""Personal file utility to use with custom and/or default file system paths."""
|
|
8
|
+
pass
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@file.command()
|
|
12
|
+
@click.argument("input_oxps", type=click.Path(exists=True))
|
|
13
|
+
@click.argument("output_pdf", type=click.Path())
|
|
14
|
+
def oxps_to_pdf(input_oxps, output_pdf):
|
|
15
|
+
"""Converts an OXPS file (INPUT_OXPS) to a PDF file (OUTPUT_PDF)."""
|
|
16
|
+
try:
|
|
17
|
+
# Open the OXPS file
|
|
18
|
+
oxps_document = fitz.open(input_oxps)
|
|
19
|
+
|
|
20
|
+
# Convert to PDF bytes
|
|
21
|
+
pdf_bytes = oxps_document.convert_to_pdf()
|
|
22
|
+
|
|
23
|
+
# Open the PDF bytes as a new PDF document
|
|
24
|
+
pdf_document = fitz.open("pdf", pdf_bytes)
|
|
25
|
+
|
|
26
|
+
# Save the PDF document to a file
|
|
27
|
+
pdf_document.save(output_pdf)
|
|
28
|
+
|
|
29
|
+
click.echo(f"Successfully converted '{input_oxps}' to '{output_pdf}'")
|
|
30
|
+
|
|
31
|
+
except Exception as e:
|
|
32
|
+
click.echo(f"Error converting file: {e}", err=True)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
import os
|
|
36
|
+
import subprocess
|
|
37
|
+
from pathlib import Path
|
|
38
|
+
from typing import List, Optional
|
|
39
|
+
|
|
40
|
+
DEFAULT_DIRS = ["~/repos/lefv-vault", "~/Documents/OneDrive", "~/Documents/Documents"]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@file.command(name="search")
|
|
44
|
+
@click.argument("search-string", type=str)
|
|
45
|
+
@click.argument("search-dirs", default=DEFAULT_DIRS)
|
|
46
|
+
@click.argument("context-lines", default=3, type=int)
|
|
47
|
+
def find_string_with_fzf(
|
|
48
|
+
search_string: str = "foo",
|
|
49
|
+
search_dirs: Optional[List[str]] = DEFAULT_DIRS,
|
|
50
|
+
context_lines: int = 3,
|
|
51
|
+
) -> List[str]:
|
|
52
|
+
"""
|
|
53
|
+
Search for a string with ripgrep in given directories and select matches with fzf.
|
|
54
|
+
|
|
55
|
+
Parameters:
|
|
56
|
+
search_string (str): The string to search for.
|
|
57
|
+
search_dirs (Optional[List[str]]): Directories to search in. Defaults to a predefined list.
|
|
58
|
+
context_lines (int): Number of lines of context above and below the match.
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
List[str]: List of selected lines with context from fzf.
|
|
62
|
+
"""
|
|
63
|
+
if not search_string.strip():
|
|
64
|
+
raise ValueError("Search string cannot be empty")
|
|
65
|
+
|
|
66
|
+
dirs_to_search = search_dirs or DEFAULT_DIRS
|
|
67
|
+
expanded_dirs = [str(Path(d).expanduser()) for d in dirs_to_search]
|
|
68
|
+
|
|
69
|
+
# Validate directories exist
|
|
70
|
+
valid_dirs = [d for d in expanded_dirs if Path(d).exists()]
|
|
71
|
+
if not valid_dirs:
|
|
72
|
+
raise FileNotFoundError("None of the provided or default directories exist")
|
|
73
|
+
|
|
74
|
+
# Run ripgrep with context lines
|
|
75
|
+
rg_command = ["rg", "--color=always", f"-C{context_lines}", search_string, *valid_dirs]
|
|
76
|
+
|
|
77
|
+
try:
|
|
78
|
+
rg_proc = subprocess.run(rg_command, capture_output=True, text=True, check=True)
|
|
79
|
+
except subprocess.CalledProcessError as e:
|
|
80
|
+
print("No matches found or error running rg.")
|
|
81
|
+
return []
|
|
82
|
+
|
|
83
|
+
# Pipe the output through fzf
|
|
84
|
+
try:
|
|
85
|
+
fzf_proc = subprocess.run(
|
|
86
|
+
["fzf", "--ansi", "--multi"],
|
|
87
|
+
input=rg_proc.stdout,
|
|
88
|
+
capture_output=True,
|
|
89
|
+
text=True,
|
|
90
|
+
check=True,
|
|
91
|
+
)
|
|
92
|
+
selections = fzf_proc.stdout.strip().split("\n")
|
|
93
|
+
return [s for s in selections if s.strip()]
|
|
94
|
+
except subprocess.CalledProcessError:
|
|
95
|
+
# User exited fzf without selection
|
|
96
|
+
return []
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
if __name__ == "__main__":
|
|
100
|
+
file()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
[gcloud]
|
|
2
|
+
default_project = "remote-ws-88" # Default project value
|
|
3
|
+
default_region = "us-west1" # Default region value
|
|
4
|
+
|
|
5
|
+
[workstations]
|
|
6
|
+
cluster = "cluster-cirrus-ws" # Default cluster value
|
|
7
|
+
config = "config-cirrus-ws" # Default config value
|
|
8
|
+
|
|
9
|
+
[instances]
|
|
10
|
+
alpha = "apps-luis-fernandez-de-la-vara"
|
|
11
|
+
|
|
12
|
+
[tcp_tunnel]
|
|
13
|
+
local_host = "127.0.0.1" # Local host for TCP tunnel
|
|
14
|
+
local_port = "2222" # Local port for TCP tunnel
|
|
15
|
+
remote_port = "22" # Remote port for SSH connection
|
|
16
|
+
|
|
17
|
+
[commands.describe]
|
|
18
|
+
command = "describe" # Command for querying workstation details
|
|
19
|
+
|
|
20
|
+
[commands.tunnel]
|
|
21
|
+
command = "start-tcp-tunnel" # Command for establishing TCP tunnel
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
# from mcli.public.mcli.lib.shell.shell import shell_exec, get_shell_script_path
|
|
4
|
+
from mcli.lib.shell.shell import get_shell_script_path, shell_exec
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# Click CLI group renamed to 'gcloud'
|
|
8
|
+
@click.group()
|
|
9
|
+
def gcloud():
|
|
10
|
+
"""gcloud utility - use this to interact with gcloud"""
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@click.command()
|
|
15
|
+
def start():
|
|
16
|
+
"""Start a gcloud instance"""
|
|
17
|
+
scripts_path = get_shell_script_path("gcloud", __file__)
|
|
18
|
+
shell_exec(scripts_path, "start")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@gcloud.command()
|
|
22
|
+
def stop():
|
|
23
|
+
"""Start a gcloud instance"""
|
|
24
|
+
scripts_path = get_shell_script_path("gcloud", __file__)
|
|
25
|
+
shell_exec(scripts_path, "stop")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@gcloud.command()
|
|
29
|
+
def describe():
|
|
30
|
+
"""Start a gcloud instance"""
|
|
31
|
+
scripts_path = get_shell_script_path("gcloud", __file__)
|
|
32
|
+
shell_exec(scripts_path, "describe")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@gcloud.command()
|
|
36
|
+
@click.argument("remote-port", type=str)
|
|
37
|
+
@click.argument("local-port", type=str)
|
|
38
|
+
def tunnel(remote_port: str, local_port: str):
|
|
39
|
+
"""Create an alpha tunnel using the instance"""
|
|
40
|
+
logger.info(f"Creating a tunnel at {remote_port} to local port {local_port}")
|
|
41
|
+
scripts_path = get_shell_script_path("gcloud", __file__)
|
|
42
|
+
shell_exec(scripts_path, "tunnel", remote_port, local_port)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@gcloud.command()
|
|
46
|
+
def login(remote_port: str, local_port: str):
|
|
47
|
+
"""Login to gcloud"""
|
|
48
|
+
logger.info(f"Authenticating into gcloud")
|
|
49
|
+
scripts_path = get_shell_script_path("gcloud", __file__)
|
|
50
|
+
shell_exec(scripts_path, "login", remote_port, local_port)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
gcloud.add_command(start)
|
|
54
|
+
gcloud.add_command(tunnel)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
if __name__ == "__main__":
|
|
58
|
+
gcloud()
|