Interpreter / executor.py
likhonsheikh's picture
Create executor.py
00226c3 verified
import subprocess, tempfile, shutil, traceback, importlib.util
import concurrent.futures
import os
class CodeExecutor:
def __init__(self):
self.temp_dir = tempfile.TemporaryDirectory()
self.executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)
def _install_packages(self, packages):
for package in packages:
package = package.strip()
if not package:
continue
try:
spec = importlib.util.find_spec(package)
if spec is None:
subprocess.check_call(["pip", "install", package], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=15)
except subprocess.CalledProcessError as e:
raise Exception(f"❌ Error installing package {package}: {e}")
except subprocess.TimeoutExpired:
raise Exception(f"⏰ Timed out installing package {package}")
def _execute_code(self, code, inputs):
temp_file = f"{self.temp_dir.name}/user_code.py"
output_file = f"{self.temp_dir.name}/stdout.txt"
error_file = f"{self.temp_dir.name}/stderr.txt"
with open(temp_file, "w") as f:
f.write(code)
with open(output_file, "w") as out, open(error_file, "w") as err:
try:
process = subprocess.Popen(
["python", temp_file],
stdin=subprocess.PIPE,
stdout=out,
stderr=err,
text=True
)
if inputs:
for line in inputs:
process.stdin.write(line + "\n")
process.stdin.close()
process.wait(timeout=15)
except subprocess.TimeoutExpired:
process.kill()
err.write("⏰ Execution timed out.\n")
except Exception:
err.write(traceback.format_exc())
with open(output_file, "r") as out, open(error_file, "r") as err:
output_text = out.read().strip()
error_text = err.read().strip()
if error_text:
return f"⚠️ Error:\n{error_text}"
return f"βœ… Output:\n{output_text}"
def execute(self, code, inputs, packages):
if packages:
self._install_packages(packages.split(","))
future = self.executor.submit(self._execute_code, code, inputs)
try:
return future.result(timeout=20)
except concurrent.futures.TimeoutError:
return "⏳ Code execution exceeded time limit."
except Exception as e:
return f"❌ Execution Error: {e}"
def __del__(self):
self.executor.shutdown(wait=False)
shutil.rmtree(self.temp_dir.name)