nakas commited on
Commit
8be8236
·
verified ·
1 Parent(s): da5bcdc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +142 -234
app.py CHANGED
@@ -5,204 +5,109 @@ import tempfile
5
  import importlib.util
6
  import sys
7
  import os
8
- import ast
9
  import traceback
10
- from types import MethodType
11
 
12
- # Check Gradio version
13
  GRADIO_VERSION = gr.__version__
14
- print(f"Gradio version: {GRADIO_VERSION}")
15
 
16
- # Patch Gradio Button class if needed
17
- if not hasattr(gr.Button, 'click'):
18
- # For Gradio 4.x, we need to add a click method
19
- def patched_click(self, fn, inputs=None, outputs=None):
20
- """Patched click method for Gradio 4.x buttons"""
21
- if inputs is None:
22
- inputs = []
23
- if outputs is None:
24
- outputs = []
25
-
26
- # In Gradio 4.x, this would be the event listener pattern
27
- return self.click(fn=fn, inputs=inputs, outputs=outputs)
28
-
29
- # Try to add the method, might not work but worth a try
30
- try:
31
- gr.Button.click = patched_click
32
- print("Added click method to Button class")
33
- except Exception as e:
34
- print(f"Failed to patch Button class: {e}")
35
-
36
- # Function to generate working code for the current Gradio version
37
- def generate_compatible_code(prompt):
38
- """Generate code that's guaranteed to work with this Gradio version"""
39
- if "hello world" in prompt.lower():
40
- return """
41
  import gradio as gr
42
 
43
- # Creating a simple hello world app that works in all Gradio versions
44
- def say_hello():
45
  return "Hello, World!"
46
 
47
- # Create the Gradio interface
48
  demo = gr.Interface(
49
- fn=say_hello,
50
- inputs=[],
51
- outputs=gr.Textbox(label="Output"),
52
- title="Hello World App"
53
  )
54
  """
55
- elif "calculator" in prompt.lower():
56
- return """
57
  import gradio as gr
58
- import numpy as np
59
 
60
- # Create a simple calculator
61
- def calculate(num1, num2, operation):
62
- if operation == "Add":
63
- return num1 + num2
64
- elif operation == "Subtract":
65
- return num1 - num2
66
- elif operation == "Multiply":
67
- return num1 * num2
68
- elif operation == "Divide":
69
- if num2 == 0:
70
- return "Error: Division by zero"
71
- return num1 / num2
72
  else:
73
- return "Please select an operation"
74
 
75
- # Create the Gradio interface - works in all versions
76
  demo = gr.Interface(
77
  fn=calculate,
78
  inputs=[
79
  gr.Number(label="First Number"),
80
  gr.Number(label="Second Number"),
81
- gr.Dropdown(["Add", "Subtract", "Multiply", "Divide"], label="Operation")
82
  ],
83
- outputs=gr.Number(label="Result"),
84
- title="Simple Calculator"
85
  )
86
  """
87
- elif "image" in prompt.lower() or "filter" in prompt.lower():
88
- return """
89
- import gradio as gr
90
- import numpy as np
91
- from PIL import Image, ImageEnhance
92
 
93
- # Create an image brightness adjuster
94
- def adjust_brightness(image, brightness_factor):
95
- if image is None:
96
- return None
97
-
98
- # Convert to PIL Image
99
- pil_image = Image.fromarray(image)
100
-
101
- # Adjust brightness
102
- enhancer = ImageEnhance.Brightness(pil_image)
103
- brightened = enhancer.enhance(brightness_factor)
104
-
105
- # Return as numpy array
106
- return np.array(brightened)
107
-
108
- # Create the Gradio interface - works in all versions
109
- demo = gr.Interface(
110
- fn=adjust_brightness,
111
- inputs=[
112
- gr.Image(label="Input Image"),
113
- gr.Slider(0.1, 3.0, 1.0, label="Brightness Factor")
114
- ],
115
- outputs=gr.Image(label="Adjusted Image"),
116
- title="Image Brightness Adjuster"
117
- )
118
- """
119
- elif "text" in prompt.lower() or "sentiment" in prompt.lower():
120
- return """
121
  import gradio as gr
122
- import random
123
 
124
- # Simple sentiment analyzer (mock)
125
- def analyze_sentiment(text):
126
  if not text:
127
  return "Please enter some text"
128
 
129
- # Calculate length and random sentiment for demo
130
- text_length = len(text)
131
- sentiment = random.choice(["Positive", "Neutral", "Negative"])
132
 
133
- return f"Length: {text_length} characters | Sentiment: {sentiment}"
134
 
135
- # Create the Gradio interface - works in all versions
136
  demo = gr.Interface(
137
- fn=analyze_sentiment,
138
- inputs=gr.Textbox(lines=5, label="Enter text here"),
139
- outputs=gr.Textbox(label="Analysis Result"),
140
- title="Text Analyzer"
141
- )
142
- """
143
- else:
144
- return """
145
- import gradio as gr
146
-
147
- # A general purpose demo that works in all Gradio versions
148
- def process_input(text_input):
149
- if not text_input:
150
- return "Please enter some input"
151
-
152
- # Process the input
153
- word_count = len(text_input.split())
154
- char_count = len(text_input)
155
-
156
- return f"Word count: {word_count} | Character count: {char_count}"
157
-
158
- # Create the Gradio interface - works in all versions
159
- demo = gr.Interface(
160
- fn=process_input,
161
- inputs=gr.Textbox(lines=3, label="Input"),
162
- outputs=gr.Textbox(label="Output"),
163
- title="Text Processor"
164
  )
165
  """
