nakas commited on
Commit
018aa15
·
verified ·
1 Parent(s): 9833992

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +115 -186
app.py CHANGED
@@ -1,256 +1,185 @@
1
  import gradio as gr
2
- import requests
3
- import re
4
  import os
5
- import subprocess
6
  import tempfile
7
- import sys
8
- import json
 
9
  import time
 
10
 
11
- # Print Python version and gradio version for debugging
12
- print(f"Python version: {sys.version}")
13
- print(f"Gradio version: {gr.__version__}")
14
-
15
- # Track running processes and files
16
- running_process = None
17
- temp_file = None
18
 
19
- def call_openai_api(api_key, prompt):
20
- """Call OpenAI API to generate Gradio app code"""
21
- headers = {
22
- "Content-Type": "application/json",
23
- "Authorization": f"Bearer {api_key}"
24
- }
25
 
26
- system_prompt = """You are an expert at creating Python applications with Gradio.
27
- Create a complete, standalone Gradio application based on the user's prompt.
28
-
29
- Important guidelines:
30
- 1. Use ONLY gr.Interface (NOT gr.Blocks)
31
- 2. Always include server_name="0.0.0.0" and server_port=7861 in the launch parameters
32
- 3. Keep the app simple and focused on the user's request
33
- 4. DO NOT use any flagging callbacks or flagging_dir parameters
34
- 5. Use only standard Python libraries that come with Python
35
- 6. Try to use the simplest possible implementation
36
-
37
- Example:
38
- ```python
39
- import gradio as gr
40
- import numpy as np
41
-
42
- def process(input_value):
43
- return input_value * 2
44
 
45
- demo = gr.Interface(
46
- fn=process,
47
- inputs=gr.Number(label="Input"),
48
- outputs=gr.Number(label="Output"),
49
- title="Number Doubler"
50
- )
51
 
52
- demo.launch(server_name="0.0.0.0", server_port=7861)
53
- ```
54
- """
 
 
 
 
 
 
 
 
55
 
56
  try:
57
  response = requests.post(
58
  "https://api.openai.com/v1/chat/completions",
59
- headers=headers,
 
 
 
60
  json={
61
  "model": "gpt-4o",
62
  "messages": [
63
- {"role": "system", "content": system_prompt},
64
  {"role": "user", "content": prompt}
65
  ],
66
- "temperature": 0.2,
67
- "max_tokens": 4000
68
  }
69
  )
70
 
71
  if response.status_code != 200:
72
- return None, f"API Error: {response.status_code} - {response.text}"
73
 
74
- result = response.json()
75
- content = result["choices"][0]["message"]["content"]
76
 
77
- # Extract code from the response
78
  code_pattern = r'```python\s*([\s\S]*?)```'
79
- code_match = re.search(code_pattern, content)
 
 
 
80
 
81
- if code_match:
82
- return code_match.group(1), None
83
- else:
84
- # If no code block found, use the entire content
85
- return content, None
86
  except Exception as e:
87
- return None, f"API call failed: {str(e)}"
88
 
89
- def run_app(code):
90
- """Run the Gradio app in a subprocess"""
91
- global running_process, temp_file
92
 
93
- # Stop any previously running process
94
- if running_process and running_process.poll() is None:
95
- running_process.terminate()
96
  time.sleep(1)
97
- if running_process.poll() is None:
98
- running_process.kill()
99
 
100
- # Clean up previous temp file
101
- if temp_file and os.path.exists(temp_file):
102
  try:
103
- os.unlink(temp_file)
104
  except:
105
  pass
106
 
107
- # Create a temporary file for the app
108
- fd, temp_file = tempfile.mkstemp(suffix='.py')
109
  os.close(fd)
110
 
111
- # Make sure launch parameters are correct
112
- if "server_name" not in code or "server_port" not in code:
113
- code += "\n\ndemo.launch(server_name='0.0.0.0', server_port=7861)\n"
114
 
