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) |