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.

Files changed (216) hide show
  1. mcli/app/__init__.py +0 -2
  2. mcli/app/commands_cmd.py +30 -26
  3. mcli/app/completion_helpers.py +5 -5
  4. mcli/app/init_cmd.py +10 -10
  5. mcli/app/lock_cmd.py +29 -24
  6. mcli/app/main.py +2 -8
  7. mcli/app/model/model.py +5 -10
  8. mcli/app/store_cmd.py +8 -8
  9. mcli/app/video/__init__.py +0 -2
  10. mcli/app/video/video.py +1 -14
  11. mcli/chat/chat.py +90 -108
  12. mcli/chat/command_rag.py +0 -4
  13. mcli/chat/enhanced_chat.py +32 -41
  14. mcli/chat/system_controller.py +37 -37
  15. mcli/chat/system_integration.py +4 -5
  16. mcli/cli.py +2 -3
  17. mcli/lib/api/api.py +4 -9
  18. mcli/lib/api/daemon_client.py +19 -20
  19. mcli/lib/api/daemon_client_local.py +1 -3
  20. mcli/lib/api/daemon_decorator.py +6 -6
  21. mcli/lib/api/mcli_decorators.py +4 -8
  22. mcli/lib/auth/__init__.py +0 -1
  23. mcli/lib/auth/auth.py +4 -5
  24. mcli/lib/auth/mcli_manager.py +7 -12
  25. mcli/lib/auth/token_util.py +5 -5
  26. mcli/lib/config/__init__.py +29 -1
  27. mcli/lib/config/config.py +0 -1
  28. mcli/lib/custom_commands.py +1 -1
  29. mcli/lib/discovery/command_discovery.py +15 -15
  30. mcli/lib/erd/erd.py +7 -7
  31. mcli/lib/files/files.py +1 -1
  32. mcli/lib/fs/__init__.py +31 -1
  33. mcli/lib/fs/fs.py +12 -13
  34. mcli/lib/lib.py +0 -1
  35. mcli/lib/logger/logger.py +7 -10
  36. mcli/lib/performance/optimizer.py +25 -27
  37. mcli/lib/performance/rust_bridge.py +22 -27
  38. mcli/lib/performance/uvloop_config.py +0 -1
  39. mcli/lib/pickles/__init__.py +0 -1
  40. mcli/lib/pickles/pickles.py +0 -2
  41. mcli/lib/secrets/commands.py +0 -2
  42. mcli/lib/secrets/manager.py +0 -1
  43. mcli/lib/secrets/repl.py +2 -3
  44. mcli/lib/secrets/store.py +1 -2
  45. mcli/lib/services/data_pipeline.py +34 -34
  46. mcli/lib/services/lsh_client.py +38 -40
  47. mcli/lib/shell/shell.py +2 -2
  48. mcli/lib/toml/__init__.py +0 -1
  49. mcli/lib/ui/styling.py +0 -1
  50. mcli/lib/ui/visual_effects.py +33 -41
  51. mcli/lib/watcher/watcher.py +0 -1
  52. mcli/ml/__init__.py +1 -1
  53. mcli/ml/api/__init__.py +1 -1
  54. mcli/ml/api/app.py +8 -9
  55. mcli/ml/api/middleware.py +10 -10
  56. mcli/ml/api/routers/__init__.py +1 -1
  57. mcli/ml/api/routers/admin_router.py +3 -3
  58. mcli/ml/api/routers/auth_router.py +17 -18
  59. mcli/ml/api/routers/backtest_router.py +2 -2
  60. mcli/ml/api/routers/data_router.py +2 -2
  61. mcli/ml/api/routers/model_router.py +14 -15
  62. mcli/ml/api/routers/monitoring_router.py +2 -2
  63. mcli/ml/api/routers/portfolio_router.py +2 -2
  64. mcli/ml/api/routers/prediction_router.py +10 -9
  65. mcli/ml/api/routers/trade_router.py +2 -2
  66. mcli/ml/api/routers/websocket_router.py +6 -7
  67. mcli/ml/api/schemas.py +2 -2
  68. mcli/ml/auth/__init__.py +1 -1
  69. mcli/ml/auth/auth_manager.py +22 -23
  70. mcli/ml/auth/models.py +17 -17
  71. mcli/ml/auth/permissions.py +17 -17
  72. mcli/ml/backtesting/__init__.py +1 -1
  73. mcli/ml/backtesting/backtest_engine.py +31 -35
  74. mcli/ml/backtesting/performance_metrics.py +12 -14
  75. mcli/ml/backtesting/run.py +1 -2
  76. mcli/ml/cache.py +35 -36
  77. mcli/ml/cli/__init__.py +1 -1
  78. mcli/ml/cli/main.py +21 -24
  79. mcli/ml/config/__init__.py +1 -1
  80. mcli/ml/config/settings.py +28 -29
  81. mcli/ml/configs/__init__.py +1 -1
  82. mcli/ml/configs/dvc_config.py +14 -15
  83. mcli/ml/configs/mlflow_config.py +12 -13
  84. mcli/ml/configs/mlops_manager.py +19 -21
  85. mcli/ml/dashboard/__init__.py +4 -4
  86. mcli/ml/dashboard/app.py +20 -30
  87. mcli/ml/dashboard/app_supabase.py +16 -19
  88. mcli/ml/dashboard/app_training.py +11 -14
  89. mcli/ml/dashboard/cli.py +2 -2
  90. mcli/ml/dashboard/common.py +2 -3
  91. mcli/ml/dashboard/components/__init__.py +1 -1
  92. mcli/ml/dashboard/components/charts.py +13 -11
  93. mcli/ml/dashboard/components/metrics.py +7 -7
  94. mcli/ml/dashboard/components/tables.py +12 -9
  95. mcli/ml/dashboard/overview.py +2 -2
  96. mcli/ml/dashboard/pages/__init__.py +1 -1
  97. mcli/ml/dashboard/pages/cicd.py +15 -18
  98. mcli/ml/dashboard/pages/debug_dependencies.py +7 -7
  99. mcli/ml/dashboard/pages/monte_carlo_predictions.py +11 -18
  100. mcli/ml/dashboard/pages/predictions_enhanced.py +24 -32
  101. mcli/ml/dashboard/pages/scrapers_and_logs.py +22 -24
  102. mcli/ml/dashboard/pages/test_portfolio.py +3 -6
  103. mcli/ml/dashboard/pages/trading.py +16 -18
  104. mcli/ml/dashboard/pages/workflows.py +20 -30
  105. mcli/ml/dashboard/utils.py +9 -9
  106. mcli/ml/dashboard/warning_suppression.py +3 -3
  107. mcli/ml/data_ingestion/__init__.py +1 -1
  108. mcli/ml/data_ingestion/api_connectors.py +41 -46
  109. mcli/ml/data_ingestion/data_pipeline.py +36 -46
  110. mcli/ml/data_ingestion/stream_processor.py +43 -46
  111. mcli/ml/database/__init__.py +1 -1
  112. mcli/ml/database/migrations/env.py +2 -2
  113. mcli/ml/database/models.py +22 -24
  114. mcli/ml/database/session.py +14 -14
  115. mcli/ml/experimentation/__init__.py +1 -1
  116. mcli/ml/experimentation/ab_testing.py +45 -46
  117. mcli/ml/features/__init__.py +1 -1
  118. mcli/ml/features/ensemble_features.py +22 -27
  119. mcli/ml/features/recommendation_engine.py +30 -30
  120. mcli/ml/features/stock_features.py +29 -32
  121. mcli/ml/features/test_feature_engineering.py +10 -11
  122. mcli/ml/logging.py +4 -4
  123. mcli/ml/mlops/__init__.py +1 -1
  124. mcli/ml/mlops/data_versioning.py +29 -30
  125. mcli/ml/mlops/experiment_tracker.py +24 -24
  126. mcli/ml/mlops/model_serving.py +31 -34
  127. mcli/ml/mlops/pipeline_orchestrator.py +27 -35
  128. mcli/ml/models/__init__.py +5 -6
  129. mcli/ml/models/base_models.py +23 -23
  130. mcli/ml/models/ensemble_models.py +31 -31
  131. mcli/ml/models/recommendation_models.py +18 -19
  132. mcli/ml/models/test_models.py +14 -16
  133. mcli/ml/monitoring/__init__.py +1 -1
  134. mcli/ml/monitoring/drift_detection.py +32 -36
  135. mcli/ml/monitoring/metrics.py +2 -2
  136. mcli/ml/optimization/__init__.py +1 -1
  137. mcli/ml/optimization/optimize.py +1 -2
  138. mcli/ml/optimization/portfolio_optimizer.py +30 -32
  139. mcli/ml/predictions/__init__.py +1 -1
  140. mcli/ml/preprocessing/__init__.py +1 -1
  141. mcli/ml/preprocessing/data_cleaners.py +22 -23
  142. mcli/ml/preprocessing/feature_extractors.py +23 -26
  143. mcli/ml/preprocessing/ml_pipeline.py +23 -23
  144. mcli/ml/preprocessing/test_preprocessing.py +7 -8
  145. mcli/ml/scripts/populate_sample_data.py +0 -4
  146. mcli/ml/serving/serve.py +1 -2
  147. mcli/ml/tasks.py +17 -17
  148. mcli/ml/tests/test_integration.py +29 -30
  149. mcli/ml/tests/test_training_dashboard.py +21 -21
  150. mcli/ml/trading/__init__.py +1 -1
  151. mcli/ml/trading/migrations.py +5 -5
  152. mcli/ml/trading/models.py +21 -23
  153. mcli/ml/trading/paper_trading.py +16 -13
  154. mcli/ml/trading/risk_management.py +17 -18
  155. mcli/ml/trading/trading_service.py +25 -28
  156. mcli/ml/training/__init__.py +1 -1
  157. mcli/ml/training/train.py +0 -1
  158. mcli/public/oi/oi.py +1 -2
  159. mcli/self/completion_cmd.py +6 -10
  160. mcli/self/logs_cmd.py +19 -24
  161. mcli/self/migrate_cmd.py +22 -20
  162. mcli/self/redis_cmd.py +10 -11
  163. mcli/self/self_cmd.py +10 -18
  164. mcli/self/store_cmd.py +10 -12
  165. mcli/self/visual_cmd.py +9 -14
  166. mcli/self/zsh_cmd.py +2 -4
  167. mcli/workflow/daemon/async_command_database.py +23 -24
  168. mcli/workflow/daemon/async_process_manager.py +27 -29
  169. mcli/workflow/daemon/client.py +27 -33
  170. mcli/workflow/daemon/daemon.py +32 -36
  171. mcli/workflow/daemon/enhanced_daemon.py +24 -33
  172. mcli/workflow/daemon/process_cli.py +11 -12
  173. mcli/workflow/daemon/process_manager.py +23 -26
  174. mcli/workflow/daemon/test_daemon.py +4 -5
  175. mcli/workflow/dashboard/dashboard_cmd.py +0 -1
  176. mcli/workflow/doc_convert.py +15 -17
  177. mcli/workflow/gcloud/__init__.py +0 -1
  178. mcli/workflow/gcloud/gcloud.py +11 -8
  179. mcli/workflow/git_commit/ai_service.py +14 -15
  180. mcli/workflow/lsh_integration.py +9 -11
  181. mcli/workflow/model_service/client.py +26 -31
  182. mcli/workflow/model_service/download_and_run_efficient_models.py +10 -14
  183. mcli/workflow/model_service/lightweight_embedder.py +25 -35
  184. mcli/workflow/model_service/lightweight_model_server.py +26 -32
  185. mcli/workflow/model_service/lightweight_test.py +7 -10
  186. mcli/workflow/model_service/model_service.py +80 -91
  187. mcli/workflow/model_service/ollama_efficient_runner.py +14 -18
  188. mcli/workflow/model_service/openai_adapter.py +23 -23
  189. mcli/workflow/model_service/pdf_processor.py +21 -26
  190. mcli/workflow/model_service/test_efficient_runner.py +12 -16
  191. mcli/workflow/model_service/test_example.py +11 -13
  192. mcli/workflow/model_service/test_integration.py +3 -5
  193. mcli/workflow/model_service/test_new_features.py +7 -8
  194. mcli/workflow/notebook/converter.py +1 -1
  195. mcli/workflow/notebook/notebook_cmd.py +5 -6
  196. mcli/workflow/notebook/schema.py +0 -1
  197. mcli/workflow/notebook/validator.py +7 -3
  198. mcli/workflow/openai/openai.py +1 -2
  199. mcli/workflow/registry/registry.py +4 -1
  200. mcli/workflow/repo/repo.py +6 -7
  201. mcli/workflow/scheduler/cron_parser.py +16 -19
  202. mcli/workflow/scheduler/job.py +10 -10
  203. mcli/workflow/scheduler/monitor.py +15 -15
  204. mcli/workflow/scheduler/persistence.py +17 -18
  205. mcli/workflow/scheduler/scheduler.py +37 -38
  206. mcli/workflow/secrets/__init__.py +1 -1
  207. mcli/workflow/sync/test_cmd.py +0 -1
  208. mcli/workflow/wakatime/__init__.py +5 -9
  209. mcli/workflow/wakatime/wakatime.py +1 -2
  210. {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/METADATA +1 -1
  211. mcli_framework-7.12.4.dist-info/RECORD +279 -0
  212. mcli_framework-7.12.2.dist-info/RECORD +0 -279
  213. {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/WHEEL +0 -0
  214. {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/entry_points.txt +0 -0
  215. {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/licenses/LICENSE +0 -0
  216. {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/top_level.txt +0 -0
@@ -1,15 +1,12 @@
1
- """Streamlit dashboard for ML system monitoring - Supabase version"""
1
+ """Streamlit dashboard for ML system monitoring - Supabase version."""
2
2
 
3
- import asyncio
4
3
  import os
5
4
  from datetime import datetime, timedelta
6
5
 
7
- import numpy as np
8
6
  import pandas as pd
9
7
  import plotly.express as px
10
8
  import plotly.graph_objects as go
11
9
  import streamlit as st
12
- from plotly.subplots import make_subplots
13
10
 
14
11
  from mcli.ml.dashboard.common import (
15
12
  get_supabase_client,
@@ -30,7 +27,7 @@ apply_dashboard_styles()
30
27
 
31
28
  @st.cache_data(ttl=30)
32
29
  def get_politicians_data():
33
- """Get politicians data from Supabase"""
30
+ """Get politicians data from Supabase."""
34
31
  client = get_supabase_client()
35
32
  if not client:
36
33
  st.warning("No Supabase client available")
@@ -49,7 +46,7 @@ def get_politicians_data():
49
46
 
50
47
  @st.cache_data(ttl=30)
51
48
  def get_disclosures_data():
52
- """Get trading disclosures from Supabase with politician details"""
49
+ """Get trading disclosures from Supabase with politician details."""
53
50
  client = get_supabase_client()
54
51
  if not client:
55
52
  return pd.DataFrame()
@@ -114,7 +111,7 @@ def get_disclosures_data():
114
111
 
115
112
  @st.cache_data(ttl=30)
116
113
  def get_predictions_data():
117
- """Get ML predictions from Supabase"""
114
+ """Get ML predictions from Supabase."""
118
115
  client = get_supabase_client()
119
116
  if not client:
120
117
  return pd.DataFrame()
@@ -129,14 +126,14 @@ def get_predictions_data():
129
126
  .execute()
130
127
  )
131
128
  return pd.DataFrame(response.data)
132
- except:
129
+ except Exception:
133
130
  # Table might not exist yet
134
131
  return pd.DataFrame()
135
132
 
136
133
 
137
134
  @st.cache_data(ttl=30)
138
135
  def get_portfolios_data():
139
- """Get portfolio data from Supabase"""
136
+ """Get portfolio data from Supabase."""
140
137
  client = get_supabase_client()
141
138
  if not client:
142
139
  return pd.DataFrame()
@@ -145,14 +142,14 @@ def get_portfolios_data():
145
142
  # Try to get portfolios if table exists
146
143
  response = client.table("portfolios").select("*").execute()
147
144
  return pd.DataFrame(response.data)
148
- except:
145
+ except Exception:
149
146
  # Table might not exist yet
150
147
  return pd.DataFrame()
151
148
 
152
149
 
153
150
  @st.cache_data(ttl=30)
154
151
  def get_jobs_data():
155
- """Get data pull jobs from Supabase"""
152
+ """Get data pull jobs from Supabase."""
156
153
  client = get_supabase_client()
157
154
  if not client:
158
155
  return pd.DataFrame()
@@ -172,7 +169,7 @@ def get_jobs_data():
172
169
 
173
170
 
174
171
  def main():
175
- """Main dashboard function"""
172
+ """Main dashboard function."""
176
173
 
177
174
  # Title and header
178
175
  st.title("🤖 MCLI ML System Dashboard")
@@ -280,7 +277,7 @@ def main():
280
277
 
281
278
 
282
279
  def show_overview():
283
- """Show overview dashboard"""
280
+ """Show overview dashboard."""
284
281
  st.header("System Overview")
285
282
 
286
283
  # Get data
@@ -365,7 +362,7 @@ def show_overview():
365
362
 
366
363
 
367
364
  def show_politicians():
368
- """Show politicians dashboard"""
365
+ """Show politicians dashboard."""
369
366
  st.header("Politicians")
370
367
 
371
368
  politicians = get_politicians_data()
@@ -432,7 +429,7 @@ def show_politicians():
432
429
 
433
430
 
434
431
  def show_disclosures():
435
- """Show trading disclosures dashboard"""
432
+ """Show trading disclosures dashboard."""
436
433
  st.header("Trading Disclosures")
437
434
 
438
435
  disclosures = get_disclosures_data()
@@ -507,7 +504,7 @@ def show_disclosures():
507
504
 
508
505
 
509
506
  def show_predictions():
510
- """Show ML predictions dashboard"""
507
+ """Show ML predictions dashboard."""
511
508
  st.header("ML Predictions")
512
509
 
513
510
  predictions = get_predictions_data()
@@ -528,7 +525,7 @@ def show_predictions():
528
525
 
529
526
 
530
527
  def show_jobs():
531
- """Show data pull jobs dashboard"""
528
+ """Show data pull jobs dashboard."""
532
529
  st.header("Data Pull Jobs")
533
530
 
534
531
  jobs = get_jobs_data()
@@ -575,7 +572,7 @@ def show_jobs():
575
572
 
576
573
 
577
574
  def show_system_health():
578
- """Show system health dashboard"""
575
+ """Show system health dashboard."""
579
576
  st.header("System Health")
580
577
 
581
578
  client = get_supabase_client()
@@ -589,7 +586,7 @@ def show_system_health():
589
586
  # Try a simple query to test connection
590
587
  client.table("politicians").select("id").limit(1).execute()
591
588
  st.success("✅ Supabase: Connected")
592
- except:
589
+ except Exception:
593
590
  st.error("❌ Supabase: Connection Error")
594
591
  else:
595
592
  st.warning("⚠️ Supabase: Not Configured")
@@ -1,13 +1,10 @@
1
- """Enhanced training dashboard with Bitcoin-style model comparison and analysis"""
2
-
3
- from datetime import datetime, timedelta
1
+ """Enhanced training dashboard with Bitcoin-style model comparison and analysis."""
4
2
 
5
3
  import numpy as np
6
4
  import pandas as pd
7
5
  import plotly.express as px
8
6
  import plotly.graph_objects as go
9
7
  import streamlit as st
10
- from plotly.subplots import make_subplots
11
8
  from scipy import stats
12
9
 
13
10
  from mcli.ml.dashboard.common import setup_page_config
@@ -43,7 +40,7 @@ st.markdown(
43
40
 
44
41
  @st.cache_data(ttl=60)
45
42
  def get_training_jobs():
46
- """Get recent training jobs and experiments"""
43
+ """Get recent training jobs and experiments."""
47
44
  db = SessionLocal()
48
45
 
49
46
  try:
@@ -72,7 +69,7 @@ def get_training_jobs():
72
69
 
73
70
  @st.cache_data(ttl=60)
74
71
  def get_model_comparison():
75
- """Get model comparison data with comprehensive metrics"""
72
+ """Get model comparison data with comprehensive metrics."""
76
73
  db = SessionLocal()
77
74
 
78
75
  try:
@@ -121,11 +118,11 @@ def get_model_comparison():
121
118
 
122
119
  @st.cache_data(ttl=60)
123
120
  def get_feature_importance(model_id: str):
124
- """Get feature importance for a specific model"""
121
+ """Get feature importance for a specific model."""
125
122
  db = SessionLocal()
126
123
 
127
124
  try:
128
- from sqlalchemy.dialects.postgresql import UUID
125
+ pass
129
126
 
130
127
  model = db.query(Model).filter(Model.id == model_id).first()
131
128
 
@@ -143,7 +140,7 @@ def get_feature_importance(model_id: str):
143
140
 
144
141
 
145
142
  def show_model_comparison():
146
- """Show comprehensive model comparison inspired by bitcoin project"""
143
+ """Show comprehensive model comparison inspired by bitcoin project."""
147
144
  st.header("📊 Model Performance Comparison")
148
145
 
149
146
  models_df = get_model_comparison()
@@ -266,7 +263,7 @@ def show_model_comparison():
266
263
 
267
264
 
268
265
  def show_residual_analysis():
269
- """Show residual analysis for model predictions"""
266
+ """Show residual analysis for model predictions."""
270
267
  st.header("📈 Residual Analysis")
271
268
 
272
269
  models_df = get_model_comparison()
@@ -277,7 +274,7 @@ def show_residual_analysis():
277
274
 
278
275
  # Model selector
279
276
  model_options = models_df["name"].unique()
280
- selected_model = st.selectbox("Select Model for Analysis", model_options)
277
+ st.selectbox("Select Model for Analysis", model_options)
281
278
 
282
279
  # Generate simulated residuals (in real scenario, load actual predictions)
283
280
  np.random.seed(42)
@@ -418,7 +415,7 @@ def show_residual_analysis():
418
415
 
419
416
 
420
417
  def show_feature_importance():
421
- """Show feature importance analysis"""
418
+ """Show feature importance analysis."""
422
419
  st.header("🔍 Feature Importance Analysis")
423
420
 
424
421
  models_df = get_model_comparison()
@@ -527,7 +524,7 @@ def show_feature_importance():
527
524
 
528
525
 
529
526
  def show_training_history():
530
- """Show training history and experiments"""
527
+ """Show training history and experiments."""
531
528
  st.header("📚 Training History")
532
529
 
533
530
  jobs_df = get_training_jobs()
@@ -577,7 +574,7 @@ def show_training_history():
577
574
 
578
575
 
579
576
  def main():
580
- """Main dashboard function"""
577
+ """Main dashboard function."""
581
578
  st.title("🔬 ML Training Dashboard")
582
579
  st.markdown("Comprehensive model training analysis and comparison")
583
580
 
mcli/ml/dashboard/cli.py CHANGED
@@ -1,4 +1,4 @@
1
- """CLI interface for ML dashboard"""
1
+ """CLI interface for ML dashboard."""
2
2
 
3
3
  import subprocess
4
4
  import sys
@@ -17,7 +17,7 @@ def launch(
17
17
  host: str = typer.Option("localhost", "--host", "-h", help="Host to bind to"),
18
18
  debug: bool = typer.Option(False, "--debug", help="Run in debug mode"),
19
19
  ):
20
- """Launch the ML monitoring dashboard"""
20
+ """Launch the ML monitoring dashboard."""
21
21
 
22
22
  # Get the dashboard app path
23
23
  dashboard_path = Path(__file__).parent / "app.py"
@@ -7,7 +7,6 @@ This module provides shared functionality across all dashboard variants to avoid
7
7
  import os
8
8
  import warnings
9
9
  from pathlib import Path
10
- from typing import Optional
11
10
 
12
11
  import streamlit as st
13
12
  from dotenv import load_dotenv
@@ -95,7 +94,7 @@ def get_supabase_client():
95
94
  if client:
96
95
  data = client.table('politicians').select('*').execute()
97
96
  """
98
- from supabase import Client, create_client
97
+ from supabase import create_client
99
98
 
100
99
  # Try Streamlit secrets first (for Streamlit Cloud)
101
100
  url = ""
@@ -131,7 +130,7 @@ def get_supabase_client():
131
130
  client = create_client(url, key)
132
131
 
133
132
  # Test connection with a simple query
134
- try:
133
+ try: # noqa: SIM105
135
134
  # Try politicians table first (most common)
136
135
  client.table("politicians").select("id").limit(1).execute()
137
136
  except Exception:
@@ -1,4 +1,4 @@
1
- """Reusable Streamlit dashboard components"""
1
+ """Reusable Streamlit dashboard components."""
2
2
 
3
3
  from .charts import *
4
4
  from .metrics import *
@@ -1,6 +1,6 @@
1
- """Reusable chart components for Streamlit dashboards"""
1
+ """Reusable chart components for Streamlit dashboards."""
2
2
 
3
- from typing import Any, Dict, List, Optional
3
+ from typing import Dict, List, Optional
4
4
 
5
5
  import pandas as pd
6
6
  import plotly.express as px
@@ -16,11 +16,13 @@ def create_timeline_chart(
16
16
  color_col: Optional[str] = None,
17
17
  height: int = 400,
18
18
  ) -> go.Figure:
19
- """Create a timeline chart with Plotly"""
19
+ """Create a timeline chart with Plotly."""
20
20
 
21
21
  fig = px.line(data, x=x_col, y=y_col, color=color_col, title=title, markers=True)
22
22
 
23
- fig.update_layout(height=height, hovermode="x unified", showlegend=True if color_col else False)
23
+ fig.update_layout(
24
+ height=height, hovermode="x unified", showlegend=True if color_col else False
25
+ ) # noqa: SIM210
24
26
 
25
27
  return fig
26
28
 
@@ -31,7 +33,7 @@ def create_status_pie_chart(
31
33
  title: str = "Status Distribution",
32
34
  color_map: Optional[Dict[str, str]] = None,
33
35
  ) -> go.Figure:
34
- """Create a pie chart for status distribution"""
36
+ """Create a pie chart for status distribution."""
35
37
 
36
38
  status_counts = data[status_col].value_counts()
37
39
 
@@ -69,7 +71,7 @@ def create_metric_trend_chart(
69
71
  title: str,
70
72
  target_value: Optional[float] = None,
71
73
  ) -> go.Figure:
72
- """Create a metric trend chart with optional target line"""
74
+ """Create a metric trend chart with optional target line."""
73
75
 
74
76
  fig = go.Figure()
75
77
 
@@ -109,7 +111,7 @@ def create_heatmap(
109
111
  title: str = "Heatmap",
110
112
  color_scale: str = "Blues",
111
113
  ) -> go.Figure:
112
- """Create a heatmap visualization"""
114
+ """Create a heatmap visualization."""
113
115
 
114
116
  pivot_data = data.pivot_table(index=y_col, columns=x_col, values=value_col, aggfunc="mean")
115
117
 
@@ -128,7 +130,7 @@ def create_gantt_chart(
128
130
  status_col: Optional[str] = None,
129
131
  title: str = "Timeline",
130
132
  ) -> go.Figure:
131
- """Create a Gantt chart for job/task scheduling"""
133
+ """Create a Gantt chart for job/task scheduling."""
132
134
 
133
135
  fig = px.timeline(
134
136
  data, x_start=start_col, x_end=end_col, y=task_col, color=status_col, title=title
@@ -143,7 +145,7 @@ def create_gantt_chart(
143
145
  def create_multi_metric_gauge(
144
146
  values: Dict[str, float], max_values: Dict[str, float], title: str = "Metrics"
145
147
  ) -> go.Figure:
146
- """Create multiple gauge charts in a grid"""
148
+ """Create multiple gauge charts in a grid."""
147
149
 
148
150
  from plotly.subplots import make_subplots
149
151
 
@@ -194,7 +196,7 @@ def create_multi_metric_gauge(
194
196
  def create_waterfall_chart(
195
197
  categories: List[str], values: List[float], title: str = "Waterfall Chart"
196
198
  ) -> go.Figure:
197
- """Create a waterfall chart for step-by-step changes"""
199
+ """Create a waterfall chart for step-by-step changes."""
198
200
 
199
201
  fig = go.Figure(
200
202
  go.Waterfall(
@@ -213,5 +215,5 @@ def create_waterfall_chart(
213
215
 
214
216
 
215
217
  def render_chart(fig: go.Figure, key: Optional[str] = None):
216
- """Helper to render Plotly chart with consistent configuration"""
218
+ """Helper to render Plotly chart with consistent configuration."""
217
219
  st.plotly_chart(fig, width="stretch", config={"responsive": True}, key=key)
@@ -1,4 +1,4 @@
1
- """Reusable metric display components"""
1
+ """Reusable metric display components."""
2
2
 
3
3
  from typing import Optional, Union
4
4
 
@@ -13,7 +13,7 @@ def display_metric_card(
13
13
  help_text: Optional[str] = None,
14
14
  icon: Optional[str] = None,
15
15
  ):
16
- """Display a metric card with optional delta and icon"""
16
+ """Display a metric card with optional delta and icon."""
17
17
 
18
18
  if icon:
19
19
  label = f"{icon} {label}"
@@ -22,7 +22,7 @@ def display_metric_card(
22
22
 
23
23
 
24
24
  def display_status_badge(status: str, size: str = "medium") -> str:
25
- """Return a colored status badge"""
25
+ """Return a colored status badge."""
26
26
 
27
27
  status_colors = {
28
28
  "completed": "🟢",
@@ -48,7 +48,7 @@ def display_status_badge(status: str, size: str = "medium") -> str:
48
48
 
49
49
 
50
50
  def display_kpi_row(metrics: dict, columns: Optional[int] = None):
51
- """Display a row of KPIs in columns"""
51
+ """Display a row of KPIs in columns."""
52
52
 
53
53
  if columns is None:
54
54
  columns = len(metrics)
@@ -71,7 +71,7 @@ def display_kpi_row(metrics: dict, columns: Optional[int] = None):
71
71
 
72
72
 
73
73
  def display_progress_bar(label: str, progress: float, show_percentage: bool = True):
74
- """Display a progress bar with label"""
74
+ """Display a progress bar with label."""
75
75
 
76
76
  st.text(label)
77
77
  st.progress(min(1.0, max(0.0, progress)))
@@ -81,7 +81,7 @@ def display_progress_bar(label: str, progress: float, show_percentage: bool = Tr
81
81
 
82
82
 
83
83
  def display_health_indicator(component: str, is_healthy: bool, details: Optional[str] = None):
84
- """Display a health status indicator"""
84
+ """Display a health status indicator."""
85
85
 
86
86
  if is_healthy:
87
87
  st.success(f"✅ {component}: Healthy" + (f" ({details})" if details else ""))
@@ -90,7 +90,7 @@ def display_health_indicator(component: str, is_healthy: bool, details: Optional
90
90
 
91
91
 
92
92
  def display_alert(message: str, alert_type: str = "info", icon: Optional[str] = None):
93
- """Display an alert message"""
93
+ """Display an alert message."""
94
94
 
95
95
  if icon:
96
96
  message = f"{icon} {message}"
@@ -1,5 +1,6 @@
1
- """Reusable table components"""
1
+ """Reusable table components."""
2
2
 
3
+ from io import BytesIO
3
4
  from typing import Any, Callable, List, Optional
4
5
 
5
6
  import pandas as pd
@@ -13,7 +14,7 @@ def display_dataframe_with_search(
13
14
  page_size: int = 20,
14
15
  key_prefix: str = "table",
15
16
  ) -> pd.DataFrame:
16
- """Display a dataframe with search and pagination"""
17
+ """Display a dataframe with search and pagination."""
17
18
 
18
19
  if df.empty:
19
20
  st.info("No data available")
@@ -62,7 +63,7 @@ def display_dataframe_with_search(
62
63
  def display_filterable_dataframe(
63
64
  df: pd.DataFrame, filter_columns: Optional[dict] = None, key_prefix: str = "filter"
64
65
  ) -> pd.DataFrame:
65
- """Display a dataframe with column-specific filters"""
66
+ """Display a dataframe with column-specific filters."""
66
67
 
67
68
  if df.empty:
68
69
  st.info("No data available")
@@ -97,7 +98,7 @@ def display_filterable_dataframe(
97
98
  .str.contains(search_text, case=False, na=False)
98
99
  ]
99
100
 
100
- elif filter_type == "date_range":
101
+ elif filter_type == "date_range": # noqa: SIM102
101
102
  if pd.api.types.is_datetime64_any_dtype(df[col_name]):
102
103
  min_date = df[col_name].min()
103
104
  max_date = df[col_name].max()
@@ -127,7 +128,7 @@ def display_table_with_actions(
127
128
  st.info("No data available")
128
129
  return
129
130
 
130
- for idx, row in df.iterrows():
131
+ for _idx, row in df.iterrows():
131
132
  with st.container():
132
133
  # Display row data in columns
133
134
  data_cols = st.columns([3] + [1] * len(actions))
@@ -156,13 +157,13 @@ def display_expandable_table(
156
157
  row_id_column: str = "id",
157
158
  key_prefix: str = "expand",
158
159
  ):
159
- """Display a table where each row can be expanded for details"""
160
+ """Display a table where each row can be expanded for details."""
160
161
 
161
162
  if df.empty:
162
163
  st.info("No data available")
163
164
  return
164
165
 
165
- for idx, row in df.iterrows():
166
+ for _idx, row in df.iterrows():
166
167
  # Summary view
167
168
  summary_data = {col: row[col] for col in summary_columns if col in row}
168
169
  summary_text = " | ".join([f"{k}: {v}" for k, v in summary_data.items()])
@@ -174,10 +175,12 @@ def display_expandable_table(
174
175
  def export_dataframe(
175
176
  df: pd.DataFrame,
176
177
  filename: str = "data",
177
- formats: List[str] = ["csv", "json"],
178
+ formats: Optional[List[str]] = None,
178
179
  key_prefix: str = "export",
179
180
  ):
180
- """Provide export buttons for a dataframe"""
181
+ """Provide export buttons for a dataframe."""
182
+ if formats is None:
183
+ formats = ["csv", "json"]
181
184
 
182
185
  if df.empty:
183
186
  return
@@ -1,4 +1,4 @@
1
- """Overview page - Introduction to the Politician Trading Tracker"""
1
+ """Overview page - Introduction to the Politician Trading Tracker."""
2
2
 
3
3
  import streamlit as st
4
4
 
@@ -15,7 +15,7 @@ except ImportError:
15
15
 
16
16
 
17
17
  def show_overview():
18
- """Main overview page"""
18
+ """Main overview page."""
19
19
 
20
20
  # Hero section
21
21
  st.markdown(
@@ -1,4 +1,4 @@
1
- """Dashboard page modules"""
1
+ """Dashboard page modules."""
2
2
 
3
3
  from .cicd import show_cicd_dashboard
4
4
  from .workflows import show_workflows_dashboard
@@ -1,35 +1,32 @@
1
- """CI/CD Pipeline Monitoring Dashboard"""
1
+ """CI/CD Pipeline Monitoring Dashboard."""
2
2
 
3
3
  import os
4
- from datetime import datetime, timedelta
5
- from typing import Optional
6
4
 
7
5
  import pandas as pd
8
6
  import plotly.express as px
9
- import plotly.graph_objects as go
10
7
  import requests
11
8
  import streamlit as st
12
9
 
13
10
  # Import components
14
11
  try:
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
12
+ from ..components.charts import create_status_pie_chart, render_chart
13
+ from ..components.metrics import display_kpi_row, display_status_badge
17
14
  from ..components.tables import display_filterable_dataframe, export_dataframe
18
15
  except ImportError:
19
16
  # Fallback for when imported outside package context
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
17
+ from components.charts import create_status_pie_chart, render_chart
18
+ from components.metrics import display_kpi_row, display_status_badge
22
19
  from components.tables import display_filterable_dataframe, export_dataframe
23
20
 
24
21
 
25
22
  def get_cicd_api_url() -> str:
26
- """Get CI/CD API URL from environment"""
23
+ """Get CI/CD API URL from environment."""
27
24
  lsh_url = os.getenv("LSH_API_URL", "http://localhost:3034")
28
25
  return f"{lsh_url}/api/cicd"
29
26
 
30
27
 
31
28
  def fetch_cicd_builds(limit: int = 100) -> pd.DataFrame:
32
- """Fetch CI/CD build data from API"""
29
+ """Fetch CI/CD build data from API."""
33
30
  try:
34
31
  api_url = get_cicd_api_url()
35
32
  response = requests.get(f"{api_url}/builds", params={"limit": limit}, timeout=5)
@@ -56,7 +53,7 @@ def fetch_cicd_builds(limit: int = 100) -> pd.DataFrame:
56
53
 
57
54
 
58
55
  def create_mock_cicd_data() -> pd.DataFrame:
59
- """Create mock CI/CD data for demonstration"""
56
+ """Create mock CI/CD data for demonstration."""
60
57
  import random
61
58
  from datetime import datetime, timedelta
62
59
 
@@ -92,7 +89,7 @@ def create_mock_cicd_data() -> pd.DataFrame:
92
89
 
93
90
 
94
91
  def fetch_webhooks() -> list:
95
- """Fetch configured webhooks"""
92
+ """Fetch configured webhooks."""
96
93
  try:
97
94
  api_url = get_cicd_api_url()
98
95
  response = requests.get(f"{api_url}/webhooks", timeout=5)
@@ -129,7 +126,7 @@ def fetch_webhooks() -> list:
129
126
 
130
127
 
131
128
  def show_cicd_dashboard():
132
- """Main CI/CD dashboard page"""
129
+ """Main CI/CD dashboard page."""
133
130
 
134
131
  st.title("🔧 CI/CD Pipeline Dashboard")
135
132
  st.markdown("Monitor build pipelines, deployments, and CI/CD metrics")
@@ -212,7 +209,7 @@ def show_cicd_dashboard():
212
209
 
213
210
 
214
211
  def show_cicd_overview(builds_df: pd.DataFrame):
215
- """Show CI/CD overview charts"""
212
+ """Show CI/CD overview charts."""
216
213
 
217
214
  col1, col2 = st.columns(2)
218
215
 
@@ -280,7 +277,7 @@ def show_cicd_overview(builds_df: pd.DataFrame):
280
277
 
281
278
 
282
279
  def show_build_history(builds_df: pd.DataFrame):
283
- """Show detailed build history"""
280
+ """Show detailed build history."""
284
281
 
285
282
  st.markdown("### Build History")
286
283
 
@@ -326,7 +323,7 @@ def show_build_history(builds_df: pd.DataFrame):
326
323
  )
327
324
 
328
325
  # Mock logs
329
- if st.button(f"View Logs", key=f"logs_{build.get('id')}"):
326
+ if st.button("View Logs", key=f"logs_{build.get('id')}"):
330
327
  st.code(
331
328
  f"""
332
329
  [INFO] Starting build for {build.get('pipeline_name')}
@@ -340,7 +337,7 @@ def show_build_history(builds_df: pd.DataFrame):
340
337
 
341
338
 
342
339
  def show_webhooks_config():
343
- """Show webhook configuration"""
340
+ """Show webhook configuration."""
344
341
 
345
342
  st.markdown("### 🔔 Configured Webhooks")
346
343
 
@@ -385,7 +382,7 @@ def show_webhooks_config():
385
382
 
386
383
 
387
384
  def show_cicd_configuration():
388
- """Show CI/CD configuration options"""
385
+ """Show CI/CD configuration options."""
389
386
 
390
387
  st.markdown("### ⚙️ CI/CD Configuration")
391
388