File size: 6,054 Bytes
6e19f63
 
1368c37
018aa15
 
 
ece917e
018aa15
8be8236
018aa15
 
 
da5bcdc
018aa15
 
 
6e19f63
018aa15
 
 
 
 
 
 
 
 
 
 
 
 
6e19f63
018aa15
 
 
44abb7c
018aa15
 
 
 
 
 
 
 
 
 
 
da5bcdc
8be8236
 
 
018aa15
 
 
 
9833992
 
 
018aa15
9833992
 
018aa15
9833992
8be8236
 
 
018aa15
8be8236
018aa15
1368c37
018aa15
9833992
018aa15
 
 
 
9833992
018aa15
 
 
8be8236
018aa15
6e19f63
018aa15
 
 
83a7163
018aa15
 
 
9833992
018aa15
 
e9c6962
018aa15
 
9833992
018aa15
9833992
 
 
018aa15
 
e9c6962
 
018aa15
 
 
f8ca66e
018aa15
 
f8ca66e
018aa15
 
e9c6962
018aa15
 
 
83a7163
018aa15
 
 
 
 
e9c6962
018aa15
 
e9c6962
9833992
018aa15
 
e9c6962
018aa15
 
57a2c17
018aa15
 
9e8ab62
018aa15
 
 
44abb7c
018aa15
 
 
 
9833992
 
018aa15
9833992
018aa15
9833992
018aa15
 
 
9833992
 
 
 
018aa15
8be8236
018aa15
 
e9c6962
018aa15
 
9833992
018aa15
 
1368c37
018aa15
9e8ab62
1368c37
018aa15
 
 
44abb7c
 
1368c37
018aa15
9833992
018aa15
9e8ab62
7928d62
fc0b4cb
9833992
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
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)