import gradio as gr import os import tempfile import requests import subprocess import re import time import sys # Global variables to track resources app_process = None temp_file_path = None def cleanup(): """Clean up resources when the app exits""" global app_process, temp_file_path if app_process and app_process.poll() is None: print("Stopping running process...") app_process.terminate() time.sleep(1) if app_process.poll() is None: app_process.kill() if temp_file_path and os.path.exists(temp_file_path): print(f"Removing temp file: {temp_file_path}") try: os.unlink(temp_file_path) except Exception as e: print(f"Error removing temp file: {e}") # Register cleanup function to run at exit import atexit atexit.register(cleanup) def get_app_code(api_key, description): """Get app code from the OpenAI API""" prompt = f"""Create a simple Gradio app that {description}. The app should: 1. Use ONLY gr.Interface (not Blocks) 2. Be self-contained and not use any external dependencies 3. Use only Python standard library and NumPy/Pandas if needed 4. Include demo.launch(server_name="0.0.0.0", server_port=7861) at the end Provide ONLY Python code with no explanation or markdown.""" try: response = requests.post( "https://api.openai.com/v1/chat/completions", headers={ "Content-Type": "application/json", "Authorization": f"Bearer {api_key}" }, json={ "model": "gpt-4o", "messages": [ {"role": "system", "content": "You are a Gradio expert. Provide only Python code without explanations."}, {"role": "user", "content": prompt} ], "temperature": 0.2 } ) if response.status_code != 200: return None, f"API Error: {response.status_code}" content = response.json()["choices"][0]["message"]["content"] # Extract code blocks if present code_pattern = r'```python\s*([\s\S]*?)```' code_matches = re.findall(code_pattern, content) if code_matches: return code_matches[0], None # If no code blocks found, use the whole content return content, None except Exception as e: return None, f"Error: {str(e)}" def run_gradio_app(code): """Save the code to a temp file and run it as a subprocess""" global app_process, temp_file_path # Stop any existing process if app_process and app_process.poll() is None: app_process.terminate() time.sleep(1) if app_process.poll() is None: app_process.kill() # Remove any existing temp file if temp_file_path and os.path.exists(temp_file_path): try: os.unlink(temp_file_path) except: pass # Create a new temp file fd, temp_file_path = tempfile.mkstemp(suffix='.py') os.close(fd) # Write code to file with open(temp_file_path, 'w') as f: f.write(code) # Run the app as a subprocess app_process = subprocess.Popen([sys.executable, temp_file_path]) # Wait a moment for the app to start time.sleep(3) # Check if process is still running if app_process.poll() is not None: return False, f"App failed to start (exit code: {app_process.returncode})" return True, None # Create a very simple Gradio interface with gr.Blocks() as demo: gr.Markdown("# 🤖 Simple Gradio App Generator") api_key = gr.Textbox(label="OpenAI API Key", placeholder="sk-...", type="password") description = gr.Textbox(label="Describe the app you want", lines=3) with gr.Row(): generate_btn = gr.Button("Generate & Run App") stop_btn = gr.Button("Stop Running App", visible=False) code_display = gr.Code(label="Generated Code", language="python") status = gr.Markdown("") # Frame to display the running app app_display = gr.HTML("
App will appear here
") def generate_and_run(key, desc): if not key or len(key) < 20: return None, "Please enter a valid API key", gr.update(visible=False), gr.update(visible=False) # Get code from API code, error = get_app_code(key, desc) if error: return None, f"Error: {error}", gr.update(visible=False), gr.update(visible=False) # Run the app success, run_error = run_gradio_app(code) if not success: return code, f"Error running app: {run_error}", gr.update(visible=False), gr.update(visible=False) # Create iframe to show the app iframe = f"""
""" return code, "✅ App is running! View it below:", iframe, gr.update(visible=True) def stop_app(): global app_process if app_process and app_process.poll() is None: app_process.terminate() time.sleep(1) if app_process.poll() is None: app_process.kill() return "App stopped", "
App stopped
", gr.update(visible=False) generate_btn.click( generate_and_run, inputs=[api_key, description], outputs=[code_display, status, app_display, stop_btn] ) stop_btn.click( stop_app, inputs=[], outputs=[status, app_display, stop_btn] ) if __name__ == "__main__": demo.launch(server_name="0.0.0.0", server_port=7860)