mcli-framework 7.2.0__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.

Files changed (97) hide show
  1. mcli/__init__.py +160 -0
  2. mcli/__main__.py +14 -0
  3. mcli/app/__init__.py +23 -0
  4. mcli/app/commands_cmd.py +741 -0
  5. mcli/app/model/__init__.py +0 -0
  6. mcli/app/video/__init__.py +5 -0
  7. mcli/chat/__init__.py +34 -0
  8. mcli/lib/__init__.py +0 -0
  9. mcli/lib/api/__init__.py +0 -0
  10. mcli/lib/auth/__init__.py +1 -0
  11. mcli/lib/config/__init__.py +1 -0
  12. mcli/lib/erd/__init__.py +25 -0
  13. mcli/lib/files/__init__.py +0 -0
  14. mcli/lib/fs/__init__.py +1 -0
  15. mcli/lib/logger/__init__.py +3 -0
  16. mcli/lib/performance/__init__.py +17 -0
  17. mcli/lib/pickles/__init__.py +1 -0
  18. mcli/lib/shell/__init__.py +0 -0
  19. mcli/lib/toml/__init__.py +1 -0
  20. mcli/lib/watcher/__init__.py +0 -0
  21. mcli/ml/__init__.py +16 -0
  22. mcli/ml/api/__init__.py +30 -0
  23. mcli/ml/api/routers/__init__.py +27 -0
  24. mcli/ml/api/schemas.py +2 -2
  25. mcli/ml/auth/__init__.py +45 -0
  26. mcli/ml/auth/models.py +2 -2
  27. mcli/ml/backtesting/__init__.py +39 -0
  28. mcli/ml/cli/__init__.py +5 -0
  29. mcli/ml/cli/main.py +1 -1
  30. mcli/ml/config/__init__.py +33 -0
  31. mcli/ml/configs/__init__.py +16 -0
  32. mcli/ml/dashboard/__init__.py +12 -0
  33. mcli/ml/dashboard/app_integrated.py +296 -30
  34. mcli/ml/dashboard/app_training.py +1 -1
  35. mcli/ml/dashboard/components/__init__.py +7 -0
  36. mcli/ml/dashboard/pages/__init__.py +6 -0
  37. mcli/ml/dashboard/pages/cicd.py +1 -1
  38. mcli/ml/dashboard/pages/debug_dependencies.py +364 -0
  39. mcli/ml/dashboard/pages/gravity_viz.py +565 -0
  40. mcli/ml/dashboard/pages/monte_carlo_predictions.py +555 -0
  41. mcli/ml/dashboard/pages/overview.py +378 -0
  42. mcli/ml/dashboard/pages/predictions_enhanced.py +20 -6
  43. mcli/ml/dashboard/pages/scrapers_and_logs.py +22 -6
  44. mcli/ml/dashboard/pages/test_portfolio.py +423 -0
  45. mcli/ml/dashboard/pages/trading.py +768 -0
  46. mcli/ml/dashboard/streamlit_extras_utils.py +297 -0
  47. mcli/ml/dashboard/utils.py +161 -0
  48. mcli/ml/dashboard/warning_suppression.py +34 -0
  49. mcli/ml/data_ingestion/__init__.py +39 -0
  50. mcli/ml/database/__init__.py +47 -0
  51. mcli/ml/database/session.py +169 -16
  52. mcli/ml/experimentation/__init__.py +29 -0
  53. mcli/ml/features/__init__.py +39 -0
  54. mcli/ml/mlops/__init__.py +33 -0
  55. mcli/ml/models/__init__.py +94 -0
  56. mcli/ml/monitoring/__init__.py +25 -0
  57. mcli/ml/optimization/__init__.py +27 -0
  58. mcli/ml/predictions/__init__.py +5 -0
  59. mcli/ml/predictions/monte_carlo.py +428 -0
  60. mcli/ml/preprocessing/__init__.py +28 -0
  61. mcli/ml/scripts/__init__.py +1 -0
  62. mcli/ml/trading/__init__.py +66 -0
  63. mcli/ml/trading/alpaca_client.py +417 -0
  64. mcli/ml/trading/migrations.py +164 -0
  65. mcli/ml/trading/models.py +418 -0
  66. mcli/ml/trading/paper_trading.py +326 -0
  67. mcli/ml/trading/risk_management.py +370 -0
  68. mcli/ml/trading/trading_service.py +480 -0
  69. mcli/ml/training/__init__.py +10 -0
  70. mcli/mygroup/__init__.py +3 -0
  71. mcli/public/__init__.py +1 -0
  72. mcli/public/commands/__init__.py +2 -0
  73. mcli/self/__init__.py +3 -0
  74. mcli/self/self_cmd.py +514 -15
  75. mcli/workflow/__init__.py +0 -0
  76. mcli/workflow/daemon/__init__.py +15 -0
  77. mcli/workflow/daemon/daemon.py +21 -3
  78. mcli/workflow/dashboard/__init__.py +5 -0
  79. mcli/workflow/docker/__init__.py +0 -0
  80. mcli/workflow/file/__init__.py +0 -0
  81. mcli/workflow/gcloud/__init__.py +1 -0
  82. mcli/workflow/git_commit/__init__.py +0 -0
  83. mcli/workflow/interview/__init__.py +0 -0
  84. mcli/workflow/politician_trading/__init__.py +4 -0
  85. mcli/workflow/registry/__init__.py +0 -0
  86. mcli/workflow/repo/__init__.py +0 -0
  87. mcli/workflow/scheduler/__init__.py +25 -0
  88. mcli/workflow/search/__init__.py +0 -0
  89. mcli/workflow/sync/__init__.py +5 -0
  90. mcli/workflow/videos/__init__.py +1 -0
  91. mcli/workflow/wakatime/__init__.py +80 -0
  92. {mcli_framework-7.2.0.dist-info → mcli_framework-7.4.0.dist-info}/METADATA +4 -1
  93. {mcli_framework-7.2.0.dist-info → mcli_framework-7.4.0.dist-info}/RECORD +97 -18
  94. {mcli_framework-7.2.0.dist-info → mcli_framework-7.4.0.dist-info}/WHEEL +0 -0
  95. {mcli_framework-7.2.0.dist-info → mcli_framework-7.4.0.dist-info}/entry_points.txt +0 -0
  96. {mcli_framework-7.2.0.dist-info → mcli_framework-7.4.0.dist-info}/licenses/LICENSE +0 -0
  97. {mcli_framework-7.2.0.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,25 +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 pages.cicd import show_cicd_dashboard
51
- from pages.workflows import show_workflows_dashboard
52
- from pages.predictions_enhanced import show_predictions_enhanced
53
- from pages.scrapers_and_logs import show_scrapers_and_logs
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}")
54
124
 
