peterpeter8585 commited on
Commit
c609b26
Β·
verified Β·
1 Parent(s): 8617d37

Upload 2 files

Browse files
Files changed (2) hide show
  1. app/init.py +0 -0
  2. app/main.py +83 -0
app/init.py ADDED
File without changes
app/main.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import os
3
+ import sys
4
+ import tempfile
5
+ from typing import List
6
+
7
+ from fastapi import FastAPI, HTTPException
8
+ from pydantic import BaseModel
9
+
10
+ app = FastAPI(title="Unlimited Runner API", version="0.1.0")
11
+
12
+ # μ™„ν™”λœ μ œν•œ
13
+ MAX_STDOUT_BYTES = 2_000_000 # 2MB
14
+ EXEC_TIMEOUT = 120 # 120s
15
+ PIP_TIMEOUT = 600 # 10m
16
+
17
+ class RunPythonBody(BaseModel):
18
+ code: str
19
+
20
+ class PipBody(BaseModel):
21
+ packages: List[str]
22
+
23
+ @app.get("/health")
24
+ async def health():
25
+ return {"ok": True}
26
+
27
+ @app.post("/run-python")
28
+ async def run_python(body: RunPythonBody):
29
+ # μ½”λ“œ 파일둜 μ €μž₯ ν›„ μ‹€ν–‰
30
+ with tempfile.TemporaryDirectory() as td:
31
+ code_path = os.path.join(td, "snippet.py")
32
+ with open(code_path, "w", encoding="utf-8") as f:
33
+ f.write(body.code)
34
+
35
+ try:
36
+ proc = await asyncio.create_subprocess_exec(
37
+ sys.executable, code_path,
38
+ stdout=asyncio.subprocess.PIPE,
39
+ stderr=asyncio.subprocess.PIPE,
40
+ )
41
+ try:
42
+ stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=EXEC_TIMEOUT)
43
+ except asyncio.TimeoutError:
44
+ proc.kill()
45
+ raise HTTPException(status_code=408, detail="Execution timed out")
46
+
47
+ return {
48
+ "returncode": proc.returncode,
49
+ "stdout": stdout[:MAX_STDOUT_BYTES].decode("utf-8", errors="replace"),
50
+ "stderr": stderr[:MAX_STDOUT_BYTES].decode("utf-8", errors="replace"),
51
+ }
52
+ except Exception as e:
53
+ raise HTTPException(status_code=500, detail=str(e))
54
+
55
+ @app.post("/pip")
56
+ async def pip_install(body: PipBody):
57
+ pkgs = [p.strip() for p in body.packages if p.strip()]
58
+ if not pkgs:
59
+ raise HTTPException(status_code=400, detail="No packages provided")
60
+
61
+ try:
62
+ proc = await asyncio.create_subprocess_exec(
63
+ sys.executable, "-m", "pip", "install", "--no-input", *pkgs,
64
+ stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE,
65
+ )
66
+ try:
67
+ stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=PIP_TIMEOUT)
68
+ except asyncio.TimeoutError:
69
+ proc.kill()
70
+ raise HTTPException(status_code=408, detail="pip install timed out")
71
+
72
+ return {
73
+ "returncode": proc.returncode,
74
+ "stdout": stdout[:MAX_STDOUT_BYTES].decode("utf-8", errors="replace"),
75
+ "stderr": stderr[:MAX_STDOUT_BYTES].decode("utf-8", errors="replace"),
76
+ }
77
+ except Exception as e:
78
+ raise HTTPException(status_code=500, detail=str(e))
79
+
80
+ if __name__ == "__main__":
81
+ import uvicorn
82
+ port = int(os.environ.get("PORT", "7860"))
83
+ uvicorn.run("app.main:app", host="0.0.0.0", port=port, workers=1)