Spaces:
Sleeping
Sleeping
File size: 2,951 Bytes
e1f352a 00ea332 e1f352a 00ea332 e1f352a 4addbf0 e1f352a 4addbf0 e1f352a 00ea332 e1f352a 4addbf0 00ea332 e1f352a 00ea332 e1f352a 00ea332 e1f352a 00ea332 e1f352a 00ea332 e1f352a 00ea332 e1f352a 00ea332 e1f352a 00ea332 e1f352a 00ea332 e1f352a 00ea332 e1f352a 00ea332 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# app.py
import gradio as gr
import sys, io, traceback, re, subprocess, importlib, multiprocessing, resource, signal
# ----------------------
# Helper: Install missing packages safely
# ----------------------
def _install_missing(packages):
"""Install packages if not already installed. Fail gracefully if not found."""
for pkg in packages:
try:
importlib.import_module(pkg)
except ImportError:
try:
subprocess.check_call(
[sys.executable, "-m", "pip", "install", "--disable-pip-version-check", "-q", pkg]
)
except subprocess.CalledProcessError:
# فقط هشدار میده، برنامه نمیترکه
print(f"[WARN] Package '{pkg}' not found on PyPI or failed to install.", file=sys.stderr)
# ----------------------
# Worker process
# ----------------------
def _worker(code, stdin_input, conn):
sys.stdin = io.StringIO(stdin_input)
sys.stdout = io.StringIO()
sys.stderr = io.StringIO()
# محدودیت حافظه و زمان
resource.setrlimit(resource.RLIMIT_AS, (512 * 1024 * 1024, 512 * 1024 * 1024)) # 512MB
signal.alarm(10) # 10 ثانیه تایماوت
try:
# پیدا کردن importها
imports = re.findall(r'^\s*import (\w+)|^\s*from (\w+)', code, flags=re.MULTILINE)
imports = {i[0] or i[1] for i in imports}
if imports:
_install_missing(imports)
safe_globals = {"__builtins__": __builtins__}
exec(compile(code, "<user_code>", "exec"), safe_globals, None)
out = sys.stdout.getvalue()
err = sys.stderr.getvalue()
conn.send((out, err))
except Exception:
conn.send(("", traceback.format_exc()))
finally:
conn.close()
# ----------------------
# Runner
# ----------------------
def run_code(code, stdin_input=""):
parent_conn, child_conn = multiprocessing.Pipe()
p = multiprocessing.Process(target=_worker, args=(code, stdin_input, child_conn))
p.start()
p.join(12) # یک مقدار بیشتر از تایماوت داخلی
if p.is_alive():
p.terminate()
return "", "Error: Timeout (execution took too long)"
return parent_conn.recv()
# ----------------------
# Gradio UI
# ----------------------
with gr.Blocks(title="Python Runner (Auto Install)") as demo:
gr.Markdown("### 🐍 Python Sandbox with Auto-Package Install (USE WITH CAUTION)")
code = gr.Code(label="Python code", language="python")
stdin = gr.Textbox(label="stdin", placeholder="Optional input for `input()` calls")
run_btn = gr.Button("▶ Run")
stdout = gr.Textbox(label="stdout")
stderr = gr.Textbox(label="stderr", elem_classes="stderr")
def execute(c, s):
return run_code(c, s)
run_btn.click(execute, [code, stdin], [stdout, stderr])
if __name__ == "__main__":
demo.launch()
|