Spaces:
Runtime error
Runtime error
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) |