MargeCode / app.py
ancerlop's picture
Update app.py
2e8c18d verified
import gradio as gr
import subprocess, tempfile, os, resource, shutil
# ------------------------------------------------------------------
# 1️⃣ Función que compila y ejecuta el código C
# ------------------------------------------------------------------
def compile_and_run(code: str, stdin: str = "") -> str:
"""
Compila el código C recibido, lo ejecuta con límites de
recursos y devuelve stdout, stderr y exit-code.
"""
tmpdir = tempfile.mkdtemp(prefix="c_exec_")
c_path = os.path.join(tmpdir, "main.c")
bin_path = os.path.join(tmpdir, "main")
# Guardar el código fuente
with open(c_path, "w") as f:
f.write(code)
# Compilar
compile_proc = subprocess.run(
["gcc", c_path, "-O2", "-std=c11", "-pipe", "-o", bin_path],
capture_output=True,
text=True,
timeout=10
)
if compile_proc.returncode != 0:
shutil.rmtree(tmpdir, ignore_errors=True)
return f"❌ Error de compilación:\n{compile_proc.stderr}"
# Límites (CPU 2 s, RAM 128 MB)
def limit_resources():
resource.setrlimit(resource.RLIMIT_CPU, (2, 2))
resource.setrlimit(resource.RLIMIT_AS, (128 * 1024 * 1024,
128 * 1024 * 1024))
try:
run_proc = subprocess.run(
[bin_path],
input=stdin,
text=True,
capture_output=True,
timeout=2,
preexec_fn=limit_resources
)
except subprocess.TimeoutExpired:
shutil.rmtree(tmpdir, ignore_errors=True)
return "⏰ Tiempo de ejecución excedido (2 s)."
stdout, stderr = run_proc.stdout, run_proc.stderr
exit_code = run_proc.returncode
shutil.rmtree(tmpdir, ignore_errors=True)
result = f"⏹ Código de salida: {exit_code}\n"
if stdout:
result += f"\n📤 STDOUT\n{stdout}"
if stderr:
result += f"\n⚠️ STDERR\n{stderr}"
return result.strip()
# ------------------------------------------------------------------
# 2️⃣ Detección automática del lenguaje para gr.Code
# ('c' en Gradio ≥4, 'cpp' en Gradio 3)
# ------------------------------------------------------------------
def detect_c_language() -> str:
langs = getattr(gr.Code, "languages", [])
return "c" if "c" in langs else "cpp"
code_lang = detect_c_language()
# ------------------------------------------------------------------
# 3️⃣ Construcción de la interfaz
# ------------------------------------------------------------------
title = "Compilador C online (42 Edition)"
description = (
"Ejecuta fragmentos de **lenguaje C** con límite de recursos.\n"
"Disponible también como endpoint REST (`/run/predict`)."
)
demo = gr.Interface(
fn=compile_and_run,
inputs=[
gr.Code(language=code_lang, label="Código C"),
gr.Textbox(
lines=3,
placeholder="Entrada estándar (stdin)",
label="Stdin (opcional)"
),
],
outputs=gr.Textbox(label="Resultado"),
title=title,
description=description,
examples=[
["#include <stdio.h>\nint main(){puts(\"Hola 42!\");}", ""],
["#include <stdio.h>\nint main(){int a,b;scanf(\"%d %d\",&a,&b);"
"printf(\"%d\\n\",a+b);}", "3 4"],
],
)
if __name__ == "__main__":
demo.launch()