nakas's picture
Update app.py
018aa15 verified
raw
history blame
6.05 kB
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("<div style='text-align:center; margin-top:20px;'>App will appear here</div>")
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"""
<div style="border:1px solid #ddd; border-radius:5px; height:500px; margin-top:10px;">
<iframe src="http://localhost:7861" width="100%" height="100%" frameborder="0"></iframe>
</div>
"""
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", "<div style='text-align:center; margin-top:20px;'>App stopped</div>", 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)