mcli-framework 7.6.0__py3-none-any.whl → 7.6.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mcli-framework might be problematic. Click here for more details.
- mcli/app/commands_cmd.py +51 -39
- mcli/app/main.py +10 -2
- mcli/app/model_cmd.py +1 -1
- mcli/lib/custom_commands.py +4 -10
- mcli/ml/api/app.py +1 -5
- mcli/ml/dashboard/app.py +2 -2
- mcli/ml/dashboard/app_integrated.py +168 -116
- mcli/ml/dashboard/app_supabase.py +7 -3
- mcli/ml/dashboard/app_training.py +3 -6
- mcli/ml/dashboard/components/charts.py +74 -115
- mcli/ml/dashboard/components/metrics.py +24 -44
- mcli/ml/dashboard/components/tables.py +32 -40
- mcli/ml/dashboard/overview.py +102 -78
- mcli/ml/dashboard/pages/cicd.py +103 -56
- mcli/ml/dashboard/pages/debug_dependencies.py +35 -28
- mcli/ml/dashboard/pages/gravity_viz.py +374 -313
- mcli/ml/dashboard/pages/monte_carlo_predictions.py +50 -48
- mcli/ml/dashboard/pages/predictions_enhanced.py +396 -248
- mcli/ml/dashboard/pages/scrapers_and_logs.py +299 -273
- mcli/ml/dashboard/pages/test_portfolio.py +153 -121
- mcli/ml/dashboard/pages/trading.py +238 -169
- mcli/ml/dashboard/pages/workflows.py +129 -84
- mcli/ml/dashboard/streamlit_extras_utils.py +70 -79
- mcli/ml/dashboard/utils.py +24 -21
- mcli/ml/dashboard/warning_suppression.py +6 -4
- mcli/ml/database/session.py +16 -5
- mcli/ml/mlops/pipeline_orchestrator.py +1 -3
- mcli/ml/predictions/monte_carlo.py +6 -18
- mcli/ml/trading/alpaca_client.py +95 -96
- mcli/ml/trading/migrations.py +76 -40
- mcli/ml/trading/models.py +78 -60
- mcli/ml/trading/paper_trading.py +92 -74
- mcli/ml/trading/risk_management.py +106 -85
- mcli/ml/trading/trading_service.py +155 -110
- mcli/ml/training/train_model.py +1 -3
- mcli/self/self_cmd.py +71 -57
- mcli/workflow/daemon/daemon.py +2 -0
- mcli/workflow/model_service/openai_adapter.py +6 -2
- mcli/workflow/politician_trading/models.py +6 -2
- mcli/workflow/politician_trading/scrapers_corporate_registry.py +39 -88
- mcli/workflow/politician_trading/scrapers_free_sources.py +32 -39
- mcli/workflow/politician_trading/scrapers_third_party.py +21 -39
- mcli/workflow/politician_trading/seed_database.py +70 -89
- {mcli_framework-7.6.0.dist-info → mcli_framework-7.6.2.dist-info}/METADATA +1 -1
- {mcli_framework-7.6.0.dist-info → mcli_framework-7.6.2.dist-info}/RECORD +49 -49
- {mcli_framework-7.6.0.dist-info → mcli_framework-7.6.2.dist-info}/WHEEL +0 -0
- {mcli_framework-7.6.0.dist-info → mcli_framework-7.6.2.dist-info}/entry_points.txt +0 -0
- {mcli_framework-7.6.0.dist-info → mcli_framework-7.6.2.dist-info}/licenses/LICENSE +0 -0
- {mcli_framework-7.6.0.dist-info → mcli_framework-7.6.2.dist-info}/top_level.txt +0 -0
mcli/ml/dashboard/pages/cicd.py
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
"""CI/CD Pipeline Monitoring Dashboard"""
|
|
2
2
|
|
|
3
|
-
import streamlit as st
|
|
4
|
-
import pandas as pd
|
|
5
|
-
import requests
|
|
6
3
|
import os
|
|
7
4
|
from datetime import datetime, timedelta
|
|
8
|
-
import plotly.graph_objects as go
|
|
9
|
-
import plotly.express as px
|
|
10
5
|
from typing import Optional
|
|
11
6
|
|
|
7
|
+
import pandas as pd
|
|
8
|
+
import plotly.express as px
|
|
9
|
+
import plotly.graph_objects as go
|
|
10
|
+
import requests
|
|
11
|
+
import streamlit as st
|
|
12
|
+
|
|
12
13
|
# Import components
|
|
13
14
|
try:
|
|
14
|
-
from ..components.
|
|
15
|
-
from ..components.
|
|
15
|
+
from ..components.charts import create_status_pie_chart, create_timeline_chart, render_chart
|
|
16
|
+
from ..components.metrics import display_health_indicator, display_kpi_row, display_status_badge
|
|
16
17
|
from ..components.tables import display_filterable_dataframe, export_dataframe
|
|
17
18
|
except ImportError:
|
|
18
19
|
# Fallback for when imported outside package context
|
|
19
|
-
from components.
|
|
20
|
-
from components.
|
|
20
|
+
from components.charts import create_status_pie_chart, create_timeline_chart, render_chart
|
|
21
|
+
from components.metrics import display_health_indicator, display_kpi_row, display_status_badge
|
|
21
22
|
from components.tables import display_filterable_dataframe, export_dataframe
|
|
22
23
|
|
|
23
24
|
|
|
@@ -65,21 +66,27 @@ def create_mock_cicd_data() -> pd.DataFrame:
|
|
|
65
66
|
|
|
66
67
|
data = []
|
|
67
68
|
for i in range(50):
|
|
68
|
-
start_time = datetime.now() - timedelta(
|
|
69
|
+
start_time = datetime.now() - timedelta(
|
|
70
|
+
days=random.randint(0, 30), hours=random.randint(0, 23)
|
|
71
|
+
)
|
|
69
72
|
duration = random.randint(60, 600) # seconds
|
|
70
73
|
status = random.choices(statuses, weights=[70, 15, 10, 5])[0]
|
|
71
74
|
|
|
72
|
-
data.append(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
75
|
+
data.append(
|
|
76
|
+
{
|
|
77
|
+
"id": f"build-{i+1}",
|
|
78
|
+
"pipeline_name": random.choice(pipelines),
|
|
79
|
+
"branch": random.choice(branches),
|
|
80
|
+
"status": status,
|
|
81
|
+
"started_at": start_time.isoformat(),
|
|
82
|
+
"duration_sec": duration if status != "running" else None,
|
|
83
|
+
"commit_sha": f"{random.randint(1000000, 9999999):07x}",
|
|
84
|
+
"triggered_by": random.choice(["github-webhook", "manual", "schedule"]),
|
|
85
|
+
"success_rate": (
|
|
86
|
+
random.uniform(0.7, 1.0) if status == "success" else random.uniform(0, 0.5)
|
|
87
|
+
),
|
|
88
|
+
}
|
|
89
|
+
)
|
|
83
90
|
|
|
84
91
|
return pd.DataFrame(data)
|
|
85
92
|
|
|
@@ -104,8 +111,20 @@ def fetch_webhooks() -> list:
|
|
|
104
111
|
|
|
105
112
|
# Return mock data
|
|
106
113
|
return [
|
|
107
|
-
{
|
|
108
|
-
|
|
114
|
+
{
|
|
115
|
+
"id": "wh-1",
|
|
116
|
+
"name": "GitHub Main",
|
|
117
|
+
"url": "https://github.com/user/repo",
|
|
118
|
+
"events": ["push", "pull_request"],
|
|
119
|
+
"active": True,
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"id": "wh-2",
|
|
123
|
+
"name": "GitLab CI",
|
|
124
|
+
"url": "https://gitlab.com/user/repo",
|
|
125
|
+
"events": ["push"],
|
|
126
|
+
"active": True,
|
|
127
|
+
},
|
|
109
128
|
]
|
|
110
129
|
|
|
111
130
|
|
|
@@ -125,6 +144,7 @@ def show_cicd_dashboard():
|
|
|
125
144
|
|
|
126
145
|
if auto_refresh:
|
|
127
146
|
from streamlit_autorefresh import st_autorefresh
|
|
147
|
+
|
|
128
148
|
# Auto-refresh every 30 seconds
|
|
129
149
|
st_autorefresh(interval=30000, key="cicd_refresh")
|
|
130
150
|
|
|
@@ -155,10 +175,18 @@ def show_cicd_dashboard():
|
|
|
155
175
|
|
|
156
176
|
metrics = {
|
|
157
177
|
"Total Builds": {"value": total_builds, "icon": "📦"},
|
|
158
|
-
"Success Rate": {
|
|
178
|
+
"Success Rate": {
|
|
179
|
+
"value": f"{success_rate:.1f}%",
|
|
180
|
+
"delta": "+5.2%",
|
|
181
|
+
"delta_color": "normal",
|
|
182
|
+
"icon": "✅",
|
|
183
|
+
},
|
|
159
184
|
"Failed Builds": {"value": failed_builds, "icon": "❌"},
|
|
160
185
|
"Running": {"value": running_builds, "icon": "🔵"},
|
|
161
|
-
"Avg Duration": {
|
|
186
|
+
"Avg Duration": {
|
|
187
|
+
"value": f"{avg_duration:.0f}s" if pd.notna(avg_duration) else "N/A",
|
|
188
|
+
"icon": "⏱️",
|
|
189
|
+
},
|
|
162
190
|
}
|
|
163
191
|
|
|
164
192
|
display_kpi_row(metrics, columns=5)
|
|
@@ -166,7 +194,9 @@ def show_cicd_dashboard():
|
|
|
166
194
|
st.divider()
|
|
167
195
|
|
|
168
196
|
# === Tabs for different views ===
|
|
169
|
-
tab1, tab2, tab3, tab4 = st.tabs(
|
|
197
|
+
tab1, tab2, tab3, tab4 = st.tabs(
|
|
198
|
+
["📈 Overview", "🔍 Build History", "🔔 Webhooks", "⚙️ Configuration"]
|
|
199
|
+
)
|
|
170
200
|
|
|
171
201
|
with tab1:
|
|
172
202
|
show_cicd_overview(builds_df)
|
|
@@ -199,9 +229,9 @@ def show_cicd_overview(builds_df: pd.DataFrame):
|
|
|
199
229
|
fig = px.bar(
|
|
200
230
|
x=pipeline_counts.values,
|
|
201
231
|
y=pipeline_counts.index,
|
|
202
|
-
orientation=
|
|
232
|
+
orientation="h",
|
|
203
233
|
title="Top Pipelines by Build Count",
|
|
204
|
-
labels={"x": "Number of Builds", "y": "Pipeline"}
|
|
234
|
+
labels={"x": "Number of Builds", "y": "Pipeline"},
|
|
205
235
|
)
|
|
206
236
|
render_chart(fig)
|
|
207
237
|
|
|
@@ -211,9 +241,11 @@ def show_cicd_overview(builds_df: pd.DataFrame):
|
|
|
211
241
|
if "started_at" in builds_df.columns and "status" in builds_df.columns:
|
|
212
242
|
# Group by date and calculate success rate
|
|
213
243
|
builds_df["date"] = builds_df["started_at"].dt.date
|
|
214
|
-
daily_stats =
|
|
215
|
-
|
|
216
|
-
|
|
244
|
+
daily_stats = (
|
|
245
|
+
builds_df.groupby("date")
|
|
246
|
+
.agg({"status": lambda x: (x == "success").sum() / len(x) * 100})
|
|
247
|
+
.reset_index()
|
|
248
|
+
)
|
|
217
249
|
daily_stats.columns = ["date", "success_rate"]
|
|
218
250
|
|
|
219
251
|
fig = px.line(
|
|
@@ -222,7 +254,7 @@ def show_cicd_overview(builds_df: pd.DataFrame):
|
|
|
222
254
|
y="success_rate",
|
|
223
255
|
title="Daily Success Rate",
|
|
224
256
|
labels={"date": "Date", "success_rate": "Success Rate (%)"},
|
|
225
|
-
markers=True
|
|
257
|
+
markers=True,
|
|
226
258
|
)
|
|
227
259
|
fig.add_hline(y=90, line_dash="dash", line_color="green", annotation_text="Target: 90%")
|
|
228
260
|
render_chart(fig)
|
|
@@ -242,7 +274,7 @@ def show_cicd_overview(builds_df: pd.DataFrame):
|
|
|
242
274
|
y="duration_min",
|
|
243
275
|
color="pipeline_name",
|
|
244
276
|
title="Build Duration Over Time",
|
|
245
|
-
labels={"started_at": "Time", "duration_min": "Duration (minutes)"}
|
|
277
|
+
labels={"started_at": "Time", "duration_min": "Duration (minutes)"},
|
|
246
278
|
)
|
|
247
279
|
render_chart(fig)
|
|
248
280
|
|
|
@@ -256,13 +288,11 @@ def show_build_history(builds_df: pd.DataFrame):
|
|
|
256
288
|
filter_config = {
|
|
257
289
|
"pipeline_name": "multiselect",
|
|
258
290
|
"status": "multiselect",
|
|
259
|
-
"branch": "multiselect"
|
|
291
|
+
"branch": "multiselect",
|
|
260
292
|
}
|
|
261
293
|
|
|
262
294
|
filtered_df = display_filterable_dataframe(
|
|
263
|
-
builds_df,
|
|
264
|
-
filter_columns=filter_config,
|
|
265
|
-
key_prefix="cicd_filter"
|
|
295
|
+
builds_df, filter_columns=filter_config, key_prefix="cicd_filter"
|
|
266
296
|
)
|
|
267
297
|
|
|
268
298
|
# Export option
|
|
@@ -274,7 +304,9 @@ def show_build_history(builds_df: pd.DataFrame):
|
|
|
274
304
|
|
|
275
305
|
if not filtered_df.empty:
|
|
276
306
|
for _, build in filtered_df.head(20).iterrows():
|
|
277
|
-
with st.expander(
|
|
307
|
+
with st.expander(
|
|
308
|
+
f"{build.get('pipeline_name', 'Unknown')} - {build.get('commit_sha', 'Unknown')[:7]} - {display_status_badge(build.get('status', 'unknown'), 'small')}"
|
|
309
|
+
):
|
|
278
310
|
col1, col2 = st.columns(2)
|
|
279
311
|
|
|
280
312
|
with col1:
|
|
@@ -284,20 +316,27 @@ def show_build_history(builds_df: pd.DataFrame):
|
|
|
284
316
|
st.markdown(f"**Triggered By:** {build.get('triggered_by', 'N/A')}")
|
|
285
317
|
|
|
286
318
|
with col2:
|
|
287
|
-
st.markdown(
|
|
319
|
+
st.markdown(
|
|
320
|
+
f"**Status:** {display_status_badge(build.get('status', 'unknown'), 'small')}"
|
|
321
|
+
)
|
|
288
322
|
st.markdown(f"**Started:** {build.get('started_at', 'N/A')}")
|
|
289
|
-
if pd.notna(build.get(
|
|
290
|
-
st.markdown(
|
|
323
|
+
if pd.notna(build.get("duration_sec")):
|
|
324
|
+
st.markdown(
|
|
325
|
+
f"**Duration:** {build['duration_sec']}s ({build['duration_sec']/60:.1f}m)"
|
|
326
|
+
)
|
|
291
327
|
|
|
292
328
|
# Mock logs
|
|
293
329
|
if st.button(f"View Logs", key=f"logs_{build.get('id')}"):
|
|
294
|
-
st.code(
|
|
330
|
+
st.code(
|
|
331
|
+
f"""
|
|
295
332
|
[INFO] Starting build for {build.get('pipeline_name')}
|
|
296
333
|
[INFO] Checking out branch: {build.get('branch')}
|
|
297
334
|
[INFO] Installing dependencies...
|
|
298
335
|
[INFO] Running tests...
|
|
299
336
|
[INFO] Build {'completed successfully' if build.get('status') == 'success' else 'failed'}
|
|
300
|
-
""",
|
|
337
|
+
""",
|
|
338
|
+
language="bash",
|
|
339
|
+
)
|
|
301
340
|
|
|
302
341
|
|
|
303
342
|
def show_webhooks_config():
|
|
@@ -312,7 +351,9 @@ def show_webhooks_config():
|
|
|
312
351
|
return
|
|
313
352
|
|
|
314
353
|
for webhook in webhooks:
|
|
315
|
-
with st.expander(
|
|
354
|
+
with st.expander(
|
|
355
|
+
f"{webhook['name']} - {'✅ Active' if webhook['active'] else '❌ Inactive'}"
|
|
356
|
+
):
|
|
316
357
|
st.markdown(f"**URL:** `{webhook['url']}`")
|
|
317
358
|
st.markdown(f"**Events:** {', '.join(webhook['events'])}")
|
|
318
359
|
st.markdown(f"**Status:** {'Active' if webhook['active'] else 'Inactive'}")
|
|
@@ -351,8 +392,12 @@ def show_cicd_configuration():
|
|
|
351
392
|
with st.form("cicd_config"):
|
|
352
393
|
st.markdown("#### Pipeline Settings")
|
|
353
394
|
|
|
354
|
-
max_concurrent_builds = st.number_input(
|
|
355
|
-
|
|
395
|
+
max_concurrent_builds = st.number_input(
|
|
396
|
+
"Max Concurrent Builds", min_value=1, max_value=10, value=3
|
|
397
|
+
)
|
|
398
|
+
build_timeout = st.number_input(
|
|
399
|
+
"Build Timeout (minutes)", min_value=5, max_value=120, value=30
|
|
400
|
+
)
|
|
356
401
|
retry_failed_builds = st.checkbox("Auto-retry Failed Builds", value=True)
|
|
357
402
|
max_retries = st.number_input("Max Retries", min_value=1, max_value=5, value=2)
|
|
358
403
|
|
|
@@ -365,17 +410,19 @@ def show_cicd_configuration():
|
|
|
365
410
|
|
|
366
411
|
if submitted:
|
|
367
412
|
st.success("✅ Configuration saved successfully!")
|
|
368
|
-
st.json(
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
"
|
|
375
|
-
|
|
376
|
-
|
|
413
|
+
st.json(
|
|
414
|
+
{
|
|
415
|
+
"max_concurrent_builds": max_concurrent_builds,
|
|
416
|
+
"build_timeout_minutes": build_timeout,
|
|
417
|
+
"retry_failed_builds": retry_failed_builds,
|
|
418
|
+
"max_retries": max_retries,
|
|
419
|
+
"notifications": {
|
|
420
|
+
"on_success": notify_on_success,
|
|
421
|
+
"on_failure": notify_on_failure,
|
|
422
|
+
"email": notification_email,
|
|
423
|
+
},
|
|
377
424
|
}
|
|
378
|
-
|
|
425
|
+
)
|
|
379
426
|
|
|
380
427
|
|
|
381
428
|
if __name__ == "__main__":
|
|
@@ -1,36 +1,44 @@
|
|
|
1
1
|
"""Debug Dependencies - Diagnostic page for troubleshooting installation issues"""
|
|
2
2
|
|
|
3
|
-
import streamlit as st
|
|
4
|
-
import sys
|
|
5
3
|
import subprocess
|
|
4
|
+
import sys
|
|
6
5
|
from pathlib import Path
|
|
7
6
|
from typing import Dict, List, Tuple
|
|
8
7
|
|
|
8
|
+
import streamlit as st
|
|
9
|
+
|
|
9
10
|
|
|
10
11
|
def show_debug_dependencies():
|
|
11
12
|
"""Diagnostic page for dependency debugging"""
|
|
12
13
|
|
|
13
14
|
st.title("🔍 Dependency Diagnostics")
|
|
14
|
-
st.markdown(
|
|
15
|
+
st.markdown(
|
|
16
|
+
"""
|
|
15
17
|
This page helps diagnose why certain dependencies (like alpaca-py) may not be installing correctly.
|
|
16
|
-
"""
|
|
18
|
+
"""
|
|
19
|
+
)
|
|
17
20
|
|
|
18
21
|
# Python environment info
|
|
19
22
|
st.header("🐍 Python Environment")
|
|
20
23
|
|
|
21
24
|
col1, col2 = st.columns(2)
|
|
22
25
|
with col1:
|
|
23
|
-
st.metric(
|
|
26
|
+
st.metric(
|
|
27
|
+
"Python Version",
|
|
28
|
+
f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
|
|
29
|
+
)
|
|
24
30
|
with col2:
|
|
25
31
|
st.metric("Platform", sys.platform)
|
|
26
32
|
|
|
27
33
|
with st.expander("📋 Detailed Python Info", expanded=False):
|
|
28
|
-
st.code(
|
|
34
|
+
st.code(
|
|
35
|
+
f"""
|
|
29
36
|
Python Version: {sys.version}
|
|
30
37
|
Python Path: {sys.executable}
|
|
31
38
|
Prefix: {sys.prefix}
|
|
32
39
|
Platform: {sys.platform}
|
|
33
|
-
"""
|
|
40
|
+
"""
|
|
41
|
+
)
|
|
34
42
|
|
|
35
43
|
# Check Python paths
|
|
36
44
|
st.header("📁 Python Paths")
|
|
@@ -92,9 +100,11 @@ Platform: {sys.platform}
|
|
|
92
100
|
# Detailed alpaca-py investigation
|
|
93
101
|
st.header("🔬 Alpaca-py Deep Dive")
|
|
94
102
|
|
|
95
|
-
st.markdown(
|
|
103
|
+
st.markdown(
|
|
104
|
+
"""
|
|
96
105
|
Attempting to import alpaca-py components individually to identify specific failure points.
|
|
97
|
-
"""
|
|
106
|
+
"""
|
|
107
|
+
)
|
|
98
108
|
|
|
99
109
|
alpaca_submodules = [
|
|
100
110
|
"alpaca",
|
|
@@ -146,20 +156,14 @@ Platform: {sys.platform}
|
|
|
146
156
|
|
|
147
157
|
for pm_name, pm_command in package_managers:
|
|
148
158
|
try:
|
|
149
|
-
result = subprocess.run(
|
|
150
|
-
pm_command,
|
|
151
|
-
capture_output=True,
|
|
152
|
-
text=True,
|
|
153
|
-
timeout=10
|
|
154
|
-
)
|
|
159
|
+
result = subprocess.run(pm_command, capture_output=True, text=True, timeout=10)
|
|
155
160
|
|
|
156
161
|
if result.returncode == 0:
|
|
157
162
|
packages_found = True
|
|
158
163
|
|
|
159
164
|
# Search for alpaca-related packages
|
|
160
165
|
alpaca_packages = [
|
|
161
|
-
line for line in result.stdout.split("\n")
|
|
162
|
-
if "alpaca" in line.lower()
|
|
166
|
+
line for line in result.stdout.split("\n") if "alpaca" in line.lower()
|
|
163
167
|
]
|
|
164
168
|
|
|
165
169
|
if alpaca_packages:
|
|
@@ -193,12 +197,7 @@ Platform: {sys.platform}
|
|
|
193
197
|
|
|
194
198
|
for pm_name, pm_command in show_commands:
|
|
195
199
|
try:
|
|
196
|
-
result = subprocess.run(
|
|
197
|
-
pm_command,
|
|
198
|
-
capture_output=True,
|
|
199
|
-
text=True,
|
|
200
|
-
timeout=10
|
|
201
|
-
)
|
|
200
|
+
result = subprocess.run(pm_command, capture_output=True, text=True, timeout=10)
|
|
202
201
|
|
|
203
202
|
if result.returncode == 0:
|
|
204
203
|
package_info_found = True
|
|
@@ -208,6 +207,7 @@ Platform: {sys.platform}
|
|
|
208
207
|
# Try to get the version from import
|
|
209
208
|
try:
|
|
210
209
|
import alpaca
|
|
210
|
+
|
|
211
211
|
if hasattr(alpaca, "__version__"):
|
|
212
212
|
st.info(f"📦 Alpaca version from import: {alpaca.__version__}")
|
|
213
213
|
except:
|
|
@@ -224,6 +224,7 @@ Platform: {sys.platform}
|
|
|
224
224
|
# Check if imports work anyway
|
|
225
225
|
try:
|
|
226
226
|
import alpaca
|
|
227
|
+
|
|
227
228
|
st.success("✅ Alpaca module imports successfully!")
|
|
228
229
|
if hasattr(alpaca, "__version__"):
|
|
229
230
|
st.info(f"📦 Version from import: {alpaca.__version__}")
|
|
@@ -276,6 +277,7 @@ Platform: {sys.platform}
|
|
|
276
277
|
st.markdown("Checking for relevant environment variables:")
|
|
277
278
|
|
|
278
279
|
import os
|
|
280
|
+
|
|
279
281
|
for var in env_vars_to_check:
|
|
280
282
|
value = os.environ.get(var)
|
|
281
283
|
if value:
|
|
@@ -296,13 +298,15 @@ Platform: {sys.platform}
|
|
|
296
298
|
|
|
297
299
|
if is_cloud:
|
|
298
300
|
st.success("✅ Running on Streamlit Cloud")
|
|
299
|
-
st.info(
|
|
301
|
+
st.info(
|
|
302
|
+
"""
|
|
300
303
|
**Note:** On Streamlit Cloud, packages are installed from requirements.txt during deployment.
|
|
301
304
|
If alpaca-py is not installed, check:
|
|
302
305
|
1. requirements.txt has correct package name and version
|
|
303
306
|
2. Package has no conflicting dependencies
|
|
304
307
|
3. Deployment logs for installation errors
|
|
305
|
-
"""
|
|
308
|
+
"""
|
|
309
|
+
)
|
|
306
310
|
else:
|
|
307
311
|
st.info("ℹ️ Running locally (not Streamlit Cloud)")
|
|
308
312
|
|
|
@@ -328,7 +332,8 @@ Platform: {sys.platform}
|
|
|
328
332
|
st.header("🛠️ Troubleshooting Guide")
|
|
329
333
|
|
|
330
334
|
with st.expander("🔧 Common Solutions", expanded=True):
|
|
331
|
-
st.markdown(
|
|
335
|
+
st.markdown(
|
|
336
|
+
"""
|
|
332
337
|
### If alpaca-py import fails:
|
|
333
338
|
|
|
334
339
|
#### 1. Check Requirements.txt
|
|
@@ -372,7 +377,8 @@ Platform: {sys.platform}
|
|
|
372
377
|
pip uninstall alpaca-py -y
|
|
373
378
|
pip install alpaca-py>=0.20.0
|
|
374
379
|
```
|
|
375
|
-
"""
|
|
380
|
+
"""
|
|
381
|
+
)
|
|
376
382
|
|
|
377
383
|
# Export diagnostics
|
|
378
384
|
st.header("💾 Export Diagnostics")
|
|
@@ -394,7 +400,7 @@ Generated: {pd.Timestamp.now()}
|
|
|
394
400
|
diagnostics += f"\n- {module_name}: {status}\n Info: {info}\n"
|
|
395
401
|
|
|
396
402
|
diagnostics += "\n## Installed Packages\n"
|
|
397
|
-
if
|
|
403
|
+
if "result" in locals() and result.returncode == 0:
|
|
398
404
|
diagnostics += result.stdout
|
|
399
405
|
|
|
400
406
|
st.code(diagnostics)
|
|
@@ -403,4 +409,5 @@ Generated: {pd.Timestamp.now()}
|
|
|
403
409
|
|
|
404
410
|
if __name__ == "__main__":
|
|
405
411
|
import pandas as pd
|
|
412
|
+
|
|
406
413
|
show_debug_dependencies()
|