import gradio as gr import subprocess import tempfile import shutil import traceback class CodeExecutor: def __init__(self): self.temp_dir = tempfile.TemporaryDirectory() def _install_packages(self, packages): for package in packages: try: subprocess.check_call(["pip", "install", package], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) except subprocess.CalledProcessError as e: raise Exception(f"Error installing package {package}: {e}") def _uninstall_packages(self, packages): for package in packages: try: subprocess.check_call(["pip", "uninstall", "-y", package], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) except subprocess.CalledProcessError as e: raise Exception(f"Error uninstalling package {package}: {e}") def _execute_code(self, code, inputs): temp_file = f"{self.temp_dir.name}/temp.py" with open(temp_file, "w") as f: f.write(code) output_file = f"{self.temp_dir.name}/output.txt" error_file = f"{self.temp_dir.name}/error.txt" with open(output_file, "w") as output, open(error_file, "w") as error: try: process = subprocess.Popen(["python", temp_file], stdin=subprocess.PIPE, stdout=output, stderr=error) if inputs: for input_value in inputs: process.stdin.write(input_value.encode()) process.stdin.write(b"\n") process.stdin.close() process.wait() except Exception as e: error.write(traceback.format_exc()) with open(output_file, "r") as output, open(error_file, "r") as error: output_text = output.read() error_text = error.read() if error_text: return f"{code}\n\nTraceback (most recent call last):\n{error_text}" return f"{code}\n\nOutput:\n{output_text}" def execute(self, code, inputs, packages): try: if not packages: packages = [] else: packages = [p.strip() for p in packages.split(",")] if packages: self._install_packages(packages) input_values = [i.strip() for i in inputs.split(",")] if inputs else [] output = self._execute_code(code, input_values) if packages: self._uninstall_packages(packages) return output except Exception as e: return f"Error: {str(e)}" finally: shutil.rmtree(self.temp_dir.name) def __del__(self): shutil.rmtree(self.temp_dir.name) def wrapper_execute(code, inputs, packages): executor = CodeExecutor() return executor.execute(code, inputs, packages) def create_interface(): with gr.Blocks() as demo: gr.Markdown("# Code Interpreter") gr.Markdown("Enter Python code and inputs to execute") code_input = gr.Textbox(label="Code", lines=20) inputs_input = gr.Textbox(label="Inputs (comma-separated)", lines=1) packages_input = gr.Textbox(label="Install Packages (comma-separated)", lines=1) output_text = gr.Text(label="Output", lines=20) run_button = gr.Button("Run") run_button.click( wrapper_execute, inputs=[code_input, inputs_input, packages_input], outputs=output_text ) return demo if __name__ == "__main__": demo = create_interface() demo.launch()