166
 
167
  def call_openai_api(api_key, prompt):
168
- """Direct API call to OpenAI"""
169
  headers = {
170
  "Content-Type": "application/json",
171
  "Authorization": f"Bearer {api_key}"
172
  }
173
 
174
- # Create a system prompt specifically for gr.Interface() style apps
175
- system_prompt = f"""You are an expert Gradio developer.
176
  Create a standalone Gradio application based on the user's prompt.
177
  Your response should ONLY include Python code without any explanation.
178
 
179
- IMPORTANT: You MUST use gr.Interface() instead of gr.Blocks() for compatibility.
180
- DO NOT use Button.click() or any other component events.
 
 
 
 
 
 
181
 
182
- Here's a template to follow:
183
  ```python
184
  import gradio as gr
185
 
186
- def my_function(input1, input2):
187
- # Process inputs
188
- result = input1 + input2 # Example operation
189
- return result
190
 
191
- # Create the Gradio interface
192
  demo = gr.Interface(
193
  fn=my_function,
194
- inputs=[gr.Textbox(label="Input 1"), gr.Textbox(label="Input 2")],
195
- outputs=gr.Textbox(label="Output"),
196
- title="My App"
197
  )
198
  ```
199
 
200
  The code must:
201
- 1. Import necessary libraries
202
- 2. Define functions that handle the app logic
203
- 3. Create a gr.Interface named 'demo'
204
  4. NOT include a launch command or if __name__ == "__main__" block
205
- 5. Avoid using component events or callbacks
206
  """
207
 
208
  data = {
@@ -215,17 +120,20 @@ The code must:
215
  "max_tokens": 4000
216
  }
217
 
218
- response = requests.post(
219
- "https://api.openai.com/v1/chat/completions",
220
- headers=headers,
221
- json=data
222
- )
223
-
224
- if response.status_code != 200:
225
- return None, f"API Error: {response.status_code} - {response.text}"
226
-
227
- result = response.json()
228
- return result["choices"][0]["message"]["content"], None
 
 
 
229
 
230
  def extract_code_blocks(text):
231
  """Extract code blocks from markdown"""
@@ -233,7 +141,7 @@ def extract_code_blocks(text):
233
  matches = re.findall(pattern, text)
234
 
235
  if not matches and text.strip():
236
- if re.search(r'import\s+\w+|def\s+\w+\(|class\s+\w+:|if\s+__name__\s*==\s*[\'"]__main__[\'"]:', text):
237
  return [text.strip()]
238
 
239
  return [match.strip() for match in matches]
@@ -268,109 +176,109 @@ def load_generated_app(code):
268
  except:
269
  pass
270
 
271
- # Create the main UI
272
- with gr.Blocks(title="AI Gradio App Generator") as demo:
273
- gr.Markdown(f"# 🤖 AI Gradio App Generator (v{GRADIO_VERSION})")
 
 
 
 
 
 
 
 
 
 
 
274
  gr.Markdown("Describe the Gradio app you want, and I'll generate it for you.")
275
 
