import os import importlib.util import sys import tempfile import traceback from pathlib import Path import gradio as gr import openai from dotenv import load_dotenv from utils import sanitize_code, extract_code_blocks, validate_gradio_code # Load environment variables (for local development) load_dotenv() # Global variables generated_app = None current_code = "" user_api_key = "" def generate_gradio_app(api_key, prompt): """Generate Gradio app code using OpenAI API""" global user_api_key # Validate API key if not api_key or len(api_key) < 20: return None, "Please provide a valid OpenAI API key" # Store API key for this session user_api_key = api_key try: # Configure client with user's API key client = openai.OpenAI(api_key=api_key) response = client.chat.completions.create( model="gpt-4o", # Using gpt-4o for best code generation messages=[ {"role": "system", "content": """You are an expert Gradio developer. Create a standalone Gradio application based on the user's prompt. Your response should ONLY include Python code without any explanation. The code must: 1. Import all necessary libraries 2. Define a complete, functional Gradio interface 3. Launch the interface with share=False and show_api=False 4. Use gr.Blocks() for complex interfaces 5. Handle errors gracefully 6. Use relative paths for any file operations 7. NOT use external APIs or services unless specifically requested 8. Be completely self-contained in a single script 9. End with a simple if __name__ == "__main__": block that launches the app """ }, {"role": "user", "content": prompt} ], temperature=0.2, max_tokens=4000 ) generated_code = response.choices[0].message.content code_blocks = extract_code_blocks(generated_code) if code_blocks: return code_blocks[0], None else: return generated_code, None except Exception as e: return None, str(e) def load_and_run_gradio_app(code): """Load and run the generated Gradio app code""" global generated_app, current_code # Check if code is safe to execute is_valid, error_msg = validate_gradio_code(code) if not is_valid: return None, error_msg # Clean up previous app if it exists if generated_app: try: generated_app.close() except: pass # Save code to a temporary file with tempfile.NamedTemporaryFile(suffix='.py', delete=False) as f: f.write(code.encode('utf-8')) temp_file = f.name try: # Import the module module_name = os.path.basename(temp_file).replace('.py', '') spec = importlib.util.spec_from_file_location(module_name, temp_file) module = importlib.util.module_from_spec(spec) sys.modules[module_name] = module spec.loader.exec_module(module) # Find the Gradio interface for attr_name in dir(module): attr = getattr(module, attr_name) if isinstance(attr, gr.Blocks) or isinstance(attr, gr.Interface): # Save a reference to the app generated_app = attr current_code = code # Return the app return attr, None return None, "No Gradio interface found in the generated code" except Exception as e: error_details = traceback.format_exc() return None, f"Error executing the generated code: {str(e)}\n{error_details}" finally: # Clean up the temporary file try: os.unlink(temp_file) except: pass def create_ui(): """Create the main Gradio interface""" with gr.Blocks(title="Dynamic Gradio App Generator") as interface: gr.Markdown("# 🤖 Dynamic Gradio App Generator") gr.Markdown("Describe the Gradio app you want to create, and the AI will generate and run it for you.") with gr.Row(): with gr.Column(scale=2): api_key = gr.Textbox( label="OpenAI API Key", placeholder="sk-...", type="password", info="Your key is used for this session only and not stored" ) prompt = gr.Textbox( label="App Description", placeholder="Describe the Gradio app you want to create...", lines=5 ) with gr.Row(): submit_btn = gr.Button("Generate & Run App", variant="primary") clear_btn = gr.Button("Clear", variant="secondary") with gr.Accordion("Generated Code", open=False): code_output = gr.Code(language="python", label="Generated Code") with gr.Column(scale=3): output = gr.HTML("