115
- # Remove any flagging parameters
116
- code = code.replace("flagging_callback", "#flagging_callback")
117
- code = code.replace("flagging_dir", "#flagging_dir")
118
 
119
- # Write the code to the file
120
- with open(temp_file, 'w') as f:
121
- f.write(code)
122
 
123
- # Run the app
124
- try:
125
- running_process = subprocess.Popen(
126
- [sys.executable, temp_file],
127
- stdout=subprocess.PIPE,
128
- stderr=subprocess.PIPE
129
- )
130
-
131
- # Wait for the app to start
132
- time.sleep(3)
133
-
134
- # Check if the process is still running
135
- if running_process.poll() is not None:
136
- stdout, stderr = running_process.communicate()
137
- return False, f"App failed to start:\n{stderr.decode('utf-8')}"
138
-
139
- return True, None
140
- except Exception as e:
141
- return False, f"Error starting app: {str(e)}"
142
-
143
- # Create a minimal Gradio interface
144
- with gr.Blocks(title="Simple Gradio App Generator") as demo:
145
- gr.Markdown("# 🤖 Gradio App Generator")
146
- gr.Markdown("Enter a description of the app you want to create.")
147
 
148
- api_key = gr.Textbox(
149
- label="OpenAI API Key",
150
- placeholder="sk-...",
151
- type="password"
152
- )
153
 
154
- prompt = gr.Textbox(
155
- label="App Description",
156
- placeholder="Describe the Gradio app you want to create...",
157
- lines=3
158
- )
159
 
160
  with gr.Row():
161
- generate_btn = gr.Button("Generate & Run App", variant="primary")
162
- stop_btn = gr.Button("Stop App", variant="stop", visible=False)
163
 
164
- code_output = gr.Code(
165
- language="python",
166
- label="Generated Code",
167
- lines=10
168
- )
169
 
170
- status_output = gr.Markdown("")
 
171
 
172
- app_frame = gr.HTML(
173
- "<div style='text-align:center; padding:50px;'><h3>Your app will appear here</h3></div>"
174
- )
175
-
176
- def on_generate(key, description):
177
- """Generate and run the app"""
178
- if not key or len(key) < 20 or not key.startswith("sk-"):
179
- return (
180
- None,
181
- "⚠️ Please provide a valid OpenAI API key",
182
- "<div style='text-align:center; padding:50px;'><h3>Invalid API key</h3></div>",
183
- gr.update(visible=False)
184
- )
185
 
186
- # Generate the code
187
- code, error = call_openai_api(key, description)
188
- if error or not code:
189
- return (
190
- None,
191
- f"⚠️ Error: {error or 'Failed to generate code'}",
192
- "<div style='text-align:center; padding:50px;'><h3>Error generating code</h3></div>",
193
- gr.update(visible=False)
194
- )
195
 
196
  # Run the app
197
- success, run_error = run_app(code)
198
  if not success:
199
- return (
200
- code,
201
- f"⚠️ Error: {run_error}",
202
- "<div style='text-align:center; padding:50px;'><h3>Error running app</h3></div>",
203
- gr.update(visible=False)
204
- )
205
 
206
- # Create an iframe to display the app
207
- iframe_html = f"""
208
- <div style="height:600px; border:1px solid #ddd; border-radius:5px; overflow:hidden;">
209
  <iframe src="http://localhost:7861" width="100%" height="100%" frameborder="0"></iframe>
210
  </div>
211
  """
212
 
213
- return (
214
- code,
215
- "✅ App is running! View it below.",
216
- iframe_html,
217
- gr.update(visible=True)
218
- )
219
 
220
- def on_stop():
221
- """Stop the running app"""
222
- global running_process, temp_file
223
 
224
- if running_process and running_process.poll() is None:
225
- running_process.terminate()
226
  time.sleep(1)
227
- if running_process.poll() is None:
228
- running_process.kill()
229
 