276
- with gr.Row():
277
- with gr.Column():
278
- api_key = gr.Textbox(
279
- label="OpenAI API Key",
280
- placeholder="sk-...",
281
- type="password",
282
- info="Your key is used only for this session"
283
- )
284
-
285
- prompt = gr.Textbox(
286
- label="App Description",
287
- placeholder="Describe the Gradio app you want to create...",
288
- lines=5
289
- )
290
-
291
- with gr.Row():
292
- submit_btn = gr.Button("Generate App", variant="primary")
293
- skip_api_btn = gr.Button("Try Without API", variant="secondary")
294
-
295
- with gr.Accordion("Generated Code", open=False):
296
- code_output = gr.Code(language="python", label="Generated Code")
297
-
298
- status_output = gr.Markdown("")
299
 
300
- generated_app_container = gr.Group(visible=False)
 
 
 
 
 
 
 
 
 
 
 
 
301
 
302
  def on_submit(api_key_input, prompt_text):
303
- # Validate API key format
304
- if not api_key_input or len(api_key_input) < 20 or not api_key_input.startswith("sk-"):
305
- return None, "⚠️ Please provide a valid OpenAI API key", gr.update(visible=False)
306
 
307
  try:
308
- # Generate custom app via API
309
- response, api_error = call_openai_api(api_key_input, prompt_text)
310
- if api_error:
311
- return None, f"⚠️ {api_error}", gr.update(visible=False)
 
 
 
 
 
 
 
312
 
313
- # Extract code blocks
314
  code_blocks = extract_code_blocks(response)
315
  if not code_blocks:
316
- return None, "⚠️ No valid code found in the response", gr.update(visible=False)
 
317
 
318
  code = code_blocks[0]
319
 
320
- # Try to load the app
321
- app, load_error = load_generated_app(code)
322
- if load_error:
323
- # If there's an error, fallback to built-in templates
324
- fallback_code = generate_compatible_code(prompt_text)
325
- app, fallback_error = load_generated_app(fallback_code)
326
-
327
- if fallback_error:
328
- return fallback_code, f"⚠️ Error loading app: {fallback_error}", gr.update(visible=False)
329
-
330
- return fallback_code, "✅ App generated from template (API generation failed)", gr.update(visible=True, value=app)
331
-
332
- # Success!
333
- return code, "✅ App generated successfully!", gr.update(visible=True, value=app)
334
-
335
- except Exception as e:
336
- error_details = traceback.format_exc()
337
 
338
- # Try fallback
339
- try:
340
- fallback_code = generate_compatible_code(prompt_text)
341
- app, fallback_error = load_generated_app(fallback_code)
342
-
343
- if fallback_error:
344
- return None, f"⚠️ Error: {str(e)}\n\nFallback also failed: {fallback_error}", gr.update(visible=False)
345
-
346
- return fallback_code, "✅ App generated from template (after error recovery)", gr.update(visible=True, value=app)
347
- except:
348
- return None, f"⚠️ Error: {str(e)}\n{error_details}", gr.update(visible=False)
349
-
350
- def on_skip_api():
351
- """Generate an app without using the API"""
352
- app_code = generate_compatible_code(prompt.value)
353
 
354
- try:
355
- app, error = load_generated_app(app_code)
356
- if error:
357
- return app_code, f"⚠️ Error loading template: {error}", gr.update(visible=False)
358
-
359
- return app_code, "✅ App generated from built-in template", gr.update(visible=True, value=app)
360
  except Exception as e:
361
- return app_code, f"⚠️ Error: {str(e)}", gr.update(visible=False)
 
 
 
 
 
 
362
 
363
  submit_btn.click(
364
  on_submit,
365
  inputs=[api_key, prompt],
366
- outputs=[code_output, status_output, generated_app_container]
367
  )
368
 
369
- skip_api_btn.click(
370
- on_skip_api,
371
- inputs=[],
372
- outputs=[code_output, status_output, generated_app_container]
373
  )
374
 
 
 
 
 
 
 
 
 
 
 
 
375
  if __name__ == "__main__":
 
376
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
5
  import importlib.util
6
  import sys
7
  import os
 
8
  import traceback
 
9
 
10
+ # Print Gradio version for debugging
11
  GRADIO_VERSION = gr.__version__
12
+ print(f"Using Gradio version: {GRADIO_VERSION}")
13
 
