ancerlop commited on
Commit
2e8c18d
·
verified ·
1 Parent(s): 5b3f6a4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +65 -60
app.py CHANGED
@@ -1,98 +1,103 @@
1
  import gradio as gr
2
- from packaging import version
3
- import subprocess, tempfile, os, uuid, resource
4
 
5
- # ---------- utilidades ----------
6
- def _detect_c_language():
7
- """
8
- Devuelve 'c' si está en la lista de lenguajes de gr.Code,
9
- o 'cpp' como fallback para versiones antiguas (<4.0).
10
- """
11
- langs = getattr(gr.Code, "languages", [])
12
- return "c" if "c" in langs else "cpp"
13
 
14
- code_lang = _detect_c_language()
15
-
16
- # --- Función principal --------------------------------------------------------
17
  def compile_and_run(code: str, stdin: str = "") -> str:
18
  """
19
- Compila el código C, lo ejecuta y devuelve la salida (stdout + stderr).
20
- Se aplican límites de tiempo y memoria para evitar abusos.
21
  """
22
- # 1. Crear carpeta temporal única
23
- tmpdir = tempfile.mkdtemp(prefix="c_exec_")
24
- c_path = os.path.join(tmpdir, "main.c")
25
  bin_path = os.path.join(tmpdir, "main")
26
 
27
- # 2. Guardar código
28
  with open(c_path, "w") as f:
29
  f.write(code)
30
 
31
- # 3. Compilar
32
  compile_proc = subprocess.run(
33
  ["gcc", c_path, "-O2", "-std=c11", "-pipe", "-o", bin_path],
34
- capture_output=True, text=True, timeout=10
 
 
35
  )
36
  if compile_proc.returncode != 0:
 
37
  return f"❌ Error de compilación:\n{compile_proc.stderr}"
38
 
39
- # 4. Establecer límites de recursos antes de ejecutar
40
  def limit_resources():
41
- resource.setrlimit(resource.RLIMIT_CPU, (2, 2)) # 2 s CPU
42
- resource.setrlimit(resource.RLIMIT_AS, (128*1024*1024, # 128 MB
43
- 128*1024*1024))
44
 
45
- # 5. Ejecutar binario generado
46
  try:
47
  run_proc = subprocess.run(
48
  [bin_path],
49
  input=stdin,
50
  text=True,
51
  capture_output=True,
52
- timeout=2, # tiempo real (wall-clock)
53
  preexec_fn=limit_resources
54
  )
55
  except subprocess.TimeoutExpired:
 
56
  return "⏰ Tiempo de ejecución excedido (2 s)."
57
 
58
- out = run_proc.stdout
59
- err = run_proc.stderr
60
- exit = run_proc.returncode
61
-
62
- response = f"⏹ Código de salida: {exit}\n"
63
- if out:
64
- response += f"\n📤 STDOUT\n{out}"
65
- if err:
66
- response += f"\n⚠️ STDERR\n{err}"
67
- return response.strip()
68
-
69
- # ---------- Compatibilidad Gradio 3.x / 4.x ----------
70
- if version.parse(gr.__version__) >= version.parse("4.0.0"):
71
- CodeInput = gr.CodeEditor # Nuevo componente
72
- code_lang = "c" # Ahora existe
73
- else:
74
- CodeInput = gr.Code # Componente antiguo
75
- code_lang = "cpp" # 'c' no está en 3.x
76
-
77
- # --- UI en Gradio -------------------------------------------------------------
 
 
 
 
 
 
 
78
  title = "Compilador C online (42 Edition)"
79
- description = """
80
- Ejecuta fragmentos de **lenguaje C** con límite de recursos.
81
- También disponible como endpoint REST (`/run/predict`).
82
- """
83
 
84
  demo = gr.Interface(
85
- fn = compile_and_run,
86
- inputs = [
87
  gr.Code(language=code_lang, label="Código C"),
88
- gr.Textbox(lines=3, placeholder="Entrada estándar (stdin)", label="Stdin (opcional)")
 
 
 
 
89
  ],
90
- outputs = gr.Textbox(label="Resultado"),
91
- title = title,
92
- description = description,
93
- examples = [
94
- [r"#include <stdio.h>\nint main(){printf(\"Hola 42!\\n\");}", ""],
95
- [r"#include <stdio.h>\nint main(){int a,b;scanf(\"%d %d\",&a,&b);printf(\"%d\\n\",a+b);}", "3 4"]
 
96
  ],
97
  )
