gabyorel commited on
Commit
8360925
·
1 Parent(s): e651e9a

Add mcp server file

Browse files
Files changed (1) hide show
  1. app.py +93 -0
app.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import ast
3
+ import modal
4
+ import io
5
+ import sys
6
+
7
+ def detect_dependencies(code_snippet: str) -> list[str]:
8
+ tree = ast.parse(code_snippet)
9
+ imports = set()
10
+ for node in ast.walk(tree):
11
+ if isinstance(node, ast.Import):
12
+ for n in node.names:
13
+ imports.add(n.name.split('.')[0])
14
+ elif isinstance(node, ast.ImportFrom):
15
+ if node.module:
16
+ imports.add(node.module.split('.')[0])
17
+ return list(imports)
18
+
19
+
20
+ def build_sandbox(requirements: list[str], app: modal.App) -> tuple[modal.Sandbox, str]:
21
+ buffer = io.StringIO()
22
+ original_stdout = sys.stdout
23
+ sys.stdout = buffer
24
+ try:
25
+ with modal.enable_output():
26
+ image = modal.Image.debian_slim(python_version='3.12').pip_install(*requirements)
27
+ sandbox = modal.Sandbox.create(app=app, image=image, timeout=60)
28
+ finally:
29
+ sys.stdout = original_stdout
30
+
31
+ logs = buffer.getvalue()
32
+ return sandbox, logs
33
+
34
+
35
+ def code_eval(code_snippet: str) -> tuple[dict, str]:
36
+ """
37
+ Run a python code snippet into a sandbox environment.
38
+
39
+ Args:
40
+ code_snippet (str): The Python code to execute.
41
+
42
+ Returns:
43
+ tuple[dict, str]:
44
+ - A dictionary containing execution results:
45
+ 'stdout', 'stderr', 'returncode', and 'error' (if any).
46
+ - A string with the image build logs (empty if no dependencies were detected).
47
+ """
48
+ try:
49
+ ast.parse(code_snippet)
50
+ except SyntaxError as e:
51
+ return {
52
+ "error": str(e),
53
+ "stdout": "",
54
+ "stderr": "",
55
+ "returncode": 1,
56
+ }, ""
57
+
58
+ app = modal.App.lookup("my-app", create_if_missing=True)
59
+ requirements = detect_dependencies(code_snippet)
60
+
61
+ if requirements:
62
+ sb, build_logs = build_sandbox(requirements, app)
63
+ else:
64
+ build_logs = ""
65
+ sb = modal.Sandbox.create(app=app, timeout=60)
66
+
67
+ with sb.open("/tmp/code.py", "w") as f:
68
+ f.write(code_snippet)
69
+
70
+ proc = sb.exec("python", "/tmp/code.py")
71
+ proc.wait()
72
+ error = proc.returncode != 0
73
+
74
+ return {
75
+ "error": "Script failed with non-zero exit code" if error else "",
76
+ "stdout": proc.stdout.read(),
77
+ "stderr": proc.stderr.read(),
78
+ "returncode": proc.returncode,
79
+ }, build_logs
80
+
81
+ app = gr.Interface(
82
+ fn=code_eval,
83
+ inputs=[gr.Code()],
84
+ outputs=[
85
+ gr.JSON(label="Execution Logs"),
86
+ gr.Textbox(label="Build Logs", interactive=False)
87
+ ],
88
+ title="Code Eval",
89
+ description="Enter a python code snippet to execute."
90
+ )
91
+
92
+ if __name__ == "__main__":
93
+ app.launch(mcp_server=True)