14
+ # Minimal hardcoded apps that should work with any Gradio version
15
+ HELLO_WORLD_APP = """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  import gradio as gr
17
 
18
+ def hello_world():
 
19
  return "Hello, World!"
20
 
 
21
  demo = gr.Interface(
22
+ fn=hello_world,
23
+ inputs=None,
24
+ outputs="text"
 
25
  )
26
  """
27
+
28
+ CALCULATOR_APP = """
29
  import gradio as gr
 
30
 
31
+ def calculate(a, b, operation):
32
+ if operation == "add":
33
+ return a + b
34
+ elif operation == "subtract":
35
+ return a - b
36
+ elif operation == "multiply":
37
+ return a * b
38
+ elif operation == "divide":
39
+ return a / b if b != 0 else "Error: Division by zero"
 
 
 
40
  else:
41
+ return "Invalid operation"
42
 
 
43
  demo = gr.Interface(
44
  fn=calculate,
45
  inputs=[
46
  gr.Number(label="First Number"),
47
  gr.Number(label="Second Number"),
48
+ gr.Radio(["add", "subtract", "multiply", "divide"], label="Operation")
49
  ],
50
+ outputs="text"
 
51
  )
52
  """
 
 
 
 
 
53
 
54
+ TEXT_ANALYZER_APP = """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  import gradio as gr
 
56
 
57
+ def analyze_text(text):
 
58
  if not text:
59
  return "Please enter some text"
60
 
61
+ num_chars = len(text)
62
+ num_words = len(text.split())
 
63
 
64
+ return f"Characters: {num_chars}, Words: {num_words}"
65
 
 
66
  demo = gr.Interface(
67
+ fn=analyze_text,
68
+ inputs="text",
69
+ outputs="text"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  )
71
  """
72
 
73
  def call_openai_api(api_key, prompt):
74
+ """Direct API call to OpenAI with minimal output requirements"""
75
  headers = {
76
  "Content-Type": "application/json",
77
  "Authorization": f"Bearer {api_key}"
78
  }
79
 
80
+ system_prompt = """You are an expert Gradio developer.
 
81
  Create a standalone Gradio application based on the user's prompt.
82
  Your response should ONLY include Python code without any explanation.
83
 
84
+ IMPORTANT: Use the MOST BASIC Gradio features ONLY.
85
+ - Use gr.Interface() instead of gr.Blocks()
86
+ - Use string literals "text" for text inputs/outputs
87
+ - Do not use any component methods like .click() or event handlers
88
+ - Do not use component properties or attributes
89
+ - Keep it extremely simple
90
+
91
+ Example of a valid app:
92
 
 
93
  ```python
94
  import gradio as gr
95
 
96
+ def my_function(text_input):
97
+ return f"You entered: {text_input}"
 
 
98
 
 
99
  demo = gr.Interface(
100
  fn=my_function,
101
+ inputs="text",
102
+ outputs="text"
 
103
  )
104
  ```
105
 
106
  The code must:
107
+ 1. Import only gradio and basic Python libraries
108
+ 2. Define simple functions
109
+ 3. Create a minimal gr.Interface named 'demo'
110
  4. NOT include a launch command or if __name__ == "__main__" block
 
111
  """
112
 
113
  data = {
 
120
  "max_tokens": 4000
121
  }
122
 
123
+ try:
124
+ response = requests.post(
125
+ "https://api.openai.com/v1/chat/completions",
126
+ headers=headers,
127
+ json=data
128
+ )
129
+
130
+ if response.status_code != 200:
131
+ return None, f"API Error: {response.status_code} - {response.text}"
132
+
133
+ result = response.json()
134
+ return result["choices"][0]["message"]["content"], None
135
+ except Exception as e:
136
+ return None, f"API Error: {str(e)}"
137
 
138
  def extract_code_blocks(text):
139
  """Extract code blocks from markdown"""
 
141
  matches = re.findall(pattern, text)
142
 
143
  if not matches and text.strip():
144
+ if re.search(r'import\s+\w+|def\s+\w+\(|class\s+\w+:', text):
145
  return [text.strip()]
146
 
147
  return [match.strip() for match in matches]
 
176
  except:
177
  pass
178
 
