xtreme86 commited on
Commit
9ab5cea
1 Parent(s): e6b1679
Files changed (1) hide show
  1. app.py +205 -77
app.py CHANGED
@@ -1,120 +1,248 @@
1
  import gradio as gr
 
 
2
 
3
- # Function to dynamically create Gradio UI elements for preview
4
- def generate_ui_preview(components):
5
- # A function to be linked to the dynamically created interface
6
- def mock_fn(*args):
7
- return args
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
- inputs = []
10
- for component in components:
11
- label = component.get('label', 'No Label')
 
 
12
  field_type = component['type']
13
 
14
  if field_type == "Textbox":
15
  placeholder = component.get('placeholder', '')
16
- inputs.append(gr.Textbox(label=label, placeholder=placeholder))
17
  elif field_type == "Number":
18
  min_value = component.get('min_value', 0)
19
  max_value = component.get('max_value', 100)
20
- inputs.append(gr.Number(label=label, minimum=min_value, maximum=max_value))
21
  elif field_type == "Dropdown":
22
  choices = component.get('choices', ['Option 1', 'Option 2'])
23
- inputs.append(gr.Dropdown(label=label, choices=choices))
 
24
  elif field_type == "Slider":
25
  min_value = component.get('min_value', 0)
26
  max_value = component.get('max_value', 100)
27
- inputs.append(gr.Slider(label=label, minimum=min_value, maximum=max_value))
28
  elif field_type == "Checkbox":
29
- inputs.append(gr.Checkbox(label=label))
 
 
 
 
 
 
 
 
 
30
 
31
- if len(inputs) > 0:
32
- return gr.Interface(fn=mock_fn, inputs=inputs, outputs=inputs).launch(prevent_thread_lock=True)
33
- else:
34
- return "No components added yet."
35
 
36
- # Function to handle dynamic field addition
37
  def add_field(component_type, field_label, placeholder_text, min_value, max_value, choices, components):
38
  new_component = {"type": component_type, "label": field_label}
39
 
40
  if component_type == "Textbox":
41
  new_component["placeholder"] = placeholder_text
42
  elif component_type in ["Number", "Slider"]:
43
- new_component["min_value"] = min_value
44
- new_component["max_value"] = max_value
45
- elif component_type == "Dropdown":
46
- new_component["choices"] = choices.split(',')
47
-
 
 
 
 
 
 
 
48
  components.append(new_component)
49
- return components, components
50
 
51
- # Function to update the visibility of specific options based on the component type
52
  def update_visibility(component_type):
53
  return (
54
  gr.update(visible=component_type == "Textbox"),
55
  gr.update(visible=component_type in ["Slider", "Number"]),
56
- gr.update(visible=component_type == "Dropdown"),
57
  gr.update(visible=component_type in ["Slider", "Number"])
58
  )
59
 
60
- # Gradio UI for designing the interface with live preview
61
- def ui():
62
- with gr.Blocks() as demo:
63
- with gr.Column():
64
- gr.Markdown("### Gradio UI Designer")
65
- interface_name = gr.Textbox(label="Interface Name", placeholder="Enter the interface name")
66
 
67
- # Components UI
68
- component_type = gr.Dropdown(choices=["Textbox", "Number", "Dropdown", "Slider", "Checkbox"], label="Field Type")
69
- field_label = gr.Textbox(label="Field Label", placeholder="Enter field label")
70
- placeholder_text = gr.Textbox(label="Placeholder (for Textbox)", visible=False)
71
- min_value = gr.Number(label="Min Value (for Slider/Number)", value=0, visible=False)
72
- max_value = gr.Number(label="Max Value (for Slider/Number)", value=100, visible=False)
73
- choices = gr.Textbox(label="Choices (comma separated for Dropdown)", visible=False)
 
 
 
74
 
75
- # Components list to track fields
76
- components_list = gr.State([])
77
-
78
- # Add field button and component preview
79
- add_button = gr.Button("Add Field")
80
- component_preview = gr.JSON(label="Component List")
81
 
