areeb1501 commited on
Commit
2201434
·
1 Parent(s): 8e72089

add design changes

Browse files
README.md CHANGED
@@ -849,7 +849,7 @@ We welcome contributions! Areas of interest:
849
 
850
  ## 📄 License
851
 
852
- MIT License - See [LICENSE](./LICENSE) for details
853
 
854
  ---
855
 
 
849
 
850
  ## 📄 License
851
 
852
+ BSL License
853
 
854
  ---
855
 
ui_components/code_editor.py CHANGED
@@ -29,52 +29,55 @@ def create_code_editor():
29
  gr.Markdown("## 💻 Code Editor")
30
  gr.Markdown("Edit and view your deployment code inline")
31
 
32
- # Load Deployment Section
33
- with gr.Row():
34
- deployment_selector = gr.Dropdown(
35
- label="Select Deployment",
36
- choices=[],
37
- interactive=True,
38
- scale=3
39
- )
40
- load_btn = gr.Button("📥 Load Code", size="sm", scale=1)
41
- refresh_deployments_btn = gr.Button("🔄", size="sm", scale=0)
42
-
43
- # Deployment Info Display
44
  with gr.Row():
 
45
  with gr.Column(scale=1):
 
 
 
 
 
 
 
 
 
 
46
  deployment_info = gr.Markdown("*Select a deployment to view details*")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  with gr.Column(scale=1):
 
48
  packages_display = gr.Textbox(
49
  label="Current Packages",
50
- interactive=True, # Allow editing packages
51
- placeholder="No deployment loaded"
 
52
  )
53
-
54
- # Code Editor Section
55
- gr.Markdown("### 📝 MCP Tools Code")
56
- code_editor = gr.Code(
57
- language="python",
58
- label="",
59
- lines=20,
60
- interactive=True,
61
- value="# Load a deployment to view and edit code"
62
- )
63
-
64
- # Tools Preview
65
- tools_preview = gr.JSON(
66
- label="📋 Detected Tools",
67
- value={}
68
- )
69
-
70
- # Action Buttons
71
- with gr.Row():
72
- save_btn = gr.Button("💾 Save & Redeploy", variant="primary", interactive=True)
73
- preview_btn = gr.Button("👁️ Preview", variant="secondary")
74
- deploy_btn = gr.Button("🚀 Deploy as New (Coming Soon)", interactive=False)
75
-
76
- # Output/Result Display
77
- output = gr.JSON(label="Result")
78
 
79
  # Functions
80
  def load_deployment_list():
 
29
  gr.Markdown("## 💻 Code Editor")
30
  gr.Markdown("Edit and view your deployment code inline")
31
 
32
+ # Main 4-column layout
 
 
 
 
 
 
 
 
 
 
 
33
  with gr.Row():
34
+ # Column 1: Deployment Selection & Info
35
  with gr.Column(scale=1):
36
+ gr.Markdown("### 📂 Select Deployment")
37
+ deployment_selector = gr.Dropdown(
38
+ label="Deployment",
39
+ choices=[],
40
+ interactive=True
41
+ )
42
+ with gr.Row():
43
+ load_btn = gr.Button("📥 Load", size="sm", scale=2)
44
+ refresh_deployments_btn = gr.Button("🔄", size="sm", scale=1)
45
+
46
  deployment_info = gr.Markdown("*Select a deployment to view details*")
47
+
48
+ # Column 2: Code Editor
49
+ with gr.Column(scale=2):
50
+ gr.Markdown("### 📝 MCP Tools Code")
51
+ code_editor = gr.Code(
52
+ language="python",
53
+ label="",
54
+ lines=18,
55
+ interactive=True,
56
+ value="# Load a deployment to view and edit code"
57
+ )
58
+
59
+ # Action Buttons
60
+ with gr.Row():
61
+ save_btn = gr.Button("💾 Save & Redeploy", variant="primary", interactive=True, scale=2)
62
+ preview_btn = gr.Button("👁️ Preview", variant="secondary", scale=1)
63
+ deploy_btn = gr.Button("🚀 Deploy as New (Coming Soon)", interactive=False, scale=1)
64
+
65
+ # Column 3: Packages & Tools Preview
66
  with gr.Column(scale=1):
67
+ gr.Markdown("### 📦 Packages & Tools")
68
  packages_display = gr.Textbox(
69
  label="Current Packages",
70
+ interactive=True,
71
+ placeholder="No deployment loaded",
72
+ lines=2
73
  )