98
 
 
1
  import gradio as gr
2
+ import subprocess, tempfile, os, resource, shutil
 
3
 
 
 
 
 
 
 
 
 
4
 
5
+ # ------------------------------------------------------------------
6
+ # 1️⃣ Función que compila y ejecuta el código C
7
+ # ------------------------------------------------------------------
8
  def compile_and_run(code: str, stdin: str = "") -> str:
9
  """
10
+ Compila el código C recibido, lo ejecuta con límites de
11
+ recursos y devuelve stdout, stderr y exit-code.
12
  """
13
+ tmpdir = tempfile.mkdtemp(prefix="c_exec_")
14
+ c_path = os.path.join(tmpdir, "main.c")
 
15
  bin_path = os.path.join(tmpdir, "main")
16
 
17
+ # Guardar el código fuente
18
  with open(c_path, "w") as f:
19
  f.write(code)
20
 
21
+ # Compilar
22
  compile_proc = subprocess.run(
23
  ["gcc", c_path, "-O2", "-std=c11", "-pipe", "-o", bin_path],
24
+ capture_output=True,
25
+ text=True,
26
+ timeout=10
27
  )
28
  if compile_proc.returncode != 0:
29
+ shutil.rmtree(tmpdir, ignore_errors=True)
30
  return f"❌ Error de compilación:\n{compile_proc.stderr}"
31
 
32
+ # Límites (CPU 2 s, RAM 128 MB)
33
  def limit_resources():
34
+ resource.setrlimit(resource.RLIMIT_CPU, (2, 2))
35
+ resource.setrlimit(resource.RLIMIT_AS, (128 * 1024 * 1024,
36
+ 128 * 1024 * 1024))
37
 
 
38
  try:
39
  run_proc = subprocess.run(
40
  [bin_path],
41
  input=stdin,
42
  text=True,
43
  capture_output=True,
44
+ timeout=2,
45
  preexec_fn=limit_resources
46
  )
47
  except subprocess.TimeoutExpired:
48
+ shutil.rmtree(tmpdir, ignore_errors=True)
49
  return "⏰ Tiempo de ejecución excedido (2 s)."
50
 
51
+ stdout, stderr = run_proc.stdout, run_proc.stderr
52
+ exit_code = run_proc.returncode
53
+
54
+ shutil.rmtree(tmpdir, ignore_errors=True)
55
+
56
+ result = f"⏹ Código de salida: {exit_code}\n"
57
+ if stdout:
58
+ result += f"\n📤 STDOUT\n{stdout}"
59
+ if stderr:
60
+ result += f"\n⚠️ STDERR\n{stderr}"
61
+ return result.strip()
62
+
63
+
64
+ # ------------------------------------------------------------------
65
+ # 2️⃣ Detección automática del lenguaje para gr.Code
66
+ # ('c' en Gradio ≥4, 'cpp' en Gradio 3)
67
+ # ------------------------------------------------------------------
68
+ def detect_c_language() -> str:
69
+ langs = getattr(gr.Code, "languages", [])
70
+ return "c" if "c" in langs else "cpp"
71
+
72
+ code_lang = detect_c_language()
73
+
74
+
75
+ # ------------------------------------------------------------------
76
+ # 3️⃣ Construcción de la interfaz
77
+ # ------------------------------------------------------------------
78
  title = "Compilador C online (42 Edition)"
79
+ description = (
80
+ "Ejecuta fragmentos de **lenguaje C** con límite de recursos.\n"
81
+ "Disponible también como endpoint REST (`/run/predict`)."
82
+ )
83
 
84
  demo = gr.Interface(
85
+ fn=compile_and_run,
86
+ inputs=[
87
  gr.Code(language=code_lang, label="Código C"),
88
+ gr.Textbox(
89
+ lines=3,
90
+ placeholder="Entrada estándar (stdin)",
91
+ label="Stdin (opcional)"
92
+ ),
93
  ],
94
+ outputs=gr.Textbox(label="Resultado"),
95
+ title=title,
96
+ description=description,
97
+ examples=[
98
+ ["#include <stdio.h>\nint main(){puts(\"Hola 42!\");}", ""],
99
+ ["#include <stdio.h>\nint main(){int a,b;scanf(\"%d %d\",&a,&b);"
100
+ "printf(\"%d\\n\",a+b);}", "3 4"],
101
  ],
102
  )
103