theguywhosucks commited on
Commit
4ee1871
·
verified ·
1 Parent(s): ee157b2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +74 -52
app.py CHANGED
@@ -5,34 +5,22 @@ import resource
5
  import multiprocessing
6
  import signal
7
  import time
8
- from fastapi import FastAPI, HTTPException
9
- from fastapi.middleware.cors import CORSMiddleware
10
- import uvicorn
11
-
12
- # --- FastAPI app ---
13
- app = FastAPI()
14
-
15
- # Allow CORS for frontend testing (optional)
16
- app.add_middleware(
17
- CORSMiddleware,
18
- allow_origins=["*"],
19
- allow_credentials=True,
20
- allow_methods=["*"],
21
- allow_headers=["*"],
22
- )
23
 
24
  # Store running sandboxes
25
  sandboxes = {}
26
 
27
- # --- Sandbox worker ---
28
- def sandbox_worker(sandbox_id: str, code: str):
 
 
29
  user_dir = f"/tmp/sandbox_{sandbox_id}"
30
  os.makedirs(user_dir, exist_ok=True)
31
  os.chdir(user_dir)
32
 
33
  # Resource limits
34
  resource.setrlimit(resource.RLIMIT_AS, (4 * 1024**3, 4 * 1024**3)) # 4GB RAM
35
- resource.setrlimit(resource.RLIMIT_CPU, (7200, 7200)) # 2h CPU time
36
 
37
  # Save user code
38
  code_file = os.path.join(user_dir, "user_code.py")
@@ -45,7 +33,7 @@ def sandbox_worker(sandbox_id: str, code: str):
45
  ["python3", code_file],
46
  capture_output=True,
47
  text=True,
48
- timeout=7200 # 2h wall clock
49
  )
50
  # Save logs
51
  with open(os.path.join(user_dir, "stdout.log"), "w") as f:
@@ -56,56 +44,90 @@ def sandbox_worker(sandbox_id: str, code: str):
56
  with open(os.path.join(user_dir, "stderr.log"), "w") as f:
57
  f.write("Execution timed out (2h limit reached).")
58
 
59
-
60
- # --- API endpoints ---
61
- @app.post("/launch")
62
- def launch_sandbox(code: str):
63
  sandbox_id = str(uuid.uuid4())[:8]
64
-
65
- p = multiprocessing.Process(target=sandbox_worker, args=(sandbox_id, code))
66
  p.start()
67
-
68
  sandboxes[sandbox_id] = {"pid": p.pid, "start_time": time.time()}
69
- return {"sandbox_id": sandbox_id}
70
-
71
 
72
- @app.get("/logs/{sandbox_id}")
73
- def get_logs(sandbox_id: str):
74
  user_dir = f"/tmp/sandbox_{sandbox_id}"
75
  if not os.path.exists(user_dir):
76
- raise HTTPException(status_code=404, detail="Sandbox not found")
77
-
78
  stdout_file = os.path.join(user_dir, "stdout.log")
79
  stderr_file = os.path.join(user_dir, "stderr.log")
80
-
81
  stdout = open(stdout_file).read() if os.path.exists(stdout_file) else ""
82
  stderr = open(stderr_file).read() if os.path.exists(stderr_file) else ""
 
83
 
84
- return {"stdout": stdout, "stderr": stderr}
85
-
86
-
87
- @app.post("/kill/{sandbox_id}")
88
- def kill_sandbox(sandbox_id: str):
89
  if sandbox_id not in sandboxes:
90
- raise HTTPException(status_code=404, detail="Sandbox not found")
91
-
92
  pid = sandboxes[sandbox_id]["pid"]
93
  try:
94
  os.kill(pid, signal.SIGKILL)
95
  del sandboxes[sandbox_id]
96
- return {"status": "killed"}
97
  except Exception as e:
98
- raise HTTPException(status_code=500, detail=str(e))
99
 
100
-
101
- @app.get("/status/{sandbox_id}")
102
- def status(sandbox_id: str):
103
  if sandbox_id not in sandboxes:
104
- return {"status": "not found"}
105
  elapsed = time.time() - sandboxes[sandbox_id]["start_time"]
