theguywhosucks commited on
Commit
e430628
Β·
verified Β·
1 Parent(s): a36cfb6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +107 -114
app.py CHANGED
@@ -1,8 +1,7 @@
1
  import gradio as gr
2
  from gradio_client import Client
3
- import json
4
  import random
5
- from datetime import datetime
6
 
7
  # Backend engines
8
  BACKEND_ENGINES = [
@@ -10,14 +9,18 @@ BACKEND_ENGINES = [
10
  "ChocoLaboratory/SANDBOX_BACKEND"
11
  ]
12
 
 
13
  class SandboxManager:
14
  def __init__(self):
15
  self.client = None
16
  self.current_engine = None
17
  self.is_connected = False
 
 
18
 
19
  def select_random_engine(self):
20
- self.current_engine = random.choice(BACKEND_ENGINES)
 
21
  return self.current_engine
22
 
23
  def connect(self):
@@ -30,183 +33,173 @@ class SandboxManager:
30
  self.is_connected = False
31
  self.current_engine = None
32
  return f"βœ— Connection failed to {engine}: {str(e)}", "Not connected"
 
 
 
 
 
 
 
 
33
 
34
  def launch_sandbox(self, main_py_code, requirements_txt):
35
  if not self.is_connected:
36
  return "βœ— Not connected to backend. Please connect first.", ""
 
 
37
  try:
38
  result = self.client.predict(
39
  code=main_py_code,
40
  requirements=requirements_txt,
41
  api_name="/launch_sandbox"
42
  )
 
43
  return f"βœ“ Sandbox deployed successfully on {self.current_engine}\n\nResponse: {result}", self.get_status()
44
  except Exception as e:
45
  return f"βœ— Deployment failed: {str(e)}", ""
46
 
47
- def fetch_logs(self):
48
- if not self.is_connected:
49
- return "βœ— Not connected to backend"
50
- try:
51
- result = self.client.predict(api_name="/fetch_logs")
52
- timestamp = datetime.now().strftime("%H:%M:%S")
53
- return f"[{timestamp}] Logs from {self.current_engine}:\n\n{result}"
54
- except Exception as e:
55
- return f"[ERROR] Failed to fetch logs: {str(e)}"
56
-
57
  def kill_sandbox(self):
58
  if not self.is_connected:
59
  return "βœ— Not connected to backend", ""
 
 
60
  try:
61
  result = self.client.predict(api_name="/kill_sandbox")
 
62
  return f"βœ“ Sandbox terminated on {self.current_engine}\n\nResponse: {result}", self.get_status()
63
  except Exception as e:
64
  return f"βœ— Termination failed: {str(e)}", ""
65
-
66
  def get_status(self):
67
  if not self.is_connected:
68
  return "OFFLINE"
 
 
 
 
 
 
 
 
 
 
 
69
  try:
70
- result = self.client.predict(api_name="/status_sandbox")
71
- if "running" in str(result).lower():
72
- return f"RUNNING - {result}"
73
- else:
74
- return f"IDLE - {result}"
75
  except Exception as e:
76
- return f"ERROR - {str(e)}"
77
 
78
  # Initialize sandbox manager
79
  sandbox = SandboxManager()
80
 
81
- # Sample files
82
  SAMPLE_MAIN_PY = "# Enterprise Python Application\nprint('Sandbox Compute Platform - Ready')"
83
  SAMPLE_REQUIREMENTS_TXT = "# Production dependencies\n# Specify exact versions for reproducibility"
84
 
85
- # Industrial-grade CSS
86
- industrial_css = """
87
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap');
88
 
89
  :root {
90
- --primary-color: #1f2937;
91
- --primary-hover: #111827;
92
- --secondary-color: #4b5563;
93
- --success-color: #10b981;
94
- --warning-color: #f59e0b;
95
- --danger-color: #ef4444;
96
- --background: #f3f4f6;
97
  --surface: #ffffff;
98
  --border: #d1d5db;
99
  --text-primary: #111827;
100
- --text-secondary: #6b7280;
101
- --text-muted: #9ca3af;
102
  }
103
 
104
- .gradio-container { font-family: 'Inter', sans-serif !important; background-color: var(--background) !important; min-height: 100vh; }
105
-
106
- .platform-header { background: linear-gradient(90deg, var(--primary-color), var(--primary-hover)) !important; color: #f9fafb !important; padding: 20px 32px !important; border-bottom: 4px solid var(--primary-color); box-shadow: 0 6px 12px rgba(0,0,0,0.15); }
107
- .platform-title { font-size: 26px !important; font-weight: 700 !important; }
108
- .platform-subtitle { font-size: 14px !important; opacity: 0.85 !important; margin-top: 4px !important; }
109
-
110
- .nav-breadcrumb { background-color: #e5e7eb !important; padding: 12px 24px !important; font-size: 13px !important; color: var(--text-secondary) !important; border-bottom: 1px solid var(--border) !important; border-radius: 6px !important; margin-top: 8px !important; }
111
-
112
- .enterprise-container { background-color: var(--surface) !important; border: 1px solid var(--border) !important; border-radius: 12px !important; margin: 16px 0 !important; overflow: hidden !important; box-shadow: 0 2px 6px rgba(0,0,0,0.06) !important; }
113
- .container-header { background: linear-gradient(to right, #f9fafb, #f3f4f6) !important; border-bottom: 1px solid var(--border) !important; padding: 14px 24px !important; font-weight: 600 !important; font-size: 16px !important; display: flex !important; align-items: center; gap: 8px !important; }
114
- .container-content { padding: 20px !important; }
115
 
116
- .btn-primary { background: linear-gradient(135deg, var(--primary-color), var(--primary-hover)) !important; color: #fff !important; border-radius: 6px !important; padding: 10px 24px !important; font-weight: 500 !important; transition: all 0.2s ease !important; }
117
- .btn-primary:hover { transform: translateY(-1px); box-shadow: 0 4px 8px rgba(0,0,0,0.15) !important; }
118
- .btn-secondary { background-color: var(--surface) !important; border: 1px solid var(--border) !important; color: var(--text-primary) !important; border-radius: 6px !important; padding: 10px 24px !important; }
119
- .btn-secondary:hover { background-color: #f9fafb !important; border-color: var(--secondary-color) !important; }
120
- .btn-danger { background: linear-gradient(135deg, var(--danger-color), #b91c1c) !important; color: #fff !important; border-radius: 6px !important; padding: 10px 24px !important; }
121
 
122
- .status-online { background: #d1fae5 !important; color: var(--success-color) !important; }
123
- .status-offline { background: #fee2e2 !important; color: var(--danger-color) !important; }
124
- .status-warning { background: #fef3c7 !important; color: var(--warning-color) !important; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
 
126
- .code-editor-professional { font-family: 'JetBrains Mono', monospace !important; background: #1f2937 !important; color: #f3f4f6 !important; border-radius: 8px !important; padding: 12px !important; }
127
- .requirements-editor { font-family: 'JetBrains Mono', monospace !important; background: #27272a !important; color: #f3f4f6 !important; border-radius: 8px !important; padding: 10px !important; }
128
- .terminal-logs { font-family: 'JetBrains Mono', monospace !important; background: #0f172a !important; color: #e2e8f0 !important; border-radius: 8px !important; padding: 14px !important; }
129
 
130
- .monitoring-panel { border-radius: 12px !important; padding: 0 !important; margin: 16px 0 !important; box-shadow: 0 2px 4px rgba(0,0,0,0.06) !important; }
131
- .panel-header { padding: 12px 16px !important; font-weight: 600 !important; background: #f3f4f6; border-bottom: 1px solid var(--border) !important; }
132
- .panel-content { padding: 16px !important; }
133
- """
134
 
135
- def auto_refresh_status(): return sandbox.get_status()
136
- def auto_refresh_logs(): return sandbox.fetch_logs()
137
- def load_sample_files(): return SAMPLE_MAIN_PY, SAMPLE_REQUIREMENTS_TXT
138
 
139
  # Build Gradio interface
140
- with gr.Blocks(css=industrial_css, title="Sandbox Compute Platform") as demo:
 
141
  gr.HTML("""
142
  <div class="platform-header">
143
  <div class="platform-title">Sandbox Compute Platform</div>
144
  <div class="platform-subtitle">Enterprise-grade cloud computing infrastructure</div>
145
  </div>
146
- <div class="nav-breadcrumb">
147
- Sandbox Management Console
148
- </div>
149
  """)
150
-
151
  with gr.Row():
152
- # Main Content
153
  with gr.Column(scale=3):
154
  with gr.Group(elem_classes=["enterprise-container"]):
155
  gr.HTML('<div class="container-header">πŸ”§ Infrastructure Management</div>')
156
- with gr.Group(elem_classes=["container-content"]):
157
- with gr.Row():
158
- connect_btn = gr.Button("Initialize Connection", elem_classes=["btn-primary"])
159
- load_samples_btn = gr.Button("Load Templates", elem_classes=["btn-secondary"])
160
- gr.HTML('<div class="form-label mt-4">Active Compute Engine</div>')
161
- current_engine_display = gr.Textbox(value="No engine selected", interactive=False, elem_classes=["info-badge"], show_label=False)
162
- gr.HTML('<div class="form-label mt-4">Connection Status</div>')
163
- connection_status = gr.Textbox(value="DISCONNECTED", interactive=False, elem_classes=["status-offline"], show_label=False)
164
-
165
  with gr.Group(elem_classes=["enterprise-container"]):
166
  gr.HTML('<div class="container-header">πŸ’» Development Environment</div>')
167
- with gr.Group(elem_classes=["container-content"]):
168
- with gr.Tab("main.py"):
169
- gr.HTML('<div class="form-label">Application Source Code</div>')
170
- main_py_editor = gr.Code(value=SAMPLE_MAIN_PY, language="python", lines=20, elem_classes=["code-editor-professional"], show_label=False)
171
- with gr.Tab("requirements.txt"):
172
- gr.HTML('<div class="form-label">Dependency Specifications</div>')
173
- requirements_editor = gr.Textbox(value=SAMPLE_REQUIREMENTS_TXT, lines=20, elem_classes=["requirements-editor"], show_label=False, max_lines=25)
174
- gr.HTML('<div class="section-divider"></div>')
175
- with gr.Row():
176
- launch_btn = gr.Button("Deploy Application", elem_classes=["btn-primary"], size="lg")
177
- kill_btn = gr.Button("Terminate Instance", elem_classes=["btn-danger"], size="lg")
178
- gr.HTML('<div class="form-label mt-4">Deployment Output</div>')
179
- launch_output = gr.Textbox(lines=6, interactive=False, placeholder="Deployment logs and status information will appear here...", elem_classes=["terminal-logs"], show_label=False)
180
-
181
- # Monitoring Panel
182
  with gr.Column(scale=1):
183
- with gr.Group(elem_classes=["monitoring-panel"]):
184
- gr.HTML('<div class="panel-header">πŸ“Š System Monitor</div>')
185
- with gr.Group(elem_classes=["panel-content"]):
186
- gr.HTML('<div class="form-label">Instance Status</div>')
187
- status_display = gr.Textbox(value="OFFLINE", interactive=False, elem_classes=["status-offline"], show_label=False)
188
- status_refresh_btn = gr.Button("Refresh Status", elem_classes=["btn-secondary"], size="sm")
189
- gr.HTML('<div class="section-divider"></div>')
190
- gr.HTML('<div class="form-label">Monitoring Settings</div>')
191
- auto_refresh_status_cb = gr.Checkbox(label="Auto-refresh status (5s interval)", value=False)
192
- auto_refresh_logs_cb = gr.Checkbox(label="Auto-refresh logs (10s interval)", value=False)
193
-
194
- # Logs Section
195
- with gr.Group(elem_classes=["enterprise-container"]):
196
- gr.HTML('<div class="container-header">πŸ“‹ System Logs</div>')
197
- with gr.Group(elem_classes=["container-content"]):
198
- with gr.Row():
199
- fetch_logs_btn = gr.Button("Fetch Application Logs", elem_classes=["btn-secondary"])
200
- gr.HTML('<div style="flex-grow: 1;"></div>')
201
- gr.HTML('<div class="form-label mt-4">Runtime Logs</div>')
202
- logs_display = gr.Textbox(lines=14, interactive=False, elem_classes=["terminal-logs"], placeholder="[SYSTEM] Logs will appear here...", show_label=False)
203
-
204
  # Event Handlers
205
  connect_btn.click(fn=sandbox.connect, outputs=[connection_status, current_engine_display])
206
  load_samples_btn.click(fn=load_sample_files, outputs=[main_py_editor, requirements_editor])
207
  launch_btn.click(fn=sandbox.launch_sandbox, inputs=[main_py_editor, requirements_editor], outputs=[launch_output, status_display])
208
  kill_btn.click(fn=sandbox.kill_sandbox, outputs=[launch_output, status_display])
209
- fetch_logs_btn.click(fn=sandbox.fetch_logs, outputs=logs_display)
210
  status_refresh_btn.click(fn=auto_refresh_status, outputs=status_display)
 
211
 
212
- demo.launch()
 
 
1
  import gradio as gr
2
  from gradio_client import Client
 
3
  import random
4
+ from datetime import datetime, timedelta
5
 
6
  # Backend engines
7
  BACKEND_ENGINES = [
 
9
  "ChocoLaboratory/SANDBOX_BACKEND"
10
  ]
11
 
12
+ # Sandbox Manager
13
  class SandboxManager:
14
  def __init__(self):
15
  self.client = None
16
  self.current_engine = None
17
  self.is_connected = False
18
+ self.sandbox_start_time = None
19
+ self.sandbox_duration = timedelta(hours=2) # 2-hour limit
20
 
21
  def select_random_engine(self):
22
+ if not self.current_engine:
23
+ self.current_engine = random.choice(BACKEND_ENGINES)
24
  return self.current_engine
25
 
26
  def connect(self):
 
33
  self.is_connected = False
34
  self.current_engine = None
35
  return f"βœ— Connection failed to {engine}: {str(e)}", "Not connected"
36
+
37
+ def check_sandbox_active(self):
38
+ if self.sandbox_start_time:
39
+ if datetime.now() - self.sandbox_start_time > self.sandbox_duration:
40
+ self.sandbox_start_time = None
41
+ return False
42
+ return True
43
+ return False
44
 
45
  def launch_sandbox(self, main_py_code, requirements_txt):
46
  if not self.is_connected:
47
  return "βœ— Not connected to backend. Please connect first.", ""
48
+ if self.check_sandbox_active():
49
+ return "⚠ Sandbox is still active. You cannot deploy another until 2 hours have passed.", self.get_status()
50
  try:
51
  result = self.client.predict(
52
  code=main_py_code,
53
  requirements=requirements_txt,
54
  api_name="/launch_sandbox"
55
  )
56
+ self.sandbox_start_time = datetime.now()
57
  return f"βœ“ Sandbox deployed successfully on {self.current_engine}\n\nResponse: {result}", self.get_status()
58
  except Exception as e:
59
  return f"βœ— Deployment failed: {str(e)}", ""
60
 
 
 
 
 
 
 
 
 
 
 
61
  def kill_sandbox(self):
62
  if not self.is_connected:
63
  return "βœ— Not connected to backend", ""
64
+ if not self.check_sandbox_active():
65
+ return "⚠ No active sandbox to terminate.", self.get_status()
66
  try:
67
  result = self.client.predict(api_name="/kill_sandbox")
68
+ self.sandbox_start_time = None
69
  return f"βœ“ Sandbox terminated on {self.current_engine}\n\nResponse: {result}", self.get_status()
70
  except Exception as e:
71
  return f"βœ— Termination failed: {str(e)}", ""
72
+
73
  def get_status(self):
74
  if not self.is_connected:
75
  return "OFFLINE"
76
+ if self.check_sandbox_active():
77
+ remaining = self.sandbox_duration - (datetime.now() - self.sandbox_start_time)
78
+ hrs, rem = divmod(remaining.seconds, 3600)
79
+ mins, sec = divmod(rem, 60)
80
+ return f"RUNNING - {hrs}h {mins}m remaining"
81
+ else:
82
+ return "IDLE"
83
+
84
+ def fetch_logs(self):
85
+ if not self.is_connected:
86
+ return "βœ— Not connected to backend"
87
  try:
88
+ result = self.client.predict(api_name="/fetch_logs")
89
+ timestamp = datetime.now().strftime("%H:%M:%S")
90
+ return f"[{timestamp}] Logs from {self.current_engine}:\n\n{result}"
 
 
91
  except Exception as e:
92
+ return f"[ERROR] Failed to fetch logs: {str(e)}"
93
 
94
  # Initialize sandbox manager
95
  sandbox = SandboxManager()
96
 
97
+ # Sample templates
98
  SAMPLE_MAIN_PY = "# Enterprise Python Application\nprint('Sandbox Compute Platform - Ready')"
99
  SAMPLE_REQUIREMENTS_TXT = "# Production dependencies\n# Specify exact versions for reproducibility"
100
 
101
+ # Readable and professional CSS
102
+ professional_css = """
103
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap');
104
 
105
  :root {
106
+ --primary-color: #1e40af;
107
+ --primary-hover: #2563eb;
108
+ --secondary-color: #374151;
109
+ --success-color: #059669;
110
+ --warning-color: #d97706;
111
+ --danger-color: #b91c1c;
112
+ --background: #f9fafb;
113
  --surface: #ffffff;
114
  --border: #d1d5db;
115
  --text-primary: #111827;
116
+ --text-secondary: #4b5563;
117
+ --text-muted: #6b7280;
118
  }
119
 
120
+ .gradio-container {
121
+ font-family: 'Inter', sans-serif !important;
122
+ background-color: var(--background) !important;
123
+ color: var(--text-primary) !important;
124
+ min-height: 100vh;
125
+ }
 
 
 
 
 
126
 
127
+ .platform-header {
128
+ background: #1e40af !important;
129
+ color: white !important;
130
+ padding: 16px 24px !important;
131
+ }
132
 
133
+ .platform-title { font-size: 24px; font-weight: 700; }
134
+ .platform-subtitle { font-size: 14px; opacity: 0.85; margin-top: 4px; }
135
+
136
+ .enterprise-container { background-color: var(--surface); border: 1px solid var(--border); border-radius: 12px; margin: 20px; padding: 16px; }
137
+ .container-header { font-weight: 600; font-size: 16px; margin-bottom: 12px; }
138
+ .code-editor-professional { font-family: 'JetBrains Mono', monospace; background: #1e1e1e; color: #f9fafb; border-radius: 8px; padding: 8px; }
139
+ .requirements-editor { font-family: 'JetBrains Mono', monospace; background: #2d2d2d; color: #f9fafb; border-radius: 8px; padding: 8px; }
140
+ .terminal-logs { font-family: 'JetBrains Mono', monospace; background: #0f172a; color: #e2e8f0; border-radius: 8px; padding: 16px; }
141
+ .btn-primary { background: var(--primary-color); color: white; border-radius: 8px; padding: 12px; }
142
+ .btn-primary:hover { background: var(--primary-hover); }
143
+ .btn-secondary { background: var(--surface); color: var(--text-primary); border: 1px solid var(--border); border-radius: 8px; padding: 12px; }
144
+ .btn-secondary:hover { background: #f3f4f6; }
145
+ .btn-danger { background: var(--danger-color); color: white; border-radius: 8px; padding: 12px; }
146
+ .status-online { background: #d1fae5; color: var(--success-color); padding: 16px; border-radius: 8px; text-align: center; }
147
+ .status-offline { background: #fee2e2; color: var(--danger-color); padding: 16px; border-radius: 8px; text-align: center; }
148
+ .status-warning { background: #fef3c7; color: var(--warning-color); padding: 16px; border-radius: 8px; text-align: center; }
149
+ .section-divider { height: 1px; background: var(--border); margin: 24px 0; }
150
+ """
151
 
152
+ def auto_refresh_status():
153
+ return sandbox.get_status()
 
154
 
155
+ def auto_refresh_logs():
156
+ return sandbox.fetch_logs()
 
 
157
 
158
+ def load_sample_files():
159
+ return SAMPLE_MAIN_PY, SAMPLE_REQUIREMENTS_TXT
 
160
 
161
  # Build Gradio interface
162
+ with gr.Blocks(css=professional_css, title="Sandbox Compute Platform") as demo:
163
+
164
  gr.HTML("""
165
  <div class="platform-header">
166
  <div class="platform-title">Sandbox Compute Platform</div>
167
  <div class="platform-subtitle">Enterprise-grade cloud computing infrastructure</div>
168
  </div>
 
 
 
169
  """)
170
+
171
  with gr.Row():
 
172
  with gr.Column(scale=3):
173
  with gr.Group(elem_classes=["enterprise-container"]):
174
  gr.HTML('<div class="container-header">πŸ”§ Infrastructure Management</div>')
175
+ connect_btn = gr.Button("Initialize Connection", elem_classes=["btn-primary"])
176
+ load_samples_btn = gr.Button("Load Templates", elem_classes=["btn-secondary"])
177
+ current_engine_display = gr.Textbox(value="No engine selected", interactive=False, elem_classes=["status-warning"], show_label=False)
178
+ connection_status = gr.Textbox(value="DISCONNECTED", interactive=False, elem_classes=["status-offline"], show_label=False)
179
+
 
 
 
 
180
  with gr.Group(elem_classes=["enterprise-container"]):
181
  gr.HTML('<div class="container-header">πŸ’» Development Environment</div>')
182
+ main_py_editor = gr.Code(value=SAMPLE_MAIN_PY, language="python", lines=20, elem_classes=["code-editor-professional"], show_label=False)
183
+ requirements_editor = gr.Textbox(value=SAMPLE_REQUIREMENTS_TXT, lines=20, elem_classes=["requirements-editor"], show_label=False)
184
+ gr.HTML('<div class="section-divider"></div>')
185
+ launch_btn = gr.Button("Deploy Application", elem_classes=["btn-primary"])
186
+ kill_btn = gr.Button("Terminate Instance", elem_classes=["btn-danger"])
187
+ launch_output = gr.Textbox(lines=6, interactive=False, elem_classes=["terminal-logs"], show_label=False)
188
+
 
 
 
 
 
 
 
 
189
  with gr.Column(scale=1):
190
+ gr.HTML('<div class="container-header">πŸ“Š System Monitor</div>')
191
+ status_display = gr.Textbox(value="OFFLINE", interactive=False, elem_classes=["status-offline"], show_label=False)
192
+ status_refresh_btn = gr.Button("Refresh Status", elem_classes=["btn-secondary"])
193
+ fetch_logs_btn = gr.Button("Fetch Application Logs", elem_classes=["btn-secondary"])
194
+ logs_display = gr.Textbox(lines=14, interactive=False, elem_classes=["terminal-logs"], show_label=False)
195
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  # Event Handlers
197
  connect_btn.click(fn=sandbox.connect, outputs=[connection_status, current_engine_display])
198
  load_samples_btn.click(fn=load_sample_files, outputs=[main_py_editor, requirements_editor])
199
  launch_btn.click(fn=sandbox.launch_sandbox, inputs=[main_py_editor, requirements_editor], outputs=[launch_output, status_display])
200
  kill_btn.click(fn=sandbox.kill_sandbox, outputs=[launch_output, status_display])
 
201
  status_refresh_btn.click(fn=auto_refresh_status, outputs=status_display)
202
+ fetch_logs_btn.click(fn=auto_refresh_logs, outputs=logs_display)
203
 
204
+ if __name__ == "__main__":
205
+ demo.launch(share=True, server_name="0.0.0.0", server_port=7860)