mcli-framework 7.3.1__py3-none-any.whl → 7.4.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/commands_cmd.py +741 -0
- mcli/ml/dashboard/app_integrated.py +286 -37
- mcli/ml/dashboard/app_training.py +1 -1
- mcli/ml/dashboard/pages/cicd.py +1 -1
- mcli/ml/dashboard/pages/debug_dependencies.py +364 -0
- mcli/ml/dashboard/pages/gravity_viz.py +565 -0
- mcli/ml/dashboard/pages/monte_carlo_predictions.py +555 -0
- mcli/ml/dashboard/pages/overview.py +378 -0
- mcli/ml/dashboard/pages/scrapers_and_logs.py +22 -6
- mcli/ml/dashboard/pages/test_portfolio.py +54 -4
- mcli/ml/dashboard/pages/trading.py +80 -26
- mcli/ml/dashboard/streamlit_extras_utils.py +297 -0
- mcli/ml/dashboard/utils.py +7 -0
- mcli/ml/dashboard/warning_suppression.py +34 -0
- mcli/ml/database/session.py +169 -16
- mcli/ml/predictions/monte_carlo.py +428 -0
- mcli/ml/trading/__init__.py +7 -1
- mcli/ml/trading/alpaca_client.py +82 -18
- mcli/self/self_cmd.py +263 -24
- {mcli_framework-7.3.1.dist-info → mcli_framework-7.4.0.dist-info}/METADATA +3 -2
- {mcli_framework-7.3.1.dist-info → mcli_framework-7.4.0.dist-info}/RECORD +25 -18
- {mcli_framework-7.3.1.dist-info → mcli_framework-7.4.0.dist-info}/WHEEL +0 -0
- {mcli_framework-7.3.1.dist-info → mcli_framework-7.4.0.dist-info}/entry_points.txt +0 -0
- {mcli_framework-7.3.1.dist-info → mcli_framework-7.4.0.dist-info}/licenses/LICENSE +0 -0
- {mcli_framework-7.3.1.dist-info → mcli_framework-7.4.0.dist-info}/top_level.txt +0 -0
|
@@ -6,13 +6,37 @@ import logging
|
|
|
6
6
|
import os
|
|
7
7
|
import pickle
|
|
8
8
|
import subprocess
|
|
9
|
+
import warnings
|
|
9
10
|
from datetime import datetime, timedelta
|
|
10
11
|
from pathlib import Path
|
|
11
12
|
from typing import List
|
|
12
13
|
|
|
13
14
|
import numpy as np
|
|
14
15
|
|
|
16
|
+
# Suppress Streamlit warnings when used outside runtime context
|
|
17
|
+
warnings.filterwarnings("ignore", message=".*missing ScriptRunContext.*")
|
|
18
|
+
warnings.filterwarnings("ignore", message=".*No runtime found.*")
|
|
19
|
+
warnings.filterwarnings("ignore", message=".*Session state does not function.*")
|
|
20
|
+
warnings.filterwarnings("ignore", message=".*to view this Streamlit app.*")
|
|
21
|
+
|
|
22
|
+
# Suppress Plotly deprecation warnings
|
|
23
|
+
warnings.filterwarnings("ignore", message=".*keyword arguments have been deprecated.*")
|
|
24
|
+
warnings.filterwarnings("ignore", message=".*Use `config` instead.*")
|
|
25
|
+
|
|
26
|
+
# Suppress media file errors
|
|
27
|
+
warnings.filterwarnings("ignore", message=".*MediaFileHandler.*")
|
|
28
|
+
warnings.filterwarnings("ignore", message=".*Missing file.*")
|
|
29
|
+
warnings.filterwarnings("ignore", message=".*Bad filename.*")
|
|
30
|
+
|
|
31
|
+
# Suppress additional warnings
|
|
32
|
+
warnings.filterwarnings("ignore", category=UserWarning)
|
|
33
|
+
warnings.filterwarnings("ignore", category=FutureWarning)
|
|
34
|
+
|
|
15
35
|
logger = logging.getLogger(__name__)
|
|
36
|
+
|
|
37
|
+
# Suppress specific Streamlit media file errors in logging
|
|
38
|
+
logging.getLogger("streamlit.runtime.media_file_storage").setLevel(logging.ERROR)
|
|
39
|
+
logging.getLogger("streamlit.web.server.media_file_handler").setLevel(logging.ERROR)
|
|
16
40
|
import pandas as pd
|
|
17
41
|
import plotly.express as px
|
|
18
42
|
import plotly.graph_objects as go
|
|
@@ -25,6 +49,26 @@ from supabase import Client, create_client
|
|
|
25
49
|
# Load environment variables from .env file
|
|
26
50
|
load_dotenv()
|
|
27
51
|
|
|
52
|
+
# Import streamlit-extras utilities
|
|
53
|
+
try:
|
|
54
|
+
from mcli.ml.dashboard.streamlit_extras_utils import (
|
|
55
|
+
enhanced_metrics,
|
|
56
|
+
section_header,
|
|
57
|
+
vertical_space,
|
|
58
|
+
data_quality_indicators,
|
|
59
|
+
trading_status_card,
|
|
60
|
+
)
|
|
61
|
+
HAS_STREAMLIT_EXTRAS = True
|
|
62
|
+
except (ImportError, KeyError, ModuleNotFoundError) as e:
|
|
63
|
+
HAS_STREAMLIT_EXTRAS = False
|
|
64
|
+
enhanced_metrics = None
|
|
65
|
+
section_header = None
|
|
66
|
+
vertical_space = None
|
|
67
|
+
data_quality_indicators = None
|
|
68
|
+
trading_status_card = None
|
|
69
|
+
# Suppress warning for now - this is handled gracefully
|
|
70
|
+
# st.warning(f"Streamlit-extras utilities not available: {e}")
|
|
71
|
+
|
|
28
72
|
# Add ML pipeline imports
|
|
29
73
|
try:
|
|
30
74
|
from mcli.ml.models import get_model_by_id
|
|
@@ -46,30 +90,136 @@ except ImportError:
|
|
|
46
90
|
PoliticianTradingPredictor = None
|
|
47
91
|
|
|
48
92
|
# Add new dashboard pages
|
|
93
|
+
HAS_OVERVIEW_PAGE = False
|
|
94
|
+
HAS_PREDICTIONS_ENHANCED = False
|
|
95
|
+
HAS_SCRAPERS_PAGE = False
|
|
96
|
+
HAS_TRADING_PAGES = False
|
|
97
|
+
HAS_MONTE_CARLO_PAGE = False
|
|
98
|
+
HAS_CICD_PAGE = False
|
|
99
|
+
HAS_WORKFLOWS_PAGE = False
|
|
100
|
+
HAS_DEBUG_PAGE = False
|
|
101
|
+
|
|
102
|
+
show_overview = None
|
|
103
|
+
show_cicd_dashboard = None
|
|
104
|
+
show_workflows_dashboard = None
|
|
105
|
+
show_predictions_enhanced = None
|
|
106
|
+
show_scrapers_and_logs = None
|
|
107
|
+
show_trading_dashboard = None
|
|
108
|
+
show_test_portfolio = None
|
|
109
|
+
show_monte_carlo_predictions = None
|
|
110
|
+
show_debug_dependencies = None
|
|
111
|
+
|
|
112
|
+
# Import Overview page
|
|
113
|
+
try:
|
|
114
|
+
from mcli.ml.dashboard.pages.overview import show_overview
|
|
115
|
+
HAS_OVERVIEW_PAGE = True
|
|
116
|
+
except (ImportError, KeyError, ModuleNotFoundError) as e:
|
|
117
|
+
st.warning(f"Overview page not available: {e}")
|
|
118
|
+
|
|
49
119
|
try:
|
|
50
|
-
from mcli.ml.dashboard.pages.cicd import show_cicd_dashboard
|
|
51
|
-
from mcli.ml.dashboard.pages.workflows import show_workflows_dashboard
|
|
52
120
|
from mcli.ml.dashboard.pages.predictions_enhanced import show_predictions_enhanced
|
|
121
|
+
HAS_PREDICTIONS_ENHANCED = True
|
|
122
|
+
except (ImportError, KeyError, ModuleNotFoundError) as e:
|
|
123
|
+
st.warning(f"Predictions Enhanced page not available: {e}")
|
|
124
|
+
|
|
125
|
+
try:
|
|
53
126
|
from mcli.ml.dashboard.pages.scrapers_and_logs import show_scrapers_and_logs
|
|
127
|
+
HAS_SCRAPERS_PAGE = True
|
|
128
|
+
except (ImportError, KeyError, ModuleNotFoundError) as e:
|
|
129
|
+
st.warning(f"Scrapers & Logs page not available: {e}")
|
|
130
|
+
|
|
131
|
+
try:
|
|
132
|
+
import sys
|
|
133
|
+
import traceback
|
|
134
|
+
|
|
135
|
+
# Verbose logging for alpaca-py debugging
|
|
136
|
+
st.info("🔍 Attempting to import trading pages (alpaca-py dependent)...")
|
|
137
|
+
|
|
138
|
+
# First, try importing alpaca directly to see the specific error
|
|
139
|
+
try:
|
|
140
|
+
import alpaca
|
|
141
|
+
st.success(f"✅ alpaca module imported successfully")
|
|
142
|
+
if hasattr(alpaca, "__version__"):
|
|
143
|
+
st.info(f"Alpaca version: {alpaca.__version__}")
|
|
144
|
+
if hasattr(alpaca, "__file__"):
|
|
145
|
+
st.caption(f"Alpaca location: {alpaca.__file__}")
|
|
146
|
+
except ImportError as alpaca_error:
|
|
147
|
+
st.error(f"❌ Failed to import alpaca module: {alpaca_error}")
|
|
148
|
+
with st.expander("🔬 Detailed alpaca import error"):
|
|
149
|
+
st.code(traceback.format_exc())
|
|
150
|
+
|
|
151
|
+
# Try to provide diagnostic info
|
|
152
|
+
st.warning("💡 Troubleshooting tips:")
|
|
153
|
+
st.markdown("""
|
|
154
|
+
- Check that `alpaca-py>=0.20.0` is in requirements.txt
|
|
155
|
+
- Verify Python version is 3.8+ (current: {}.{})
|
|
156
|
+
- Check Streamlit Cloud deployment logs for installation errors
|
|
157
|
+
- Visit the **Debug Dependencies** page for detailed diagnostics
|
|
158
|
+
""".format(sys.version_info.major, sys.version_info.minor))
|
|
159
|
+
|
|
160
|
+
# Now try importing the trading pages
|
|
54
161
|
from mcli.ml.dashboard.pages.trading import show_trading_dashboard
|
|
55
162
|
from mcli.ml.dashboard.pages.test_portfolio import show_test_portfolio
|
|
163
|
+
HAS_TRADING_PAGES = True
|
|
164
|
+
st.success("✅ Trading pages imported successfully!")
|
|
56
165
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
166
|
+
except (ImportError, KeyError, ModuleNotFoundError) as e:
|
|
167
|
+
st.error(f"❌ Trading pages not available: {e}")
|
|
168
|
+
with st.expander("📋 Full error traceback"):
|
|
169
|
+
st.code(traceback.format_exc())
|
|
170
|
+
|
|
171
|
+
# Show installed packages related to alpaca
|
|
172
|
+
try:
|
|
173
|
+
import subprocess
|
|
174
|
+
result = subprocess.run(
|
|
175
|
+
["pip", "list"],
|
|
176
|
+
capture_output=True,
|
|
177
|
+
text=True,
|
|
178
|
+
timeout=5
|
|
179
|
+
)
|
|
180
|
+
alpaca_packages = [line for line in result.stdout.split("\n") if "alpaca" in line.lower()]
|
|
181
|
+
if alpaca_packages:
|
|
182
|
+
st.info("📦 Found alpaca-related packages:")
|
|
183
|
+
for pkg in alpaca_packages:
|
|
184
|
+
st.code(pkg)
|
|
185
|
+
else:
|
|
186
|
+
st.warning("⚠️ No alpaca-related packages found in pip list")
|
|
187
|
+
|
|
188
|
+
# Show full pip list for debugging
|
|
189
|
+
with st.expander("🔍 Full pip list (for debugging)"):
|
|
190
|
+
st.code(result.stdout, language="text")
|
|
191
|
+
except Exception as pip_error:
|
|
192
|
+
st.caption(f"Could not check installed packages: {pip_error}")
|
|
193
|
+
|
|
194
|
+
try:
|
|
195
|
+
from mcli.ml.dashboard.pages.monte_carlo_predictions import show_monte_carlo_predictions
|
|
196
|
+
HAS_MONTE_CARLO_PAGE = True
|
|
197
|
+
except (ImportError, KeyError, ModuleNotFoundError) as e:
|
|
198
|
+
HAS_MONTE_CARLO_PAGE = False
|
|
199
|
+
|
|
200
|
+
# Import CI/CD and Workflows pages
|
|
201
|
+
try:
|
|
202
|
+
from mcli.ml.dashboard.pages.cicd import show_cicd_dashboard
|
|
203
|
+
HAS_CICD_PAGE = True
|
|
204
|
+
except (ImportError, KeyError, ModuleNotFoundError) as e:
|
|
205
|
+
st.warning(f"CI/CD page not available: {e}")
|
|
206
|
+
|
|
207
|
+
try:
|
|
208
|
+
from mcli.ml.dashboard.pages.workflows import show_workflows_dashboard
|
|
209
|
+
HAS_WORKFLOWS_PAGE = True
|
|
210
|
+
except (ImportError, KeyError, ModuleNotFoundError) as e:
|
|
211
|
+
st.warning(f"Workflows page not available: {e}")
|
|
212
|
+
|
|
213
|
+
# Import Debug Dependencies page (always available for troubleshooting)
|
|
214
|
+
try:
|
|
215
|
+
from mcli.ml.dashboard.pages.debug_dependencies import show_debug_dependencies
|
|
216
|
+
HAS_DEBUG_PAGE = True
|
|
217
|
+
except (ImportError, KeyError, ModuleNotFoundError) as e:
|
|
218
|
+
st.warning(f"Debug Dependencies page not available: {e}")
|
|
69
219
|
|
|
70
220
|
# Page config
|
|
71
221
|
st.set_page_config(
|
|
72
|
-
page_title="
|
|
222
|
+
page_title="Politician Trading Tracker - MCLI",
|
|
73
223
|
page_icon="📊",
|
|
74
224
|
layout="wide",
|
|
75
225
|
initial_sidebar_state="expanded",
|
|
@@ -811,15 +961,37 @@ def get_model_metrics():
|
|
|
811
961
|
|
|
812
962
|
def main():
|
|
813
963
|
"""Main dashboard function"""
|
|
964
|
+
|
|
965
|
+
# Clear any problematic session state that might cause media file errors
|
|
966
|
+
try:
|
|
967
|
+
# Remove any file-related session state that might be causing issues
|
|
968
|
+
keys_to_remove = []
|
|
969
|
+
for key in st.session_state.keys():
|
|
970
|
+
if 'file' in key.lower() or 'download' in key.lower() or 'media' in key.lower():
|
|
971
|
+
keys_to_remove.append(key)
|
|
972
|
+
|
|
973
|
+
for key in keys_to_remove:
|
|
974
|
+
if key in st.session_state:
|
|
975
|
+
del st.session_state[key]
|
|
976
|
+
except Exception:
|
|
977
|
+
# Ignore errors when clearing session state
|
|
978
|
+
pass
|
|
814
979
|
|
|
815
980
|
# Title and header
|
|
816
|
-
st.title("
|
|
817
|
-
st.markdown("
|
|
981
|
+
st.title("📊 Politician Trading Tracker")
|
|
982
|
+
st.markdown("Track, Analyze & Replicate Congressional Trading Patterns")
|
|
818
983
|
|
|
819
984
|
# Sidebar
|
|
820
985
|
st.sidebar.title("Navigation")
|
|
821
986
|
# Build page list
|
|
822
|
-
pages = [
|
|
987
|
+
pages = []
|
|
988
|
+
|
|
989
|
+
# Add Overview as first page if available
|
|
990
|
+
if HAS_OVERVIEW_PAGE:
|
|
991
|
+
pages.append("Overview")
|
|
992
|
+
|
|
993
|
+
# Add other pages
|
|
994
|
+
pages.extend([
|
|
823
995
|
"Pipeline Overview",
|
|
824
996
|
"ML Processing",
|
|
825
997
|
"Model Performance",
|
|
@@ -829,24 +1001,37 @@ def main():
|
|
|
829
1001
|
"Test Portfolio",
|
|
830
1002
|
"LSH Jobs",
|
|
831
1003
|
"System Health",
|
|
832
|
-
]
|
|
1004
|
+
])
|
|
833
1005
|
|
|
834
1006
|
# Add scrapers and logs page
|
|
835
1007
|
if HAS_SCRAPERS_PAGE:
|
|
836
1008
|
pages.append("Scrapers & Logs")
|
|
837
1009
|
|
|
838
|
-
# Add
|
|
839
|
-
if
|
|
840
|
-
pages.
|
|
841
|
-
|
|
1010
|
+
# Add Monte Carlo predictions page
|
|
1011
|
+
if HAS_MONTE_CARLO_PAGE:
|
|
1012
|
+
pages.append("Monte Carlo Predictions")
|
|
1013
|
+
|
|
1014
|
+
# Add CI/CD page if available
|
|
1015
|
+
if HAS_CICD_PAGE:
|
|
1016
|
+
pages.append("CI/CD Pipelines")
|
|
1017
|
+
|
|
1018
|
+
# Add Workflows page if available
|
|
1019
|
+
if HAS_WORKFLOWS_PAGE:
|
|
1020
|
+
pages.append("Workflows")
|
|
1021
|
+
|
|
1022
|
+
# Add Debug Dependencies page (always useful for troubleshooting)
|
|
1023
|
+
if HAS_DEBUG_PAGE:
|
|
1024
|
+
pages.append("Debug Dependencies")
|
|
1025
|
+
|
|
842
1026
|
page = st.sidebar.selectbox(
|
|
843
1027
|
"Choose a page",
|
|
844
1028
|
pages,
|
|
845
1029
|
index=0, # Default to Pipeline Overview
|
|
1030
|
+
key="main_page_selector"
|
|
846
1031
|
)
|
|
847
1032
|
|
|
848
1033
|
# Auto-refresh toggle (default off to prevent blocking)
|
|
849
|
-
auto_refresh = st.sidebar.checkbox("Auto-refresh (30s)", value=
|
|
1034
|
+
auto_refresh = st.sidebar.checkbox("Auto-refresh (30s)", value=True)
|
|
850
1035
|
if auto_refresh:
|
|
851
1036
|
try:
|
|
852
1037
|
from streamlit_autorefresh import st_autorefresh
|
|
@@ -873,7 +1058,12 @@ def main():
|
|
|
873
1058
|
|
|
874
1059
|
# Main content with error handling
|
|
875
1060
|
try:
|
|
876
|
-
if page == "
|
|
1061
|
+
if page == "Overview":
|
|
1062
|
+
if HAS_OVERVIEW_PAGE and show_overview:
|
|
1063
|
+
show_overview()
|
|
1064
|
+
else:
|
|
1065
|
+
st.error("Overview page not available")
|
|
1066
|
+
elif page == "Pipeline Overview":
|
|
877
1067
|
show_pipeline_overview()
|
|
878
1068
|
elif page == "ML Processing":
|
|
879
1069
|
show_ml_processing()
|
|
@@ -883,30 +1073,82 @@ def main():
|
|
|
883
1073
|
show_model_training_evaluation()
|
|
884
1074
|
elif page == "Predictions":
|
|
885
1075
|
# Use enhanced predictions page if available, otherwise fallback
|
|
886
|
-
if
|
|
1076
|
+
if HAS_PREDICTIONS_ENHANCED and show_predictions_enhanced:
|
|
887
1077
|
show_predictions_enhanced()
|
|
888
1078
|
else:
|
|
889
1079
|
show_predictions()
|
|
890
1080
|
elif page == "Trading Dashboard":
|
|
891
|
-
if
|
|
892
|
-
|
|
1081
|
+
if HAS_TRADING_PAGES and show_trading_dashboard:
|
|
1082
|
+
try:
|
|
1083
|
+
show_trading_dashboard()
|
|
1084
|
+
except Exception as e:
|
|
1085
|
+
st.error(f"❌ Error in Trading Dashboard page: {e}")
|
|
1086
|
+
import traceback
|
|
1087
|
+
st.code(traceback.format_exc())
|
|
893
1088
|
else:
|
|
894
1089
|
st.warning("Trading dashboard not available")
|
|
895
1090
|
elif page == "Test Portfolio":
|
|
896
|
-
if
|
|
897
|
-
|
|
1091
|
+
if HAS_TRADING_PAGES and show_test_portfolio:
|
|
1092
|
+
try:
|
|
1093
|
+
show_test_portfolio()
|
|
1094
|
+
except Exception as e:
|
|
1095
|
+
st.error(f"❌ Error in Test Portfolio page: {e}")
|
|
1096
|
+
import traceback
|
|
1097
|
+
st.code(traceback.format_exc())
|
|
898
1098
|
else:
|
|
899
1099
|
st.warning("Test portfolio not available")
|
|
1100
|
+
elif page == "Monte Carlo Predictions":
|
|
1101
|
+
if HAS_MONTE_CARLO_PAGE and show_monte_carlo_predictions:
|
|
1102
|
+
try:
|
|
1103
|
+
show_monte_carlo_predictions()
|
|
1104
|
+
except Exception as e:
|
|
1105
|
+
st.error(f"❌ Error in Monte Carlo Predictions page: {e}")
|
|
1106
|
+
import traceback
|
|
1107
|
+
st.code(traceback.format_exc())
|
|
1108
|
+
else:
|
|
1109
|
+
st.warning("Monte Carlo predictions not available")
|
|
900
1110
|
elif page == "LSH Jobs":
|
|
901
1111
|
show_lsh_jobs()
|
|
902
1112
|
elif page == "System Health":
|
|
903
1113
|
show_system_health()
|
|
904
1114
|
elif page == "Scrapers & Logs" and HAS_SCRAPERS_PAGE:
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
1115
|
+
try:
|
|
1116
|
+
show_scrapers_and_logs()
|
|
1117
|
+
except Exception as e:
|
|
1118
|
+
st.error(f"❌ Error in Scrapers & Logs page: {e}")
|
|
1119
|
+
import traceback
|
|
1120
|
+
st.code(traceback.format_exc())
|
|
1121
|
+
elif page == "CI/CD Pipelines":
|
|
1122
|
+
if show_cicd_dashboard is not None:
|
|
1123
|
+
try:
|
|
1124
|
+
show_cicd_dashboard()
|
|
1125
|
+
except Exception as e:
|
|
1126
|
+
st.error(f"❌ Error in CI/CD Pipelines page: {e}")
|
|
1127
|
+
import traceback
|
|
1128
|
+
st.code(traceback.format_exc())
|
|
1129
|
+
else:
|
|
1130
|
+
st.warning("CI/CD Pipelines page is not available. This page requires additional dependencies.")
|
|
1131
|
+
elif page == "Workflows":
|
|
1132
|
+
if show_workflows_dashboard is not None:
|
|
1133
|
+
try:
|
|
1134
|
+
show_workflows_dashboard()
|
|
1135
|
+
except Exception as e:
|
|
1136
|
+
st.error(f"❌ Error in Workflows page: {e}")
|
|
1137
|
+
import traceback
|
|
1138
|
+
st.code(traceback.format_exc())
|
|
1139
|
+
else:
|
|
1140
|
+
st.warning("Workflows page is not available. This page requires additional dependencies.")
|
|
1141
|
+
|
|
1142
|
+
elif page == "Debug Dependencies":
|
|
1143
|
+
if show_debug_dependencies is not None:
|
|
1144
|
+
try:
|
|
1145
|
+
show_debug_dependencies()
|
|
1146
|
+
except Exception as e:
|
|
1147
|
+
st.error(f"❌ Error in Debug Dependencies page: {e}")
|
|
1148
|
+
import traceback
|
|
1149
|
+
st.code(traceback.format_exc())
|
|
1150
|
+
else:
|
|
1151
|
+
st.warning("Debug Dependencies page is not available.")
|
|
910
1152
|
except Exception as e:
|
|
911
1153
|
st.error(f"❌ Error loading page '{page}': {e}")
|
|
912
1154
|
import traceback
|
|
@@ -2804,5 +3046,12 @@ def show_system_health():
|
|
|
2804
3046
|
st.plotly_chart(fig, width="stretch", config={"responsive": True})
|
|
2805
3047
|
|
|
2806
3048
|
|
|
2807
|
-
# Run the main dashboard function
|
|
2808
|
-
|
|
3049
|
+
# Run the main dashboard function with error handling
|
|
3050
|
+
try:
|
|
3051
|
+
main()
|
|
3052
|
+
except Exception as e:
|
|
3053
|
+
st.error(f"❌ Dashboard error: {e}")
|
|
3054
|
+
st.info("🔄 Please refresh the page to try again")
|
|
3055
|
+
import traceback
|
|
3056
|
+
with st.expander("Error details"):
|
|
3057
|
+
st.code(traceback.format_exc())
|
mcli/ml/dashboard/pages/cicd.py
CHANGED