Spaces:
Sleeping
Sleeping
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) |