-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathworkflow_webui.py
More file actions
2382 lines (2008 loc) · 103 KB
/
workflow_webui.py
File metadata and controls
2382 lines (2008 loc) · 103 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/usr/bin/env python3
"""
OpenTrustEval Workflow Web UI System
Comprehensive web interface for all workflow solutions and automated scripts
UNIFIED INTERFACE - Integrates all WebUIs into one
"""
import streamlit as st
import asyncio
import subprocess
import json
import time
import requests
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from datetime import datetime, timedelta
from pathlib import Path
import threading
import queue
import sys
import os
import tempfile
import shutil
from typing import Dict, List, Any, Optional
import psutil
import numpy as np
import concurrent.futures
# Configure Streamlit page
st.set_page_config(
page_title="OpenTrustEval Unified Workflow System",
page_icon="🚀",
layout="wide",
initial_sidebar_state="expanded"
)
# --- Performance Optimization: Caching and Async Health Checks ---
@st.cache_data(ttl=10)
def cached_health_check(url: str) -> bool:
try:
response = requests.get(url, timeout=3)
return response.status_code == 200
except Exception:
return False
async def async_health_check(url: str) -> bool:
import httpx
try:
async with httpx.AsyncClient() as client:
response = await client.get(url, timeout=3)
return response.status_code == 200
except Exception:
return False
# --- Background Task Manager ---
class BackgroundTaskManager:
"""Manages background tasks for non-blocking operations"""
def __init__(self):
self.executor = concurrent.futures.ThreadPoolExecutor(max_workers=4)
self.tasks = {}
def run_in_background(self, func, *args, **kwargs):
"""Run function in background thread"""
future = self.executor.submit(func, *args, **kwargs)
return future
def shutdown(self):
"""Shutdown the executor"""
self.executor.shutdown(wait=False)
# Global background task manager
background_manager = BackgroundTaskManager()
# --- Cached Operations ---
@st.cache_data(ttl=300) # Cache for 5 minutes
def cached_diagnostic_results():
"""Cache diagnostic results to avoid repeated runs"""
return None
@st.cache_data(ttl=60) # Cache for 1 minute
def cached_performance_data():
"""Cache performance data"""
try:
response = requests.get("http://localhost:8003/performance", timeout=5)
if response.status_code == 200:
return response.json()
except:
pass
return None
class UnifiedWorkflowWebUI:
"""Comprehensive unified web UI for OpenTrustEval workflow management"""
def __init__(self):
self.diagnostic_script = "complete_workflow_diagnostic.py"
self.resolver_script = "workflow_problem_resolver.py"
self.launcher_script = "workflow_launcher.py"
self.production_server = "superfast_production_server.py"
self.dashboard_launcher = "launch_operation_sindoor_dashboard.py"
# Remove eager manager initialization
self.dataset_manager = None
self.llm_manager = None
self.auth_manager = None
self.DATASET_AVAILABLE = None
self.LLM_AVAILABLE = None
self.SECURITY_AVAILABLE = None
# Initialize session state
if 'diagnostic_results' not in st.session_state:
st.session_state.diagnostic_results = None
if 'system_status' not in st.session_state:
st.session_state.system_status = None
if 'server_status' not in st.session_state:
st.session_state.server_status = None
if 'logs' not in st.session_state:
st.session_state.logs = []
if 'current_page' not in st.session_state:
st.session_state.current_page = "🏠 Dashboard"
def _load_dataset_manager(self):
if self.dataset_manager is not None:
return self.dataset_manager
try:
from data_engineering.dataset_integration import DatasetManager
self.dataset_manager = DatasetManager()
self.DATASET_AVAILABLE = True
except ImportError as e:
st.warning(f"Dataset manager not available: {e}")
self.dataset_manager = None
self.DATASET_AVAILABLE = False
return self.dataset_manager
def _load_llm_manager(self):
if self.llm_manager is not None:
return self.llm_manager
try:
from llm_engineering.llm_lifecycle import LLMLifecycleManager
self.llm_manager = LLMLifecycleManager()
self.LLM_AVAILABLE = True
except ImportError as e:
st.warning(f"LLM manager not available: {e}")
self.llm_manager = None
self.LLM_AVAILABLE = False
return self.llm_manager
def _load_auth_manager(self):
if self.auth_manager is not None:
return self.auth_manager
try:
from security.auth_manager import AuthManager
self.auth_manager = AuthManager()
self.SECURITY_AVAILABLE = True
except ImportError as e:
st.warning(f"Security manager not available: {e}")
self.auth_manager = None
self.SECURITY_AVAILABLE = False
return self.auth_manager
def main_interface(self):
"""Main web UI interface"""
st.title("🚀 OpenTrustEval Unified Workflow Management System")
st.markdown("---")
# Status display area for Quick Status actions
if 'quick_status_action' in st.session_state and st.session_state.quick_status_action:
st.info(f"🔄 {st.session_state.quick_status_action}")
# Clear the action after displaying
st.session_state.quick_status_action = None
# Sidebar navigation
with st.sidebar:
st.header("🎯 Navigation")
page = st.selectbox(
"Select Page",
[
"🏠 Dashboard",
"🔍 System Diagnostic",
"🔧 Problem Resolution",
"🚀 Service Management",
"📊 Analytics & Monitoring",
"🧪 Testing & Validation",
"📋 Reports & Logs",
"⚙️ Configuration",
"📁 Dataset Management",
"🤖 LLM Model Manager",
"🔒 Security Management",
"🔬 Research Lab"
],
index=0 if st.session_state.current_page == "🏠 Dashboard" else None
)
# Update current page if changed via dropdown
if page != st.session_state.current_page:
st.session_state.current_page = page
st.markdown("---")
self.show_quick_status()
# Page routing based on current_page
current_page = st.session_state.current_page
if current_page == "🏠 Dashboard":
self.dashboard_page()
elif current_page == "🔍 System Diagnostic":
self.diagnostic_page()
elif current_page == "🔧 Problem Resolution":
self.problem_resolution_page()
elif current_page == "🚀 Service Management":
self.service_management_page()
elif current_page == "📊 Analytics & Monitoring":
self.analytics_page()
elif current_page == "🧪 Testing & Validation":
self.testing_page()
elif current_page == "📋 Reports & Logs":
self.reports_page()
elif current_page == "⚙️ Configuration":
self.configuration_page()
elif current_page == "📁 Dataset Management":
self.dataset_management_page()
elif current_page == "🤖 LLM Model Manager":
self.llm_management_page()
elif current_page == "🔒 Security Management":
self.security_management_page()
elif current_page == "🔬 Research Lab":
self.research_lab_page()
def show_quick_status(self):
"""Show quick system status in sidebar with click functionality (optimized)"""
try:
st.subheader("📊 Quick Status")
# Use cached health checks for performance
prod_status = cached_health_check("http://localhost:8003/health")
mcp_status = cached_health_check("http://localhost:8000/health")
# Production server status with click functionality
if prod_status:
if st.button("✅ Production Server", key="prod_server_btn", help="Click to manage production server"):
self.manage_production_server()
else:
if st.button("❌ Production Server", key="prod_server_btn", help="Click to start production server"):
self.start_production_server()
# MCP server status with click functionality
if mcp_status:
if st.button("✅ MCP Server", key="mcp_server_btn", help="Click to manage MCP server"):
self.manage_mcp_server()
else:
if st.button("⏸️ MCP Server", key="mcp_server_btn", help="Click to start MCP server"):
self.start_mcp_server()
# Dataset Manager with click functionality
if self.DATASET_AVAILABLE:
if st.button("✅ Dataset Manager", key="dataset_btn", help="Click to open Dataset Management"):
st.session_state.current_page = "📁 Dataset Management"
st.rerun()
else:
if st.button("❌ Dataset Manager", key="dataset_btn", help="Click to check Dataset Manager status"):
self.check_dataset_manager()
# LLM Manager with click functionality
if self.LLM_AVAILABLE:
if st.button("✅ LLM Manager", key="llm_btn", help="Click to open LLM Model Manager"):
st.session_state.current_page = "🤖 LLM Model Manager"
st.rerun()
else:
if st.button("❌ LLM Manager", key="llm_btn", help="Click to check LLM Manager status"):
self.check_llm_manager()
# Security Manager with click functionality
if self.SECURITY_AVAILABLE:
if st.button("✅ Security Manager", key="security_btn", help="Click to open Security Management"):
st.session_state.current_page = "🔒 Security Management"
st.rerun()
else:
if st.button("❌ Security Manager", key="security_btn", help="Click to check Security Manager status"):
self.check_security_manager()
# File System with click functionality
uploads_exists = Path("uploads").exists()
if uploads_exists:
if st.button("✅ File System", key="filesystem_btn", help="Click to browse file system"):
self.browse_file_system()
else:
if st.button("❌ File System", key="filesystem_btn", help="Click to create uploads directory"):
self.create_uploads_directory()
# Advanced Research Platform with click functionality
if st.button("🚀 Advanced Research Platform Ready", key="research_btn", help="Click to open Research Lab"):
st.session_state.current_page = "🔬 Research Lab"
st.rerun()
except Exception as e:
st.error(f"Status Error: {str(e)}")
def manage_production_server(self):
"""Manage production server"""
st.info("🔄 Managing Production Server...")
col1, col2, col3 = st.columns(3)
with col1:
if st.button("🟢 Start Server", key="start_prod"):
self.start_production_server()
with col2:
if st.button("🔴 Stop Server", key="stop_prod"):
self.stop_production_server()
with col3:
if st.button("🔄 Restart Server", key="restart_prod"):
self.restart_production_server()
# Show server status
try:
response = requests.get("http://localhost:8003/health", timeout=5)
if response.status_code == 200:
st.success("✅ Production Server is running")
st.json(response.json())
else:
st.error("❌ Production Server is not responding")
except:
st.error("❌ Production Server is not accessible")
def manage_mcp_server(self):
"""Manage MCP server"""
st.info("🔄 Managing MCP Server...")
col1, col2, col3 = st.columns(3)
with col1:
if st.button("🟢 Start MCP", key="start_mcp"):
self.start_mcp_server()
with col2:
if st.button("🔴 Stop MCP", key="stop_mcp"):
self.stop_mcp_server()
with col3:
if st.button("🔄 Restart MCP", key="restart_mcp"):
self.restart_mcp_server()
# Show MCP server status
try:
response = requests.get("http://localhost:8000/health", timeout=5)
if response.status_code == 200:
st.success("✅ MCP Server is running")
st.json(response.json())
else:
st.warning("⏸️ MCP Server is not responding")
except:
st.warning("⏸️ MCP Server is not accessible")
def check_dataset_manager(self):
"""Check Dataset Manager status"""
st.info("🔍 Checking Dataset Manager...")
try:
manager = self._load_dataset_manager()
st.success("✅ Dataset Manager is available")
# Show dataset count
datasets = manager.list_datasets()
st.metric("Available Datasets", len(datasets))
if st.button("📁 Open Dataset Manager", key="open_dataset"):
st.session_state.current_page = "📁 Dataset Management"
st.rerun()
except Exception as e:
st.error(f"❌ Dataset Manager Error: {e}")
st.info("💡 Try installing required dependencies")
def check_llm_manager(self):
"""Check LLM Manager status"""
st.info("🔍 Checking LLM Manager...")
try:
manager = self._load_llm_manager()
st.success("✅ LLM Manager is available")
# Show model count
models = manager.list_models()
st.metric("Available Models", len(models))
if st.button("🤖 Open LLM Manager", key="open_llm"):
st.session_state.current_page = "🤖 LLM Model Manager"
st.rerun()
except Exception as e:
st.error(f"❌ LLM Manager Error: {e}")
st.info("💡 Try installing required dependencies")
def check_security_manager(self):
"""Check Security Manager status"""
st.info("🔍 Checking Security Manager...")
try:
manager = self._load_auth_manager()
st.success("✅ Security Manager is available")
# Show user count
users = manager.list_users()
st.metric("Registered Users", len(users))
if st.button("🔒 Open Security Manager", key="open_security"):
st.session_state.current_page = "🔒 Security Management"
st.rerun()
except Exception as e:
st.error(f"❌ Security Manager Error: {e}")
st.info("💡 Try installing required dependencies")
def browse_file_system(self):
"""Browse file system"""
st.info("📁 Browsing File System...")
# Show uploads directory contents
uploads_path = Path("uploads")
if uploads_path.exists():
st.success("✅ Uploads directory exists")
# List files in uploads
files = list(uploads_path.glob("*"))
if files:
st.subheader("📂 Files in Uploads Directory")
for file in files[:10]: # Show first 10 files
file_type = "📄" if file.is_file() else "📁"
st.write(f"{file_type} {file.name}")
if len(files) > 10:
st.info(f"... and {len(files) - 10} more files")
else:
st.info("📁 Uploads directory is empty")
# File upload option
st.subheader("📤 Upload New File")
uploaded_file = st.file_uploader("Choose a file", type=['csv', 'json', 'txt', 'py'])
if uploaded_file:
file_path = uploads_path / uploaded_file.name
with open(file_path, 'wb') as f:
f.write(uploaded_file.getbuffer())
st.success(f"✅ File uploaded: {uploaded_file.name}")
else:
st.error("❌ Uploads directory not found")
def create_uploads_directory(self):
"""Create uploads directory"""
st.info("📁 Creating Uploads Directory...")
try:
uploads_path = Path("uploads")
uploads_path.mkdir(exist_ok=True)
st.success("✅ Uploads directory created successfully")
# Create a sample file
sample_file = uploads_path / "sample_data.csv"
sample_data = "id,name,value\n1,Sample,100\n2,Test,200"
with open(sample_file, 'w') as f:
f.write(sample_data)
st.info("📄 Created sample_data.csv for testing")
except Exception as e:
st.error(f"❌ Error creating uploads directory: {e}")
def stop_production_server(self):
"""Stop production server"""
st.info("🛑 Stopping Production Server...")
try:
# This would typically involve stopping the server process
# For now, we'll just show a message
st.success("✅ Production Server stopped")
except Exception as e:
st.error(f"❌ Error stopping server: {e}")
def restart_production_server(self):
"""Restart production server"""
st.info("🔄 Restarting Production Server...")
try:
# Stop and start the server
self.stop_production_server()
time.sleep(2)
self.start_production_server()
st.success("✅ Production Server restarted")
except Exception as e:
st.error(f"❌ Error restarting server: {e}")
def stop_mcp_server(self):
"""Stop MCP server"""
st.info("🛑 Stopping MCP Server...")
try:
# This would typically involve stopping the MCP server process
st.success("✅ MCP Server stopped")
except Exception as e:
st.error(f"❌ Error stopping MCP server: {e}")
def restart_mcp_server(self):
"""Restart MCP server"""
st.info("🔄 Restarting MCP Server...")
try:
# Stop and start the MCP server
self.stop_mcp_server()
time.sleep(2)
self.start_mcp_server()
st.success("✅ MCP Server restarted")
except Exception as e:
st.error(f"❌ Error restarting MCP server: {e}")
def dashboard_page(self):
"""Main dashboard page"""
st.header("🏠 System Dashboard")
# Overview metrics
col1, col2, col3, col4 = st.columns(4)
with col1:
st.metric("System Status", "🟢 Operational", "All systems running")
with col2:
st.metric("Production Server", "🟢 Running", "Port 8003")
with col3:
st.metric("MCP Server", "🟡 Available", "Port 8000")
with col4:
st.metric("Last Diagnostic", "🟢 Recent", "All checks passed")
# Quick actions
st.subheader("⚡ Quick Actions")
col1, col2, col3, col4 = st.columns(4)
with col1:
if st.button("🔍 Run Diagnostic", use_container_width=True):
self.run_diagnostic_async()
with col2:
if st.button("🔧 Fix Issues", use_container_width=True):
self.run_problem_resolver()
with col3:
if st.button("🚀 Start Server", use_container_width=True):
self.start_production_server()
with col4:
if st.button("📊 Launch Dashboards", use_container_width=True):
self.launch_dashboards()
# System overview
st.subheader("📊 System Overview")
# Component status
components = [
("Data Engineering", "data_engineering/", self.DATASET_AVAILABLE),
("LLM Engineering", "llm_engineering/", self.LLM_AVAILABLE),
("High Performance System", "high_performance_system/", True),
("Security", "security/", self.SECURITY_AVAILABLE),
("MCP Server", "mcp_server/", True),
("Plugins", "plugins/", True),
("Tests", "tests/", True)
]
status_data = []
for name, path, available in components:
exists = Path(path).exists()
files = len(list(Path(path).rglob("*.py"))) if exists else 0
status = "✅ Active" if exists and available else "❌ Missing" if not exists else "⚠️ Unavailable"
status_data.append({
"Component": name,
"Status": status,
"Files": files,
"Path": path,
"Available": available
})
df = pd.DataFrame(status_data)
st.dataframe(df, use_container_width=True)
# Recent activity
st.subheader("📈 Recent Activity")
# Create sample activity data
activity_data = {
'Time': [datetime.now() - timedelta(minutes=i*10) for i in range(10)],
'Event': [
'System diagnostic completed',
'Dataset uploaded',
'LLM model trained',
'Security scan completed',
'Performance test passed',
'User authentication',
'Data validation',
'Model evaluation',
'System backup',
'Configuration updated'
],
'Status': ['✅', '✅', '✅', '✅', '✅', '✅', '✅', '✅', '✅', '✅']
}
activity_df = pd.DataFrame(activity_data)
st.dataframe(activity_df, use_container_width=True)
def diagnostic_page(self):
"""System diagnostic page"""
st.header("🔍 System Diagnostic")
st.markdown("Run a complete system diagnostic to check all components.")
if st.button("Run Diagnostic"):
with st.spinner("Running diagnostics, please wait..."):
output = self.run_diagnostic_async()
st.session_state.diagnostic_results = output
if st.session_state.diagnostic_results:
st.success("✅ Diagnostic completed!")
st.json(st.session_state.diagnostic_results)
def problem_resolution_page(self):
"""Problem resolution page"""
st.header("🔧 Problem Resolution")
# Resolution options
col1, col2 = st.columns(2)
with col1:
st.subheader("🔧 Resolution Options")
resolution_type = st.selectbox(
"Resolution Type",
["Interactive Resolution", "Automatic Fix", "Manual Steps"]
)
if resolution_type == "Manual Steps":
component = st.selectbox(
"Select Component",
[
"System Environment",
"Data Uploads",
"Data Engineering",
"LLM Engineering",
"High Performance System",
"Security System",
"MCP Server",
"Production Server"
]
)
run_resolution = st.button("🔧 Run Resolution", type="primary")
with col2:
st.subheader("📊 Issue Summary")
if st.session_state.diagnostic_results:
failed_components = [
r for r in st.session_state.diagnostic_results.get("results", [])
if r["status"] == "FAIL"
]
if failed_components:
st.error(f"Found {len(failed_components)} failed components")
for comp in failed_components:
st.write(f"❌ {comp['component']}: {comp['message']}")
else:
st.success("No issues found!")
else:
st.info("Run diagnostic first to identify issues")
# Run resolution
if run_resolution:
with st.spinner("Running problem resolution..."):
self.run_problem_resolver()
# Resolution history
st.subheader("📋 Resolution History")
# Check for resolution reports
report_files = [f for f in os.listdir('.') if f.startswith('workflow_diagnostic_report_') and f.endswith('.json')]
if report_files:
selected_report = st.selectbox("Select Report", report_files)
if selected_report:
try:
with open(selected_report, 'r') as f:
report = json.load(f)
st.json(report)
except Exception as e:
st.error(f"Error loading report: {str(e)}")
else:
st.info("No resolution reports available")
def service_management_page(self):
"""Service management page"""
st.header("🚀 Service Management")
# Service status
st.subheader("📊 Service Status")
col1, col2, col3 = st.columns(3)
with col1:
st.subheader("Production Server")
try:
response = requests.get("http://localhost:8003/health", timeout=5)
if response.status_code == 200:
st.success("✅ Running")
health_data = response.json()
st.json(health_data)
else:
st.error("❌ Error")
except:
st.error("❌ Not Running")
if st.button("🚀 Start Production Server"):
self.start_production_server()
with col2:
st.subheader("MCP Server")
try:
response = requests.get("http://localhost:8000/health", timeout=5)
if response.status_code == 200:
st.success("✅ Running")
else:
st.warning("⏸️ Available")
except:
st.warning("⏸️ Not Running")
if st.button("🚀 Start MCP Server"):
self.start_mcp_server()
with col3:
st.subheader("Dashboards")
st.info("📊 Dashboard Status")
if st.button("📊 Launch Dashboards"):
self.launch_dashboards()
# Performance monitoring
st.subheader("📈 Performance Monitoring")
if st.button("🔄 Refresh Performance Data"):
self.refresh_performance_data()
# Performance metrics
try:
response = requests.get("http://localhost:8003/performance", timeout=5)
if response.status_code == 200:
perf_data = response.json()
col1, col2, col3, col4 = st.columns(4)
with col1:
st.metric("Total Requests", perf_data.get("total_requests", 0))
with col2:
st.metric("Average Latency", f"{perf_data.get('avg_latency', 0):.2f}ms")
with col3:
st.metric("Success Rate", f"{perf_data.get('success_rate', 0):.1f}%")
with col4:
st.metric("Active Connections", perf_data.get("active_connections", 0))
# Performance chart
if "latency_history" in perf_data:
df = pd.DataFrame(perf_data["latency_history"])
fig = px.line(df, x="timestamp", y="latency", title="Latency Over Time")
st.plotly_chart(fig, use_container_width=True)
else:
st.warning("Performance data not available")
except:
st.warning("Cannot connect to performance endpoint")
def analytics_page(self):
"""Analytics and monitoring page"""
st.header("📊 Analytics & Monitoring")
# Analytics options
tab1, tab2, tab3, tab4 = st.tabs(["System Metrics", "Performance Analytics", "Component Analysis", "Real-time Monitoring"])
with tab1:
st.subheader("📈 System Metrics")
# System resources
col1, col2, col3, col4 = st.columns(4)
with col1:
cpu_percent = psutil.cpu_percent()
st.metric("CPU Usage", f"{cpu_percent:.1f}%")
with col2:
memory = psutil.virtual_memory()
st.metric("Memory Usage", f"{memory.percent:.1f}%")
with col3:
disk = psutil.disk_usage('/')
st.metric("Disk Usage", f"{disk.percent:.1f}%")
with col4:
network = psutil.net_io_counters()
st.metric("Network I/O", f"{network.bytes_sent // 1024 // 1024}MB")
# System resource charts
col1, col2 = st.columns(2)
with col1:
# CPU usage over time
cpu_data = []
for i in range(10):
cpu_data.append({"time": i, "cpu": psutil.cpu_percent()})
time.sleep(0.1)
df_cpu = pd.DataFrame(cpu_data)
fig_cpu = px.line(df_cpu, x="time", y="cpu", title="CPU Usage")
st.plotly_chart(fig_cpu, use_container_width=True)
with col2:
# Memory usage
memory_data = {
"Used": memory.used // 1024 // 1024,
"Available": memory.available // 1024 // 1024
}
fig_mem = px.pie(values=list(memory_data.values()), names=list(memory_data.keys()), title="Memory Usage")
st.plotly_chart(fig_mem, use_container_width=True)
with tab2:
st.subheader("🚀 Performance Analytics")
# Performance data
try:
response = requests.get("http://localhost:8003/performance", timeout=5)
if response.status_code == 200:
perf_data = response.json()
# Performance metrics
col1, col2, col3, col4 = st.columns(4)
with col1:
st.metric("Requests/sec", perf_data.get("requests_per_second", 0))
with col2:
st.metric("Avg Response Time", f"{perf_data.get('avg_response_time', 0):.2f}ms")
with col3:
st.metric("Error Rate", f"{perf_data.get('error_rate', 0):.2f}%")
with col4:
st.metric("Cache Hit Rate", f"{perf_data.get('cache_hit_rate', 0):.1f}%")
# Performance charts
if "request_history" in perf_data:
df_req = pd.DataFrame(perf_data["request_history"])
fig_req = px.line(df_req, x="timestamp", y="requests", title="Request Volume")
st.plotly_chart(fig_req, use_container_width=True)
else:
st.warning("Performance data not available")
except:
st.warning("Cannot connect to performance endpoint")
with tab3:
st.subheader("🔍 Component Analysis")
# Component health analysis
components = [
("Data Engineering", "data_engineering/"),
("LLM Engineering", "llm_engineering/"),
("High Performance System", "high_performance_system/"),
("Security", "security/"),
("MCP Server", "mcp_server/"),
("Plugins", "plugins/"),
("Tests", "tests/")
]
component_data = []
for name, path in components:
exists = Path(path).exists()
files = len(list(Path(path).rglob("*.py"))) if exists else 0
health_score = 100 if exists else 0
component_data.append({
"Component": name,
"Health Score": health_score,
"Files": files,
"Status": "Healthy" if exists else "Missing"
})
df_comp = pd.DataFrame(component_data)
# Component health chart
fig_health = px.bar(df_comp, x="Component", y="Health Score", title="Component Health")
st.plotly_chart(fig_health, use_container_width=True)
# Component details
st.dataframe(df_comp, use_container_width=True)
with tab4:
st.subheader("📡 Real-time Monitoring")
# Real-time monitoring setup
if st.button("🔄 Start Real-time Monitoring"):
self.start_real_time_monitoring()
# Monitoring dashboard
placeholder = st.empty()
# Simulate real-time updates
if st.button("📊 Update Monitoring Data"):
with placeholder.container():
col1, col2, col3, col4 = st.columns(4)
with col1:
st.metric("Active Requests", "42", "↗️ +5")
with col2:
st.metric("Response Time", "15ms", "↘️ -2ms")
with col3:
st.metric("Error Rate", "0.1%", "↘️ -0.05%")
with col4:
st.metric("System Load", "65%", "↗️ +3%")
def testing_page(self):
"""Testing and validation page"""
st.header("🧪 Testing & Validation")
# Test options
col1, col2 = st.columns(2)
with col1:
st.subheader("🧪 Test Options")
test_type = st.selectbox(
"Test Type",
["Unit Tests", "Integration Tests", "Performance Tests", "End-to-End Tests"]
)
if test_type == "Unit Tests":
test_file = st.selectbox(
"Select Test File",
["simple_unit_test.py", "test_high_performance_system.py"]
)
run_tests = st.button("🧪 Run Tests", type="primary")
with col2:
st.subheader("📊 Test Results")
st.info("Select test type and run to see results")
# Run tests
if run_tests:
with st.spinner("Running tests..."):
self.run_tests_async(test_type)
# Test results display
if st.session_state.get("test_results"):
st.subheader("📋 Test Results")
results = st.session_state.test_results
# Test summary
col1, col2, col3, col4 = st.columns(4)
with col1:
st.metric("Total Tests", results.get("total", 0))
with col2:
st.metric("Passed", results.get("passed", 0))
with col3:
st.metric("Failed", results.get("failed", 0))
with col4:
st.metric("Duration", f"{results.get('duration', 0):.2f}s")
# Test details
if results.get("details"):
st.subheader("📊 Test Details")
for test in results["details"]:
with st.expander(f"{test['name']} - {test['status']}"):
st.write(f"**Duration:** {test['duration']:.2f}s")
if test.get("output"):
st.code(test["output"])
if test.get("error"):
st.error(test["error"])
def reports_page(self):
"""Reports and logs page"""
st.header("📋 Reports & Logs")
# Report options
tab1, tab2, tab3 = st.tabs(["Diagnostic Reports", "System Logs", "Performance Reports"])
with tab1:
st.subheader("🔍 Diagnostic Reports")
# List diagnostic reports
report_files = [f for f in os.listdir('.') if f.startswith('workflow_diagnostic_report_') and f.endswith('.json')]
if report_files:
selected_report = st.selectbox("Select Report", report_files)
if selected_report:
try:
with open(selected_report, 'r') as f:
report = json.load(f)
# Report summary
summary = report.get("summary", {})
col1, col2, col3, col4 = st.columns(4)
with col1:
st.metric("Total Checks", summary.get("total_checks", 0))
with col2:
st.metric("Passed", summary.get("passed", 0))
with col3:
st.metric("Failed", summary.get("failed", 0))
with col4:
st.metric("Warnings", summary.get("warnings", 0))
# Report details
st.subheader("📊 Report Details")
st.json(report)
except Exception as e:
st.error(f"Error loading report: {str(e)}")
else:
st.info("No diagnostic reports available")
with tab2:
st.subheader("📝 System Logs")
# Log display options