nakas's picture
Create app.py
7928d62 verified
raw
history blame
7.31 kB
import os
import importlib.util
import sys
import tempfile
import traceback
from pathlib import Path
import gradio as gr
import openai
from flask import Flask, render_template, request, jsonify
from dotenv import load_dotenv
from utils import sanitize_code, extract_code_blocks, validate_gradio_code
# Load environment variables
load_dotenv()
# Configure OpenAI API
openai.api_key = os.getenv("OPENAI_API_KEY")
if not openai.api_key:
raise ValueError("OPENAI_API_KEY environment variable is not set")
app = Flask(__name__)
generated_app = None
current_code = ""
def generate_gradio_app(prompt):
"""Generate Gradio app code using OpenAI API"""
try:
response = openai.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):
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.Markdown("Your generated app will appear here.")
error_output = gr.Markdown(visible=False)
def on_submit(prompt_text):
# Generate the Gradio app code
code, error = generate_gradio_app(prompt_text)
if error:
return None, f"⚠️ **Error generating code**: {error}", gr.update(visible=True), None
# Load and run the generated app
app, run_error = load_and_run_gradio_app(code)
if run_error:
return code, f"⚠️ **Error running the generated app**: {run_error}", gr.update(visible=True), None
# Create an iframe to display the app
iframe_html = f'<iframe src="/generated_app" width="100%" height="800px" frameborder="0"></iframe>'
return code, "", gr.update(visible=False), iframe_html
def on_clear():
return "", "", gr.update(visible=False), "Your generated app will appear here."
submit_btn.click(
on_submit,
inputs=[prompt],
outputs=[code_output, error_output, error_output, output]
)
clear_btn.click(
on_clear,
inputs=[],
outputs=[prompt, code_output, error_output, output]
)
return interface
# Flask routes to handle the generated app
@app.route('/generated_app')
def serve_generated_app():
"""Serve the generated Gradio app"""
if not generated_app:
return "No app has been generated yet. Please create one first."
# Create a tempfile with the current code
with tempfile.NamedTemporaryFile(suffix='.py', delete=False) as f:
f.write(current_code.encode('utf-8'))
temp_file = f.name
# Execute the code in a subprocess
# This is a simplified version - in a real app, you'd need a more robust solution
import subprocess
result = subprocess.run([sys.executable, temp_file], capture_output=True, text=True)
# Clean up
os.unlink(temp_file)
if result.returncode != 0:
return f"Error running the app: {result.stderr}"
return result.stdout
if __name__ == "__main__":
# Create the Gradio interface
demo = create_ui()
# Launch the Gradio app
demo.launch(server_name="0.0.0.0", server_port=7860)