-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexecutor.py
More file actions
66 lines (54 loc) · 1.58 KB
/
executor.py
File metadata and controls
66 lines (54 loc) · 1.58 KB
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
ALLOWED_MODULES = {
"pandas",
"matplotlib",
"matplotlib.pyplot"
}
FORBIDDEN_KEYWORDS = [
"import os",
"import sys",
"subprocess",
"socket",
"eval(",
"exec(",
]
def safe_import(name, globals=None, locals=None, fromlist=(), level=0):
if name in ALLOWED_MODULES:
return __import__(name, globals, locals, fromlist, level)
raise ImportError(f"Import not allowed: {name}")
def extract_python_code(llm_output: str) -> str:
if "```" not in llm_output:
return llm_output.strip()
parts = llm_output.split("```")
for part in parts:
if "import pandas" in part:
return part.replace("python", "").strip()
raise ValueError("No executable Python code found.")
def validate_code(code: str):
for keyword in FORBIDDEN_KEYWORDS:
if keyword in code:
raise ValueError(f"Forbidden operation detected: {keyword}")
def execute_code(code: str):
clean_code = extract_python_code(code)
validate_code(clean_code)
safe_globals = {
"__builtins__": {
"print": print,
"range": range,
"len": len,
"str": str,
"int": int,
"float": float,
"list": list,
"dict": dict,
"set": set,
"__import__": safe_import
}
}
safe_locals = {}
print("===== EXECUTING CLEAN CODE =====")
print(clean_code)
print("================================")
exec(clean_code, safe_globals, safe_locals)
return {
"result_df": safe_locals.get("result_df", None)
}