179
+ def get_template_app(prompt_text):
180
+ """Get appropriate template app based on prompt keywords"""
181
+ prompt_lower = prompt_text.lower()
182
+
183
+ if "hello" in prompt_lower or "world" in prompt_lower:
184
+ return HELLO_WORLD_APP
185
+ elif "calculator" in prompt_lower or "math" in prompt_lower or "calculate" in prompt_lower:
186
+ return CALCULATOR_APP
187
+ else:
188
+ return TEXT_ANALYZER_APP
189
+
190
+ # Create the main UI - using the most basic approach
191
+ with gr.Blocks() as demo:
192
+ gr.Markdown(f"# AI Gradio App Generator (v{GRADIO_VERSION})")
193
  gr.Markdown("Describe the Gradio app you want, and I'll generate it for you.")
194
 
195
+ api_key = gr.Textbox(
196
+ label="OpenAI API Key",
197
+ placeholder="sk-...",
198
+ type="password"
199
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
 
201
+ prompt = gr.Textbox(
202
+ label="App Description",
203
+ placeholder="Describe the Gradio app you want to create...",
204
+ lines=3
205
+ )
206
+
207
+ submit_btn = gr.Button("Generate App")
208
+ template_btn = gr.Button("Use Template App")
209
+
210
+ code_output = gr.Code(language="python", label="Generated Code")
211
+ status_output = gr.Textbox(label="Status")
212
+
213
+ app_container = gr.HTML(label="Generated App")
214
 
215
  def on_submit(api_key_input, prompt_text):
216
+ # Validate API key
217
+ if not api_key_input or len(api_key_input) < 20:
218
+ return None, "Please provide a valid OpenAI API key", "<p>Enter a valid API key</p>"
219
 
220
  try:
221
+ # Try to generate code via API
222
+ response, error = call_openai_api(api_key_input, prompt_text)
223
+ if error:
224
+ # Fall back to template if API fails
225
+ template_code = get_template_app(prompt_text)
226
+ app, app_error = load_generated_app(template_code)
227
+
228
+ if app_error:
229
+ return template_code, f"Template fallback also failed: {app_error}", "<p>Failed to generate app</p>"
230
+
231
+ return template_code, "Using template app (API failed)", f"<iframe src='/template' width='100%' height='500px'></iframe>"
232
 
233
+ # Extract code from response
234
  code_blocks = extract_code_blocks(response)
235
  if not code_blocks:
236
+ template_code = get_template_app(prompt_text)
237
+ return template_code, "No code found in API response, using template", f"<iframe src='/template' width='100%' height='500px'></iframe>"
238
 
239
  code = code_blocks[0]
240
 
241
+ # Try to load the generated app
242
+ app, app_error = load_generated_app(code)
243
+ if app_error:
244
+ # Fall back to template
245
+ template_code = get_template_app(prompt_text)
246
+ return template_code, f"Generated code error: {app_error}\nUsing template instead", f"<iframe src='/template' width='100%' height='500px'></iframe>"
 
 
 
 
 
 
 
 
 
 
 
247
 
248
+ return code, "App generated successfully!", f"<iframe src='/generated' width='100%' height='500px'></iframe>"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
 
 
 
 
 
 
 
250
  except Exception as e:
251
+ # Final fallback
252
+ template_code = get_template_app(prompt_text)
253
+ return template_code, f"Error: {str(e)}\nUsing template instead", f"<iframe src='/template' width='100%' height='500px'></iframe>"
254
+
255
+ def on_template(prompt_text):
256
+ template_code = get_template_app(prompt_text)
257
+ return template_code, "Using built-in template app", f"<iframe src='/template' width='100%' height='500px'></iframe>"
258
 
259
  submit_btn.click(
260
  on_submit,
261
  inputs=[api_key, prompt],
262
+ outputs=[code_output, status_output, app_container]
263
  )
264
 
265
+ template_btn.click(
266
+ on_template,
267
+ inputs=[prompt],
268
+ outputs=[code_output, status_output, app_container]
269
  )
270
 
271
+ # Hello world demo that should work with any Gradio version
272
+ def hello_world():
273
+ return "Hello, World!"
274
+
275
+ basic_demo = gr.Interface(
276
+ fn=hello_world,
277
+ inputs=None,
278
+ outputs="text",
279
+ title="Hello World App"
280
+ )
281
+
282
  if __name__ == "__main__":
283
+ # Use the simplest launch method
284
  demo.launch(server_name="0.0.0.0", server_port=7860)