55
- HAS_EXTENDED_PAGES = True
125
+ try:
126
+ from mcli.ml.dashboard.pages.scrapers_and_logs import show_scrapers_and_logs
56
127
  HAS_SCRAPERS_PAGE = True
57
- except ImportError:
58
- HAS_EXTENDED_PAGES = False
59
- HAS_SCRAPERS_PAGE = False
60
- show_cicd_dashboard = None
61
- show_workflows_dashboard = None
62
- show_predictions_enhanced = None
63
- show_scrapers_and_logs = None
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
161
+ from mcli.ml.dashboard.pages.trading import show_trading_dashboard
162
+ from mcli.ml.dashboard.pages.test_portfolio import show_test_portfolio
163
+ HAS_TRADING_PAGES = True
164
+ st.success("✅ Trading pages imported successfully!")
165
+
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}")
64
219
 
65
220
  # Page config
66
221
  st.set_page_config(
67
- page_title="MCLI ML Dashboard - Integrated",
222
+ page_title="Politician Trading Tracker - MCLI",
68
223
  page_icon="📊",
69
224
  layout="wide",
70
225
  initial_sidebar_state="expanded",
@@ -806,40 +961,77 @@ def get_model_metrics():
806
961
 
807
962
  def main():
808
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
809
979
 
810
980
  # Title and header
811
- st.title("🤖 MCLI ML System Dashboard - Integrated")
812
- st.markdown("Real-time ML pipeline monitoring with LSH daemon integration")
981
+ st.title("📊 Politician Trading Tracker")
982
+ st.markdown("Track, Analyze & Replicate Congressional Trading Patterns")
813
983
 
814
984
  # Sidebar
815
985
  st.sidebar.title("Navigation")
816
986
  # Build page list
817
- 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([
818
995
  "Pipeline Overview",
819
996
  "ML Processing",
820
997
  "Model Performance",
821
998
  "Model Training & Evaluation",
822
999
  "Predictions",
1000
+ "Trading Dashboard",
1001
+ "Test Portfolio",
823
1002
  "LSH Jobs",
824
1003
  "System Health",
825
- ]
1004
+ ])
826
1005
 