82
- # Live UI preview
83
- preview_button = gr.Button("Preview UI")
84
- ui_preview = gr.HTML(label="UI Preview will appear here")
 
 
 
85
 
86
- add_button.click(
87
- add_field,
88
- inputs=[component_type, field_label, placeholder_text, min_value, max_value, choices, components_list],
89
- outputs=[component_preview, components_list]
90
- )
91
-
92
- # Update visibility based on the field type
93
- component_type.change(
94
- update_visibility,
95
- inputs=[component_type],
96
- outputs=[placeholder_text, min_value, choices, max_value]
97
- )
98
-
99
- # Preview the dynamically generated UI
100
- preview_button.click(
101
- generate_ui_preview,
102
- inputs=[components_list],
103
- outputs=[ui_preview]
104
- )
105
-
106
- # Preview and generate code button
107
- generate_button = gr.Button("Generate Code")
108
- generated_code = gr.Code(label="Generated Code")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
 
110
- generate_button.click(
111
- lambda interface_name, components: generate_gradio_code(interface_name, components),
112
- inputs=[interface_name, components_list],
113
- outputs=generated_code
114
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
 
116
  return demo
117
 
118
  # Launch the Gradio app
119
  if __name__ == "__main__":
120
- ui().launch()
 
1
  import gradio as gr
2
+ import json
3
+ import re
4
 
5
+ # Utility functions
6
+ def sanitize_name(name):
7
+ return re.sub(r'\W|^(?=\d)', '_', name).lower()
8
+
9
+ def validate_input(component):
10
+ if component['type'] in ['Number', 'Slider']:
11
+ min_value = float(component.get('min_value', 0))
12
+ max_value = float(component.get('max_value', 100))
13
+ if min_value >= max_value:
14
+ return False, "Min value must be less than max value"
15
+ elif component['type'] in ['Dropdown', 'Radio']:
16
+ if not component.get('choices'):
17
+ return False, f"{component['type']} must have at least one choice"
18
+ return True, ""
19
+
20
+ # Core functionality
21
+ def generate_gradio_code(interface_name, components):
22
+ sanitized_name = sanitize_name(interface_name)
23
+ code = f"import gradio as gr\n\n"
24
+ code += f"def {sanitized_name}_interface(*args):\n"
25
+ code += f" # Your processing logic here\n"
26
+ code += f" results = [arg for arg in args]\n"
27
+ code += f" return results\n\n"
28
 
29
+ code += f"with gr.Blocks() as {sanitized_name}:\n"
30
+ code += f" inputs = []\n"
31
+
32
+ for i, component in enumerate(components):
33
+ label = component.get('label', f'Field {i+1}')
34
  field_type = component['type']
35
 
36
  if field_type == "Textbox":
37
  placeholder = component.get('placeholder', '')
38
+ code += f" input_{i} = gr.Textbox(label='{label}', placeholder='{placeholder}')\n"
39
  elif field_type == "Number":
40
  min_value = component.get('min_value', 0)
41
  max_value = component.get('max_value', 100)
42
+ code += f" input_{i} = gr.Number(label='{label}', value=0, minimum={min_value}, maximum={max_value})\n"
43
  elif field_type == "Dropdown":
44
  choices = component.get('choices', ['Option 1', 'Option 2'])
45
+ choices_str = json.dumps(choices)
46
+ code += f" input_{i} = gr.Dropdown(label='{label}', choices={choices_str})\n"
47
  elif field_type == "Slider":
48
  min_value = component.get('min_value', 0)
49
  max_value = component.get('max_value', 100)
50
+ code += f" input_{i} = gr.Slider(label='{label}', minimum={min_value}, maximum={max_value})\n"
51
  elif field_type == "Checkbox":
52
+ code += f" input_{i} = gr.Checkbox(label='{label}')\n"
53
+ elif field_type == "Radio":
54
+ choices = component.get('choices', ['Option 1', 'Option 2'])
55
+ choices_str = json.dumps(choices)
56
+ code += f" input_{i} = gr.Radio(label='{label}', choices={choices_str})\n"
57
+
58
+ code += f" inputs.append(input_{i})\n"
59
+
60
+ code += f" outputs = [gr.Textbox(label='Output {i+1}') for i in range(len(inputs))]\n"
61
+ code += f" gr.Interface(fn={sanitized_name}_interface, inputs=inputs, outputs=outputs).launch()\n"
62
 
63
+ return code
 
 
 
64
 
 
65
  def add_field(component_type, field_label, placeholder_text, min_value, max_value, choices, components):
66
  new_component = {"type": component_type, "label": field_label}
67
 
68
  if component_type == "Textbox":
69
  new_component["placeholder"] = placeholder_text
70
  elif component_type in ["Number", "Slider"]:
71
+ new_component["min_value"] = float(min_value) if min_value else 0
72
+ new_component["max_value"] = float(max_value) if max_value else 100
73
+ elif component_type in ["Dropdown", "Radio"]:
74
+ choices_list = [choice.strip() for choice in choices.split(',') if choice.strip()]
75
+ if not choices_list:
76
+ choices_list = ['Option 1', 'Option 2']
77
+ new_component["choices"] = choices_list
78
+
79
+ is_valid, error_message = validate_input(new_component)
80
+ if not is_valid:
81
+ return components, components, gr.update(visible=True, value=error_message)
82
+
83
  components.append(new_component)
84
+ return components, components, gr.update(visible=True, value="Field added successfully!")
85
 
 
86
  def update_visibility(component_type):
87
  return (
88
  gr.update(visible=component_type == "Textbox"),
89
  gr.update(visible=component_type in ["Slider", "Number"]),
90
+ gr.update(visible=component_type in ["Dropdown", "Radio"]),
91
  gr.update(visible=component_type in ["Slider", "Number"])
92
  )
93
 
94
+ def edit_field(index, component_type, field_label, placeholder_text, min_value, max_value, choices, components):
95
+ try:
96
+ index = int(index)
97
+ if 0 <= index < len(components):
98
+ new_component = {"type": component_type, "label": field_label}
 
99
 
100
+ if component_type == "Textbox":
101
+ new_component["placeholder"] = placeholder_text
102
+ elif component_type in ["Number", "Slider"]:
103
+ new_component["min_value"] = float(min_value) if min_value else 0
104
+ new_component["max_value"] = float(max_value) if max_value else 100
105
+ elif component_type in ["Dropdown", "Radio"]:
106
+ choices_list = [choice.strip() for choice in choices.split(',') if choice.strip()]
107
+ if not choices_list:
108
+ choices_list = ['Option 1', 'Option 2']
109
+ new_component["choices"] = choices_list
110
 
111
+ is_valid, error_message = validate_input(new_component)
112
+ if not is_valid:
113
+ return components, components, gr.update(visible=True, value=error_message)
 
 
 
114
 
115
+ components[index] = new_component
116
+ return components, components, gr.update(visible=True, value="Field updated successfully!")
117
+ else:
118
+ return components, components, gr.update(visible=True, value="Invalid field index")
119
+ except ValueError:
120
+ return components, components, gr.update(visible=True, value="Invalid index. Please enter a number.")
121
 
122
+ def delete_field(index, components):
123
+ try:
124
+ index = int(index)
125
+ if 0 <= index < len(components):
126
+ del components[index]
127
+ return components, components, gr.update(visible=True, value="Field deleted successfully!")
128
+ else:
129
+ return components, components, gr.update(visible=True, value="Invalid field index")
130
+ except ValueError:
131
+ return components, components, gr.update(visible=True, value="Invalid index. Please enter a number.")
132
+
133
+ def save_design(interface_name, components):
134
+ design = {
135
+ "interface_name": interface_name,
136
+ "components": components
137
+ }
138
+ filename = f"{sanitize_name(interface_name)}_design.json"
139
+ with open(filename, 'w') as f:
140
+ json.dump(design, f, indent=2)
141
+ return gr.update(visible=True, value=f"Design saved to {filename}")
142
+
143
+ def load_design(file):
144
+ if file is None:
145
+ return None, [], gr.update(visible=True, value="No file selected")
146
+
147
+ try:
148
+ design = json.load(file)
149
+ interface_name = design.get("interface_name", "")
150
+ components = design.get("components", [])
151
+ return interface_name, components, gr.update(visible=True, value="Design loaded successfully!")
152
+ except json.JSONDecodeError:
153
+ return None, [], gr.update(visible=True, value="Invalid JSON file")
154
+
155
+ def ui():
156
+ with gr.Blocks() as demo:
157
+ gr.Markdown("# Gradio UI Designer")
158
+ gr.Markdown("Design your Gradio interface by adding and customizing fields. Generate code with a single click!")
159
+
160
+ with gr.Row():
161
+ with gr.Column(scale=2):
162
+ interface_name = gr.Textbox(label="Interface Name", placeholder="Enter the interface name")
163
+
164
+ with gr.Group():
165
+ gr.Markdown("### Add/Edit Field")
166
+ component_type = gr.Dropdown(
167
+ choices=["Textbox", "Number", "Dropdown", "Slider", "Checkbox", "Radio"],
168
+ label="Field Type"
169
+ )
170
+ field_label = gr.Textbox(label="Field Label", placeholder="Enter field label")
171
+ placeholder_text = gr.Textbox(
172
+ label="Placeholder (for Textbox)",
173
+ visible=False,
174
+ placeholder="Enter placeholder text"
175
+ )
176
+ min_value = gr.Number(label="Min Value (for Slider/Number)", value=0, visible=False)
177
+ max_value = gr.Number(label="Max Value (for Slider/Number)", value=100, visible=False)
178
+ choices = gr.Textbox(
179
+ label="Choices (comma-separated for Dropdown/Radio)",
180
+ visible=False,
181
+ placeholder="e.g., Option 1, Option 2"
182
+ )
183
+
184
+ components_list = gr.State([])
185
+ add_button = gr.Button("Add Field")
186
+ edit_index = gr.Number(label="Field Index to Edit/Delete", value=0)
187
+ edit_button = gr.Button("Edit Field")
188
+ delete_button = gr.Button("Delete Field")
189
+
190
+ feedback = gr.Textbox(label="Feedback", visible=True)
191
 
192
+ with gr.Column(scale=3):
193
+ components_display = gr.JSON(label="Component List")
194
+ generated_code = gr.Code(label="Generated Code", language="python")
195
+ generate_button = gr.Button("Generate Code")
196
+
197
+ with gr.Row():
198
+ save_button = gr.Button("Save Design")
199
+ load_button = gr.UploadButton("Load Design", file_types=[".json"])
200
+
201
+ # Event handlers
202
+ component_type.change(
203
+ update_visibility,
204
+ inputs=[component_type],
205
+ outputs=[placeholder_text, min_value, choices, max_value]
206
+ )
207
+
208
+ add_button.click(
209
+ add_field,
210
+ inputs=[component_type, field_label, placeholder_text, min_value, max_value, choices, components_list],
211
+ outputs=[components_display, components_list, feedback]
212
+ )
213
+
214
+ edit_button.click(
215
+ edit_field,
216
+ inputs=[edit_index, component_type, field_label, placeholder_text, min_value, max_value, choices, components_list],
217
+ outputs=[components_display, components_list, feedback]
218
+ )
219
+
220
+ delete_button.click(
221
+ delete_field,
222
+ inputs=[edit_index, components_list],
223
+ outputs=[components_display, components_list, feedback]
224
+ )
225
+
226
+ generate_button.click(
227
+ generate_gradio_code,
228
+ inputs=[interface_name, components_list],
229
+ outputs=generated_code
230
+ )
231
+
232
+ save_button.click(
233
+ save_design,
234
+ inputs=[interface_name, components_list],
235
+ outputs=[feedback]
236
+ )
237
+
238
+ load_button.upload(
239
+ load_design,
240
+ inputs=[load_button],
241
+ outputs=[interface_name, components_list, feedback]
242
+ )
243
 
244
  return demo
245
 
246
  # Launch the Gradio app
247
  if __name__ == "__main__":
248
+ ui().launch()