230
- if temp_file and os.path.exists(temp_file):
231
- try:
232
- os.unlink(temp_file)
233
- except:
234
- pass
235
-
236
- return (
237
- "✅ App stopped",
238
- "<div style='text-align:center; padding:50px;'><h3>App stopped</h3></div>",
239
- gr.update(visible=False)
240
- )
241
 
242
  generate_btn.click(
243
- on_generate,
244
- inputs=[api_key, prompt],
245
- outputs=[code_output, status_output, app_frame, stop_btn]
246
  )
247
 
248
  stop_btn.click(
249
- on_stop,
250
  inputs=[],
251
- outputs=[status_output, app_frame, stop_btn]
252
  )
253
 
254
  if __name__ == "__main__":
255
- # Launch with minimal parameters
256
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
1
  import gradio as gr
 
 
2
  import os
 
3
  import tempfile
4
+ import requests
5
+ import subprocess
6
+ import re
7
  import time
8
+ import sys
9
 
10
+ # Global variables to track resources
11
+ app_process = None
12
+ temp_file_path = None
 
 
 
 
13
 
14
+ def cleanup():
15
+ """Clean up resources when the app exits"""
16
+ global app_process, temp_file_path
 
 
 
17
 
18
+ if app_process and app_process.poll() is None:
19
+ print("Stopping running process...")
20
+ app_process.terminate()
21
+ time.sleep(1)
22
+ if app_process.poll() is None:
23
+ app_process.kill()
24
+
25
+ if temp_file_path and os.path.exists(temp_file_path):
26
+ print(f"Removing temp file: {temp_file_path}")
27
+ try:
28
+ os.unlink(temp_file_path)
29
+ except Exception as e:
30
+ print(f"Error removing temp file: {e}")
 
 
 
 
 
31
 
32
+ # Register cleanup function to run at exit
33
+ import atexit
34
+ atexit.register(cleanup)
 
 
 
35
 
36
+ def get_app_code(api_key, description):
37
+ """Get app code from the OpenAI API"""
38
+ prompt = f"""Create a simple Gradio app that {description}.
39
+
40
+ The app should:
41
+ 1. Use ONLY gr.Interface (not Blocks)
42
+ 2. Be self-contained and not use any external dependencies
43
+ 3. Use only Python standard library and NumPy/Pandas if needed
44
+ 4. Include demo.launch(server_name="0.0.0.0", server_port=7861) at the end
45
+
46
+ Provide ONLY Python code with no explanation or markdown."""
47
 
48
  try:
49
  response = requests.post(
50
  "https://api.openai.com/v1/chat/completions",
51
+ headers={
52
+ "Content-Type": "application/json",
53
+ "Authorization": f"Bearer {api_key}"
54
+ },
55
  json={
56
  "model": "gpt-4o",
57
  "messages": [
58
+ {"role": "system", "content": "You are a Gradio expert. Provide only Python code without explanations."},
59
  {"role": "user", "content": prompt}
60
  ],
61
+ "temperature": 0.2
 
62
  }
63
  )
64
 
65
  if response.status_code != 200:
66
+ return None, f"API Error: {response.status_code}"
67
 
68
+ content = response.json()["choices"][0]["message"]["content"]
 
69
 
70
+ # Extract code blocks if present
71
  code_pattern = r'```python\s*([\s\S]*?)```'
72
+ code_matches = re.findall(code_pattern, content)
73
+
74
+ if code_matches:
75
+ return code_matches[0], None
76
 
77
+ # If no code blocks found, use the whole content
78
+ return content, None
79
+
 
 
80
  except Exception as e:
81
+ return None, f"Error: {str(e)}"
82
 
83
+ def run_gradio_app(code):
84
+ """Save the code to a temp file and run it as a subprocess"""
85
+ global app_process, temp_file_path
86
 
87
+ # Stop any existing process
88
+ if app_process and app_process.poll() is None:
89
+ app_process.terminate()
90
  time.sleep(1)
