Spaces:
Sleeping
Sleeping
File size: 7,643 Bytes
fc0b4cb 7928d62 fc0b4cb 7928d62 fc0b4cb 7928d62 fc0b4cb 7928d62 fc0b4cb 7928d62 fc0b4cb 7928d62 fc0b4cb 7928d62 fc0b4cb 7928d62 fc0b4cb 7928d62 fc0b4cb 7928d62 fc0b4cb 46aaf2f fc0b4cb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
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, 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")
# For development purposes, use a placeholder key if not provided
# This will still fail when making actual API calls, but prevents immediate startup failure
if not openai.api_key:
print("WARNING: OPENAI_API_KEY environment variable is not set. Using placeholder for startup.")
print("You will need to add your API key in the Hugging Face Space settings as a secret.")
openai.api_key = "placeholder_key_replace_in_hf_settings"
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) |