theguywhosucks commited on
Commit
daa18cc
·
verified ·
1 Parent(s): 54383a3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +30 -52
app.py CHANGED
@@ -5,43 +5,37 @@ import resource
5
  import multiprocessing
6
  import signal
7
  import time
8
- import threading
9
  import shutil
10
  import gradio as gr
 
11
 
12
  # -------------------------
13
- # Store running sandboxes
14
  # -------------------------
15
  sandboxes = {}
16
- SANDBOX_TTL = 2 * 3600 # 2 hours
17
- MAX_RAM = 4 * 1024**3 # 4GB
18
 
19
  # -------------------------
20
- # Sandbox worker function
21
  # -------------------------
22
- def sandbox_worker(code: str, requirements: str, sandbox_id: str):
23
  user_dir = f"/tmp/sandbox_{sandbox_id}"
24
  os.makedirs(user_dir, exist_ok=True)
25
  os.chdir(user_dir)
26
 
27
- # Save requirements.txt
28
- req_file = os.path.join(user_dir, "requirements.txt")
29
- with open(req_file, "w") as f:
30
- f.write(requirements)
31
-
32
  # Resource limits
33
- resource.setrlimit(resource.RLIMIT_AS, (MAX_RAM, MAX_RAM))
34
- resource.setrlimit(resource.RLIMIT_CPU, (SANDBOX_TTL, SANDBOX_TTL))
35
 
36
- # Save user code
37
- code_file = os.path.join(user_dir, "user_code.py")
38
  with open(code_file, "w") as f:
39
  f.write(code)
 
40
 
41
- # Run code
42
  try:
43
  result = subprocess.run(
44
- ["python3", code_file],
45
  capture_output=True,
46
  text=True,
47
  timeout=SANDBOX_TTL
@@ -53,10 +47,10 @@ def sandbox_worker(code: str, requirements: str, sandbox_id: str):
53
  f.write(result.stderr)
54
  except subprocess.TimeoutExpired:
55
  with open(os.path.join(user_dir, "stderr.log"), "w") as f:
56
- f.write("Execution timed out (2h limit reached).")
57
 
58
  # -------------------------
59
- # Cleanup thread
60
  # -------------------------
61
  def cleanup_sandboxes():
62
  while True:
@@ -76,11 +70,11 @@ def cleanup_sandboxes():
76
  threading.Thread(target=cleanup_sandboxes, daemon=True).start()
77
 
78
  # -------------------------
79
- # Gradio interface functions
80
  # -------------------------
81
- def launch_sandbox(code, requirements):
82
  sandbox_id = str(uuid.uuid4())[:8]
83
- p = multiprocessing.Process(target=sandbox_worker, args=(code, requirements, sandbox_id))
84
  p.start()
85
  sandboxes[sandbox_id] = {"pid": p.pid, "start_time": time.time()}
86
  return f"Sandbox launched! ID: {sandbox_id}", sandbox_id
@@ -89,40 +83,36 @@ def fetch_logs(sandbox_id):
89
  user_dir = f"/tmp/sandbox_{sandbox_id}"
90
  if not os.path.exists(user_dir):
91
  return "Sandbox not found."
92
- stdout_file = os.path.join(user_dir, "stdout.log")
93
- stderr_file = os.path.join(user_dir, "stderr.log")
94
- stdout = open(stdout_file).read() if os.path.exists(stdout_file) else ""
95
- stderr = open(stderr_file).read() if os.path.exists(stderr_file) else ""
96
  return f"STDOUT:\n{stdout}\n\nSTDERR:\n{stderr}"
97
 
98
  def kill_sandbox(sandbox_id):
99
  if sandbox_id not in sandboxes:
100
  return "Sandbox not found."
101
- pid = sandboxes[sandbox_id]["pid"]
102
  try:
103
- os.kill(pid, signal.SIGKILL)
104
  folder = f"/tmp/sandbox_{sandbox_id}"
105
  if os.path.exists(folder):
106
  shutil.rmtree(folder)
107
  del sandboxes[sandbox_id]
108
  return f"Sandbox {sandbox_id} killed."
109
  except Exception as e:
110
- return f"Error killing sandbox: {e}"
111
 
112
  def status_sandbox(sandbox_id):
113
  if sandbox_id not in sandboxes:
114
  return "Sandbox not found."
115
- elapsed = time.time() - sandboxes[sandbox_id]["start_time"]
116
- return f"Running for {int(elapsed)} seconds"
117
 
118
  # -------------------------
119
  # Gradio UI
120
  # -------------------------
121
  with gr.Blocks() as demo:
122
- gr.Markdown("# Sandbox Backend with requirements.txt support")
123
 
124
- code_input = gr.Textbox(label="Python Code", lines=15, placeholder="Write your code here...")
125
- req_input = gr.Textbox(label="requirements.txt", lines=5, placeholder="Add dependencies here...")
126
  launch_btn = gr.Button("Launch Sandbox")
127
  sandbox_id_output = gr.Textbox(label="Sandbox ID")
128
 
@@ -135,27 +125,15 @@ with gr.Blocks() as demo:
135
  status_btn = gr.Button("Check Status")
136
  status_output = gr.Textbox(label="Sandbox Status")
137
 
138
- sandbox_id_storage = gr.State(value=None)
139
 
140
  launch_btn.click(
141
  launch_sandbox,
142
- inputs=[code_input, req_input],
143
- outputs=[sandbox_id_output, sandbox_id_storage]
144
- )
145
- logs_btn.click(
146
- fetch_logs,
147
- inputs=sandbox_id_storage,
148
- outputs=logs_output
149
- )
150
- kill_btn.click(
151
- kill_sandbox,
152
- inputs=sandbox_id_storage,
153
- outputs=kill_output
154
- )
155
- status_btn.click(
156
- status_sandbox,
157
- inputs=sandbox_id_storage,
158
- outputs=status_output
159
  )
 
 
 
160
 
161
  demo.launch()
 
5
  import multiprocessing
6
  import signal
7
  import time
 
8
  import shutil
9
  import gradio as gr
10
+ import threading
11
 
12
  # -------------------------
13
+ # Sandbox storage
14
  # -------------------------
15
  sandboxes = {}
16
+ SANDBOX_TTL = 2*3600 # 2 hours
 
17
 
18
  # -------------------------
19
+ # Worker to run bare-metal process
20
  # -------------------------
21
+ def sandbox_worker(code: str, sandbox_id: str):
22
  user_dir = f"/tmp/sandbox_{sandbox_id}"
23
  os.makedirs(user_dir, exist_ok=True)
24
  os.chdir(user_dir)
25
 
 
 
 
 
 
26
  # Resource limits
27
+ resource.setrlimit(resource.RLIMIT_AS, (4*1024**3, 4*1024**3)) # 4GB RAM
28
+ resource.setrlimit(resource.RLIMIT_CPU, (SANDBOX_TTL, SANDBOX_TTL)) # 2h CPU
29
 
30
+ # Save code as a script
31
+ code_file = os.path.join(user_dir, "user_code.sh")
32
  with open(code_file, "w") as f:
33
  f.write(code)
34
+ os.chmod(code_file, 0o755) # make executable
35
 
 
36
  try:
37
  result = subprocess.run(
38
+ ["/bin/bash", code_file],
39
  capture_output=True,
40
  text=True,
41
  timeout=SANDBOX_TTL
 
47
  f.write(result.stderr)
48
  except subprocess.TimeoutExpired:
49
  with open(os.path.join(user_dir, "stderr.log"), "w") as f:
50
+ f.write("Execution timed out (2h limit).")
51
 
52
  # -------------------------
53
+ # Auto-cleanup thread
54
  # -------------------------
55
  def cleanup_sandboxes():
56
  while True:
 
70
  threading.Thread(target=cleanup_sandboxes, daemon=True).start()
71
 
72
  # -------------------------
73
+ # Gradio API functions
74
  # -------------------------
75
+ def launch_sandbox(code):
76
  sandbox_id = str(uuid.uuid4())[:8]
77
+ p = multiprocessing.Process(target=sandbox_worker, args=(code, sandbox_id))
78
  p.start()
79
  sandboxes[sandbox_id] = {"pid": p.pid, "start_time": time.time()}
80
  return f"Sandbox launched! ID: {sandbox_id}", sandbox_id
 
83
  user_dir = f"/tmp/sandbox_{sandbox_id}"
84
  if not os.path.exists(user_dir):
85
  return "Sandbox not found."
86
+ stdout = open(os.path.join(user_dir, "stdout.log")).read() if os.path.exists(os.path.join(user_dir, "stdout.log")) else ""
87
+ stderr = open(os.path.join(user_dir, "stderr.log")).read() if os.path.exists(os.path.join(user_dir, "stderr.log")) else ""
 
 
88
  return f"STDOUT:\n{stdout}\n\nSTDERR:\n{stderr}"
89
 
90
  def kill_sandbox(sandbox_id):
91
  if sandbox_id not in sandboxes:
92
  return "Sandbox not found."
 
93
  try:
94
+ os.kill(sandboxes[sandbox_id]["pid"], signal.SIGKILL)
95
  folder = f"/tmp/sandbox_{sandbox_id}"
96
  if os.path.exists(folder):
97
  shutil.rmtree(folder)
98
  del sandboxes[sandbox_id]
99
  return f"Sandbox {sandbox_id} killed."
100
  except Exception as e:
101
+ return f"Error: {e}"
102
 
103
  def status_sandbox(sandbox_id):
104
  if sandbox_id not in sandboxes:
105
  return "Sandbox not found."
106
+ elapsed = int(time.time() - sandboxes[sandbox_id]["start_time"])
107
+ return f"Running for {elapsed} seconds"
108
 
109
  # -------------------------
110
  # Gradio UI
111
  # -------------------------
112
  with gr.Blocks() as demo:
113
+ gr.Markdown("# 🛡 Bare-Metal Sandbox")
114
 
115
+ code_input = gr.Textbox(label="Shell Script / Commands", lines=15, placeholder="#!/bin/bash\nls -la")
 
116
  launch_btn = gr.Button("Launch Sandbox")
117
  sandbox_id_output = gr.Textbox(label="Sandbox ID")
118
 
 
125
  status_btn = gr.Button("Check Status")
126
  status_output = gr.Textbox(label="Sandbox Status")
127
 
128
+ sandbox_state = gr.State(value=None)
129
 
130
  launch_btn.click(
131
  launch_sandbox,
132
+ inputs=code_input,
133
+ outputs=[sandbox_id_output, sandbox_state]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  )
135
+ logs_btn.click(fetch_logs, inputs=sandbox_state, outputs=logs_output)
136
+ kill_btn.click(kill_sandbox, inputs=sandbox_state, outputs=kill_output)
137
+ status_btn.click(status_sandbox, inputs=sandbox_state, outputs=status_output)
138
 
139
  demo.launch()