91
+ if app_process.poll() is None:
92
+ app_process.kill()
93
 
94
+ # Remove any existing temp file
95
+ if temp_file_path and os.path.exists(temp_file_path):
96
  try:
97
+ os.unlink(temp_file_path)
98
  except:
99
  pass
100
 
101
+ # Create a new temp file
102
+ fd, temp_file_path = tempfile.mkstemp(suffix='.py')
103
  os.close(fd)
104
 
105
+ # Write code to file
106
+ with open(temp_file_path, 'w') as f:
107
+ f.write(code)
108
 
109
+ # Run the app as a subprocess
110
+ app_process = subprocess.Popen([sys.executable, temp_file_path])
 
111
 
112
+ # Wait a moment for the app to start
113
+ time.sleep(3)
 
114
 
115
+ # Check if process is still running
116
+ if app_process.poll() is not None:
117
+ return False, f"App failed to start (exit code: {app_process.returncode})"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
 
119
+ return True, None
120
+
121
+ # Create a very simple Gradio interface
122
+ with gr.Blocks() as demo:
123
+ gr.Markdown("# 🤖 Simple Gradio App Generator")
124
 
125
+ api_key = gr.Textbox(label="OpenAI API Key", placeholder="sk-...", type="password")
126
+ description = gr.Textbox(label="Describe the app you want", lines=3)
 
 
 
127
 
128
  with gr.Row():
129
+ generate_btn = gr.Button("Generate & Run App")
130
+ stop_btn = gr.Button("Stop Running App", visible=False)
131
 
132
+ code_display = gr.Code(label="Generated Code", language="python")
133
+ status = gr.Markdown("")
 
 
 
134
 
135
+ # Frame to display the running app
136
+ app_display = gr.HTML("<div style='text-align:center; margin-top:20px;'>App will appear here</div>")
137
 
138
+ def generate_and_run(key, desc):
139
+ if not key or len(key) < 20:
140
+ return None, "Please enter a valid API key", gr.update(visible=False), gr.update(visible=False)
 
 
 
 
 
 
 
 
 
 
141
 
142
+ # Get code from API
143
+ code, error = get_app_code(key, desc)
144
+ if error:
145
+ return None, f"Error: {error}", gr.update(visible=False), gr.update(visible=False)
 
 
 
 
 
146
 
147
  # Run the app
148
+ success, run_error = run_gradio_app(code)
149
  if not success:
150
+ return code, f"Error running app: {run_error}", gr.update(visible=False), gr.update(visible=False)
 
 
 
 
 
151
 
152
+ # Create iframe to show the app
153
+ iframe = f"""
154
+ <div style="border:1px solid #ddd; border-radius:5px; height:500px; margin-top:10px;">
155
  <iframe src="http://localhost:7861" width="100%" height="100%" frameborder="0"></iframe>
156
  </div>
157
  """
158
 
159
+ return code, "✅ App is running! View it below:", iframe, gr.update(visible=True)
 
 
 
 
 
160
 
161
+ def stop_app():
162
+ global app_process
 
163
 
164
+ if app_process and app_process.poll() is None:
165
+ app_process.terminate()
166
  time.sleep(1)
167
+ if app_process.poll() is None:
168
+ app_process.kill()
169
 
170
+ return "App stopped", "<div style='text-align:center; margin-top:20px;'>App stopped</div>", gr.update(visible=False)
 
 
 
 
 
 
 
 
 
 
171
 
172
  generate_btn.click(
173
+ generate_and_run,
174
+ inputs=[api_key, description],
175
+ outputs=[code_display, status, app_display, stop_btn]
176
  )
177
 
178
  stop_btn.click(
179
+ stop_app,
180
  inputs=[],
181
+ outputs=[status, app_display, stop_btn]
182
  )
183
 
184
  if __name__ == "__main__":
 
185
  demo.launch(server_name="0.0.0.0", server_port=7860)