827
1006
  # Add scrapers and logs page
828
1007
  if HAS_SCRAPERS_PAGE:
829
1008
  pages.append("Scrapers & Logs")
830
1009
 
831
- # Add extended pages if available
832
- if HAS_EXTENDED_PAGES:
833
- pages.extend(["CI/CD Pipelines", "Workflows"])
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")
834
1025
 
835
1026
  page = st.sidebar.selectbox(
836
1027
  "Choose a page",
837
1028
  pages,
838
1029
  index=0, # Default to Pipeline Overview
1030
+ key="main_page_selector"
839
1031
  )
840
1032
 
841
1033
  # Auto-refresh toggle (default off to prevent blocking)
842
- auto_refresh = st.sidebar.checkbox("Auto-refresh (30s)", value=False)
1034
+ auto_refresh = st.sidebar.checkbox("Auto-refresh (30s)", value=True)
843
1035
  if auto_refresh:
844
1036
  try:
845
1037
  from streamlit_autorefresh import st_autorefresh
@@ -866,7 +1058,12 @@ def main():
866
1058
 
867
1059
  # Main content with error handling
868
1060
  try:
869
- if page == "Pipeline Overview":
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":
870
1067
  show_pipeline_overview()
871
1068
  elif page == "ML Processing":
872
1069
  show_ml_processing()
@@ -876,20 +1073,82 @@ def main():
876
1073
  show_model_training_evaluation()
877
1074
  elif page == "Predictions":
878
1075
  # Use enhanced predictions page if available, otherwise fallback
879
- if HAS_EXTENDED_PAGES and show_predictions_enhanced:
1076
+ if HAS_PREDICTIONS_ENHANCED and show_predictions_enhanced:
880
1077
  show_predictions_enhanced()
881
1078
  else:
882
1079
  show_predictions()
1080
+ elif page == "Trading Dashboard":
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())
1088
+ else:
1089
+ st.warning("Trading dashboard not available")
1090
+ elif page == "Test Portfolio":
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())
1098
+ else:
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")
883
1110
  elif page == "LSH Jobs":
884
1111
  show_lsh_jobs()
885
1112
  elif page == "System Health":
886
1113
  show_system_health()
887
1114
  elif page == "Scrapers & Logs" and HAS_SCRAPERS_PAGE:
888
- show_scrapers_and_logs()
889
- elif page == "CI/CD Pipelines" and HAS_EXTENDED_PAGES:
890
- show_cicd_dashboard()
891
- elif page == "Workflows" and HAS_EXTENDED_PAGES:
892
- show_workflows_dashboard()
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.")
893
1152
  except Exception as e:
894
1153
  st.error(f"❌ Error loading page '{page}': {e}")
895
1154
  import traceback
@@ -2787,5 +3046,12 @@ def show_system_health():
2787
3046
  st.plotly_chart(fig, width="stretch", config={"responsive": True})
2788
3047
 
2789
3048
 
2790
- # Run the main dashboard function
2791
- main()
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())
@@ -594,7 +594,7 @@ def main():
594
594
  )
595
595
 
596
596
  # Auto-refresh toggle
597
- auto_refresh = st.sidebar.checkbox("Auto-refresh (60s)", value=False)
597
+ auto_refresh = st.sidebar.checkbox("Auto-refresh (60s)", value=True)
598
598
  if auto_refresh:
599
599
  import time
600
600
 
@@ -0,0 +1,7 @@
1
+ """Reusable Streamlit dashboard components"""
2
+
3
+ from .charts import *
4
+ from .tables import *
5
+ from .metrics import *
6
+
7
+ __all__ = ["charts", "tables", "metrics"]
@@ -0,0 +1,6 @@
1
+ """Dashboard page modules"""
2
+
3
+ from .cicd import show_cicd_dashboard
4
+ from .workflows import show_workflows_dashboard
5
+
6
+ __all__ = ["show_cicd_dashboard", "show_workflows_dashboard"]
@@ -121,7 +121,7 @@ def show_cicd_dashboard():
121
121
  if st.button("🔄 Refresh"):
122
122
  st.rerun()
123
123
  with col2:
124
- auto_refresh = st.checkbox("Auto-refresh", value=False)
124
+ auto_refresh = st.checkbox("Auto-refresh", value=True)
125
125
 
126
126
  if auto_refresh:
127
127
  import time