74
+ tools_preview = gr.JSON(
75
+ label="📋 Detected Tools",
76
+ value={}
77
+ )
78
+
79
+ # Output/Result Display
80
+ output = gr.JSON(label="Result")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
 
82
  # Functions
83
  def load_deployment_list():
ui_components/stats_dashboard.py CHANGED
@@ -2,192 +2,9 @@
2
  Statistics Dashboard UI Component
3
 
4
  Analytics and visualization dashboard for deployments.
5
- Refactored from the standalone stats_dashboard.py
6
  """
7
 
8
  import gradio as gr
9
- import pandas as pd
10
- import plotly.graph_objects as go
11
- import plotly.express as px
12
- from typing import Optional
13
-
14
- from utils.database import get_db
15
- from utils.models import Deployment
16
- from utils.usage_tracker import (
17
- get_deployment_statistics,
18
- get_tool_usage_breakdown,
19
- get_usage_timeline,
20
- get_client_statistics,
21
- )
22
-
23
-
24
- # Helper Functions (prefixed with _ to hide from MCP auto-discovery)
25
- def _get_deployment_list():
26
- """Get list of all active deployments for dropdown."""
27
- try:
28
- with get_db() as db:
29
- deployments = Deployment.get_active_deployments(db)
30
- if not deployments:
31
- return []
32
- return [f"{dep.server_name} ({dep.deployment_id})" for dep in deployments]
33
- except Exception:
34
- return []
35
-
36
-
37
- def _extract_deployment_id(selection: str) -> Optional[str]:
38
- """Extract deployment_id from dropdown selection."""
39
- if not selection or "(" not in selection:
40
- return None
41
- return selection.split("(")[1].rstrip(")")
42
-
43
-
44
- def _format_number(num):
45
- """Format large numbers with K, M suffixes."""
46
- if num is None:
47
- return "N/A"
48
- if num >= 1_000_000:
49
- return f"{num/1_000_000:.1f}M"
50
- if num >= 1_000:
51
- return f"{num/1_000:.1f}K"
52
- return str(int(num))
53
-
54
-
55
- def _format_duration(ms):
56
- """Format milliseconds into human-readable duration."""
57
- if ms is None:
58
- return "N/A"
59
- if ms < 1000:
60
- return f"{int(ms)}ms"
61
- seconds = ms / 1000
62
- if seconds < 60:
63
- return f"{seconds:.1f}s"
64
- minutes = seconds / 60
65
- return f"{minutes:.1f}m"
66
-
67
-
68
- def _create_metric_card(title: str, value: str, subtitle: str = "") -> str:
69
- """Create an HTML metric card."""
70
- return f"""
71
- <div style="
72
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
73
- border-radius: 12px;
74
- padding: 24px;
75
- color: white;
76
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
77
- margin: 8px 0;
78
- ">
79
- <div style="font-size: 14px; opacity: 0.9; margin-bottom: 8px;">{title}</div>
80
- <div style="font-size: 32px; font-weight: bold; margin-bottom: 4px;">{value}</div>
81
- <div style="font-size: 12px; opacity: 0.8;">{subtitle}</div>
82
- </div>
83
- """
84
-
85
-
86
- def _create_timeline_chart(deployment_id: str, days: int = 7):
87
- """Create timeline chart showing requests over time."""
88
- timeline = get_usage_timeline(deployment_id, days=days, granularity="day")
89
-
90
- if not timeline or len(timeline) == 0:
91
- fig = go.Figure()
92
- fig.add_annotation(text="No usage data available", xref="paper", yref="paper", x=0.5, y=0.5, showarrow=False, font=dict(size=16, color="gray"))
93
- fig.update_layout(title="Requests Over Time", height=300)
94
- return fig
95
-
96
- df = pd.DataFrame(timeline)
97
- df['timestamp'] = pd.to_datetime(df['timestamp'])
98
-
99
- fig = go.Figure()
100
- fig.add_trace(go.Scatter(
101
- x=df['timestamp'], y=df['requests'], mode='lines+markers', name='Requests',
102
- line=dict(color='#667eea', width=3), marker=dict(size=8, color='#764ba2'),
103
- fill='tozeroy', fillcolor='rgba(102, 126, 234, 0.2)',
104
- ))
105
-
106
- fig.update_layout(
107
- title=f"Requests Over Time (Last {days} days)",
108
- xaxis_title="Date", yaxis_title="Requests", height=350,
109
- plot_bgcolor='rgba(0,0,0,0)', paper_bgcolor='rgba(0,0,0,0)',
110
- )
111
- return fig
112
-
113
-
114
- def _create_tool_usage_chart(deployment_id: str, days: int = 30):
115
- """Create bar chart for tool usage."""
116
- tools = get_tool_usage_breakdown(deployment_id, days=days, limit=10)
117
-
118
- if not tools or len(tools) == 0:
119
- fig = go.Figure()
120
- fig.add_annotation(text="No tool usage data available", xref="paper", yref="paper", x=0.5, y=0.5, showarrow=False, font=dict(size=16, color="gray"))
121
- fig.update_layout(title="Top Tools Used", height=300)
122
- return fig
123
-
124
- df = pd.DataFrame(tools)
125
- fig = go.Figure()
126
- fig.add_trace(go.Bar(
127
- x=df['count'], y=df['tool_name'], orientation='h',
128
- marker=dict(color=df['count'], colorscale='Viridis', showscale=False),
129
- text=df['count'], textposition='outside',
130
- ))
131
-
132
- fig.update_layout(
133
- title=f"Top Tools Used (Last {days} days)",
134
- xaxis_title="Number of Calls", yaxis_title="Tool Name",
135
- height=max(300, len(tools) * 40),
136
- plot_bgcolor='rgba(0,0,0,0)', paper_bgcolor='rgba(0,0,0,0)',
137
- )
138
- return fig
139
-
140
-
141
- def _load_deployment_stats(deployment_selection: str, days: int = 30):
142
- """Load and display statistics for selected deployment."""
143
- if not deployment_selection:
144
- return ("<div style='text-align: center; padding: 40px; color: gray;'>Please select a deployment</div>", None, None, "")
145
-
146
- deployment_id = _extract_deployment_id(deployment_selection)
147
- if not deployment_id:
148
- return ("<div style='text-align: center; padding: 40px; color: red;'>Invalid deployment</div>", None, None, "")
149
-
150
- stats = get_deployment_statistics(deployment_id, days=days)
151
- if not stats:
152
- return ("<div style='text-align: center; padding: 40px; color: red;'>Failed to load statistics</div>", None, None, "")
153
-
154
- # Create metric cards
155
- total_requests = _format_number(stats.get('total_requests', 0))
156
- success_rate = stats.get('success_rate_percent', 0)
157
- avg_time = _format_duration(stats.get('avg_response_time_ms'))
158
- failed_requests = _format_number(stats.get('failed_requests', 0))
159
-
160
- metrics_html = f"""
161
- <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; margin: 20px 0;">
162
- {_create_metric_card("Total Requests", total_requests, f"Last {days} days")}
163
- {_create_metric_card("Success Rate", f"{success_rate:.1f}%", f"{failed_requests} failures")}
164
- {_create_metric_card("Avg Response Time", avg_time, "Per request")}
165
- {_create_metric_card("Active Period", f"{days} days", "Data retention")}
166
- </div>
167
- """
168
-
169
- # Get deployment info
170
- with get_db() as db:
171
- deployment = Deployment.get_by_deployment_id(db, deployment_id)
172
- if deployment:
173
- last_used = deployment.last_used_at.strftime("%Y-%m-%d %H:%M UTC") if deployment.last_used_at else "Never"
174
- created = deployment.created_at.strftime("%Y-%m-%d %H:%M UTC") if deployment.created_at else "Unknown"
175
- info_text = f"""
176
- **Deployment Information**
177
- - **Server Name:** {deployment.server_name}
178
- - **Status:** {deployment.status}
179
- - **Created:** {created}
180
- - **Last Used:** {last_used}
181
- - **URL:** {deployment.url}
182
- """
183
- else:
184
- info_text = "Deployment information not available"
185
-
186
- # Create charts
187
- timeline_chart = _create_timeline_chart(deployment_id, days)
188
- tool_chart = _create_tool_usage_chart(deployment_id, days)
189
-
190
- return (metrics_html, timeline_chart, tool_chart, info_text)
191
 
192
 
193
  def create_stats_dashboard():
@@ -201,61 +18,51 @@ def create_stats_dashboard():
201
  gr.Markdown("## 📊 Statistics Dashboard")
202
  gr.Markdown("Monitor and analyze your deployed MCP servers")
203
 
204
- with gr.Row():
205
- with gr.Column(scale=3):
206
- deployment_dropdown = gr.Dropdown(
207
- choices=_get_deployment_list(),
208
- label="Select Deployment",
209
- info="Choose a deployment to view its statistics",
210
- interactive=True,
211
- )
212
- with gr.Column(scale=1):
213
- days_slider = gr.Slider(
214
- minimum=1, maximum=90, value=30, step=1,
215
- label="Time Range (days)",
216
- info="Number of days to analyze"
217
- )
218
- with gr.Column(scale=1):
219
- refresh_btn = gr.Button("🔄 Refresh", variant="secondary", size="sm")
220
-
221
- # Metrics Cards
222
- metrics_html = gr.HTML(
223
- "<div style='text-align: center; padding: 40px; color: gray;'>Select a deployment to view statistics</div>"
224
- )
225
-
226
- # Charts Row
227
- with gr.Row():
228
- with gr.Column():
229
- timeline_plot = gr.Plot(label="Request Timeline")
230
- with gr.Column():
231
- tool_plot = gr.Plot(label="Tool Usage")
232
-
233
- # Deployment Info
234
- with gr.Accordion("📋 Deployment Details", open=False):
235
- deployment_info = gr.Markdown("Select a deployment to view details")
236
-
237
- # Event handlers
238
- def _update_stats(deployment, days):
239
- return _load_deployment_stats(deployment, int(days))
240
-
241
- deployment_dropdown.change(
242
- fn=_update_stats,
243
- inputs=[deployment_dropdown, days_slider],
244
- outputs=[metrics_html, timeline_plot, tool_plot, deployment_info],
245
- api_visibility="private" # Don't expose UI handler as MCP tool
246
- )
247
-
248
- days_slider.change(
249
- fn=_update_stats,
250
- inputs=[deployment_dropdown, days_slider],
251
- outputs=[metrics_html, timeline_plot, tool_plot, deployment_info],
252
- api_visibility="private" # Don't expose UI handler as MCP tool
253
- )
254
-
255
- refresh_btn.click(
256
- fn=lambda: gr.Dropdown(choices=_get_deployment_list()),
257
- outputs=[deployment_dropdown],
258
- api_visibility="private" # Don't expose UI handler as MCP tool
259
- )
260
 
261
  return dashboard
 
2
  Statistics Dashboard UI Component
3
 
4
  Analytics and visualization dashboard for deployments.
 
5
  """