106
- return {"status": "running", "elapsed_sec": elapsed}
107
-
108
-
109
- # --- Main entrypoint ---
110
- if __name__ == "__main__":
111
- uvicorn.run("app:app", host="0.0.0.0", port=8000, reload=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  import multiprocessing
6
  import signal
7
  import time
8
+ import gradio as gr
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
  # Store running sandboxes
11
  sandboxes = {}
12
 
13
+ # -------------------------
14
+ # Sandbox worker function
15
+ # -------------------------
16
+ def sandbox_worker(code: str, sandbox_id: str):
17
  user_dir = f"/tmp/sandbox_{sandbox_id}"
18
  os.makedirs(user_dir, exist_ok=True)
19
  os.chdir(user_dir)
20
 
21
  # Resource limits
22
  resource.setrlimit(resource.RLIMIT_AS, (4 * 1024**3, 4 * 1024**3)) # 4GB RAM
23
+ resource.setrlimit(resource.RLIMIT_CPU, (7200, 7200)) # 2h CPU
24
 
25
  # Save user code
26
  code_file = os.path.join(user_dir, "user_code.py")
 
33
  ["python3", code_file],
34
  capture_output=True,
35
  text=True,
36
+ timeout=7200 # 2h wall-clock
37
  )
38
  # Save logs
39
  with open(os.path.join(user_dir, "stdout.log"), "w") as f:
 
44
  with open(os.path.join(user_dir, "stderr.log"), "w") as f:
45
  f.write("Execution timed out (2h limit reached).")
46
 
47
+ # -------------------------
48
+ # Gradio interface functions
49
+ # -------------------------
50
+ def launch_sandbox(code):
51
  sandbox_id = str(uuid.uuid4())[:8]
52
+ p = multiprocessing.Process(target=sandbox_worker, args=(code, sandbox_id))
 
53
  p.start()
 
54
  sandboxes[sandbox_id] = {"pid": p.pid, "start_time": time.time()}
55
+ return f"Sandbox launched! ID: {sandbox_id}", sandbox_id
 
56
 
57
+ def fetch_logs(sandbox_id):
 
58
  user_dir = f"/tmp/sandbox_{sandbox_id}"
59
  if not os.path.exists(user_dir):
60
+ return "Sandbox not found."
 
61
  stdout_file = os.path.join(user_dir, "stdout.log")
62
  stderr_file = os.path.join(user_dir, "stderr.log")
 
63
  stdout = open(stdout_file).read() if os.path.exists(stdout_file) else ""
64
  stderr = open(stderr_file).read() if os.path.exists(stderr_file) else ""
65
+ return f"STDOUT:\n{stdout}\n\nSTDERR:\n{stderr}"
66
 
67
+ def kill_sandbox(sandbox_id):
 
 
 
 
68
  if sandbox_id not in sandboxes:
69
+ return "Sandbox not found."
 
70
  pid = sandboxes[sandbox_id]["pid"]
71
  try:
72
  os.kill(pid, signal.SIGKILL)
73
  del sandboxes[sandbox_id]
74
+ return f"Sandbox {sandbox_id} killed."
75
  except Exception as e:
76
+ return f"Error killing sandbox: {e}"
77
 
78
+ def status_sandbox(sandbox_id):
 
 
79
  if sandbox_id not in sandboxes:
80
+ return "Sandbox not found."
81
  elapsed = time.time() - sandboxes[sandbox_id]["start_time"]
82
+ return f"Running for {int(elapsed)} seconds"
83
+
84
+ # -------------------------
85
+ # Gradio UI
86
+ # -------------------------
87
+ with gr.Blocks() as demo:
88
+ gr.Markdown("# Sandbox Backend")
89
+
90
+ code_input = gr.Textbox(label="Python Code", lines=15, placeholder="Write your code here...")
91
+ launch_btn = gr.Button("Launch Sandbox")
92
+ sandbox_id_output = gr.Textbox(label="Sandbox ID")
93
+
94
+ logs_btn = gr.Button("Fetch Logs")
95
+ logs_output = gr.Textbox(label="Logs", lines=10)
96
+
97
+ kill_btn = gr.Button("Kill Sandbox")
98
+ kill_output = gr.Textbox(label="Kill Status")
99
+
100
+ status_btn = gr.Button("Check Status")
101
+ status_output = gr.Textbox(label="Sandbox Status")
102
+
103
+ # Temporary storage for sandbox ID
104
+ sandbox_id_storage = gr.State(value=None)
105
+
106
+ # -------------------------
107
+ # Button actions
108
+ # -------------------------
109
+ launch_btn.click(
110
+ launch_sandbox,
111
+ inputs=code_input,
112
+ outputs=[sandbox_id_output, sandbox_id_storage]
113
+ )
114
+ logs_btn.click(
115
+ fetch_logs,
116
+ inputs=sandbox_id_storage,
117
+ outputs=logs_output
118
+ )
119
+ kill_btn.click(
120
+ kill_sandbox,
121
+ inputs=sandbox_id_storage,
122
+ outputs=kill_output
123
+ )
124
+ status_btn.click(
125
+ status_sandbox,
126
+ inputs=sandbox_id_storage,
127
+ outputs=status_output
128
+ )
129
+
130
+ # -------------------------
131
+ # Launch Gradio app
132
+ # -------------------------
133
+ demo.launch()