6
 
7
  import gradio as gr
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
 
10
  def create_stats_dashboard():
 
18
  gr.Markdown("## 📊 Statistics Dashboard")
19
  gr.Markdown("Monitor and analyze your deployed MCP servers")
20
 
21
+ # Coming Soon message with styling
22
+ gr.HTML("""
23
+ <div style="
24
+ display: flex;
25
+ flex-direction: column;
26
+ align-items: center;
27
+ justify-content: center;
28
+ min-height: 400px;
29
+ padding: 60px 20px;
30
+ text-align: center;
31
+ ">
32
+ <div style="
33
+ font-size: 72px;
34
+ margin-bottom: 24px;
35
+ ">📊</div>
36
+ <h2 style="
37
+ font-size: 36px;
38
+ font-weight: bold;
39
+ margin-bottom: 16px;
40
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
41
+ -webkit-background-clip: text;
42
+ -webkit-text-fill-color: transparent;
43
+ background-clip: text;
44
+ ">Coming Soon!</h2>
45
+ <p style="
46
+ font-size: 18px;
47
+ color: #666;
48
+ max-width: 500px;
49
+ line-height: 1.6;
50
+ ">
51
+ We're working on powerful analytics and visualization tools
52
+ to help you monitor your MCP server deployments.
53
+ </p>
54
+ <div style="
55
+ margin-top: 32px;
56
+ padding: 16px 24px;
57
+ background: rgba(102, 126, 234, 0.1);
58
+ border-radius: 12px;
59
+ border: 1px solid rgba(102, 126, 234, 0.2);
60
+ ">
61
+ <p style="margin: 0; color: #667eea; font-size: 14px;">
62
+ Features in development: Request analytics, Tool usage breakdown, Performance metrics
63
+ </p>
64
+ </div>
65
+ </div>
66
+ """)
 
 
 
 
 
 
 
 
 
 
67
 
68
  return dashboard