import gradio as gr import json import re # Utility functions def sanitize_name(name): return re.sub(r'\W|^(?=\d)', '_', name).lower() def validate_input(component): if component['type'] in ['Number', 'Slider']: min_value = float(component.get('min_value', 0)) max_value = float(component.get('max_value', 100)) if min_value >= max_value: return False, "Min value must be less than max value" elif component['type'] in ['Dropdown', 'Radio']: if not component.get('choices'): return False, f"{component['type']} must have at least one choice" return True, "" # Core functionality def generate_gradio_code(interface_name, components): sanitized_name = sanitize_name(interface_name) code = f"import gradio as gr\n\n" code += f"def {sanitized_name}_interface(*args):\n" code += f" # Your processing logic here\n" code += f" results = [arg for arg in args]\n" code += f" return results\n\n" code += f"with gr.Blocks() as {sanitized_name}:\n" code += f" inputs = []\n" for i, component in enumerate(components): label = component.get('label', f'Field {i+1}') field_type = component['type'] if field_type == "Textbox": placeholder = component.get('placeholder', '') code += f" input_{i} = gr.Textbox(label='{label}', placeholder='{placeholder}')\n" elif field_type == "Number": min_value = component.get('min_value', 0) max_value = component.get('max_value', 100) code += f" input_{i} = gr.Number(label='{label}', value=0, minimum={min_value}, maximum={max_value})\n" elif field_type == "Dropdown": choices = component.get('choices', ['Option 1', 'Option 2']) choices_str = json.dumps(choices) code += f" input_{i} = gr.Dropdown(label='{label}', choices={choices_str})\n" elif field_type == "Slider": min_value = component.get('min_value', 0) max_value = component.get('max_value', 100) code += f" input_{i} = gr.Slider(label='{label}', minimum={min_value}, maximum={max_value})\n" elif field_type == "Checkbox": code += f" input_{i} = gr.Checkbox(label='{label}')\n" elif field_type == "Radio": choices = component.get('choices', ['Option 1', 'Option 2']) choices_str = json.dumps(choices) code += f" input_{i} = gr.Radio(label='{label}', choices={choices_str})\n" code += f" inputs.append(input_{i})\n" code += f" outputs = [gr.Textbox(label='Output {i+1}') for i in range(len(inputs))]\n" code += f" gr.Interface(fn={sanitized_name}_interface, inputs=inputs, outputs=outputs).launch()\n" return code def add_field(component_type, field_label, placeholder_text, min_value, max_value, choices, components): new_component = {"type": component_type, "label": field_label} if component_type == "Textbox": new_component["placeholder"] = placeholder_text elif component_type in ["Number", "Slider"]: new_component["min_value"] = float(min_value) if min_value else 0 new_component["max_value"] = float(max_value) if max_value else 100 elif component_type in ["Dropdown", "Radio"]: choices_list = [choice.strip() for choice in choices.split(',') if choice.strip()] if not choices_list: choices_list = ['Option 1', 'Option 2'] new_component["choices"] = choices_list is_valid, error_message = validate_input(new_component) if not is_valid: return components, components, gr.update(visible=True, value=error_message) components.append(new_component) return components, components, gr.update(visible=True, value="Field added successfully!") def update_visibility(component_type): return ( gr.update(visible=component_type == "Textbox"), gr.update(visible=component_type in ["Slider", "Number"]), gr.update(visible=component_type in ["Dropdown", "Radio"]), gr.update(visible=component_type in ["Slider", "Number"]) ) def edit_field(index, component_type, field_label, placeholder_text, min_value, max_value, choices, components): try: index = int(index) if 0 <= index < len(components): new_component = {"type": component_type, "label": field_label} if component_type == "Textbox": new_component["placeholder"] = placeholder_text elif component_type in ["Number", "Slider"]: new_component["min_value"] = float(min_value) if min_value else 0 new_component["max_value"] = float(max_value) if max_value else 100 elif component_type in ["Dropdown", "Radio"]: choices_list = [choice.strip() for choice in choices.split(',') if choice.strip()] if not choices_list: choices_list = ['Option 1', 'Option 2'] new_component["choices"] = choices_list is_valid, error_message = validate_input(new_component) if not is_valid: return components, components, gr.update(visible=True, value=error_message) components[index] = new_component return components, components, gr.update(visible=True, value="Field updated successfully!") else: return components, components, gr.update(visible=True, value="Invalid field index") except ValueError: return components, components, gr.update(visible=True, value="Invalid index. Please enter a number.") def delete_field(index, components): try: index = int(index) if 0 <= index < len(components): del components[index] return components, components, gr.update(visible=True, value="Field deleted successfully!") else: return components, components, gr.update(visible=True, value="Invalid field index") except ValueError: return components, components, gr.update(visible=True, value="Invalid index. Please enter a number.") def save_design(interface_name, components): design = { "interface_name": interface_name, "components": components } filename = f"{sanitize_name(interface_name)}_design.json" with open(filename, 'w') as f: json.dump(design, f, indent=2) return gr.update(visible=True, value=f"Design saved to {filename}") def load_design(file): if file is None: return None, [], gr.update(visible=True, value="No file selected") try: design = json.load(file) interface_name = design.get("interface_name", "") components = design.get("components", []) return interface_name, components, gr.update(visible=True, value="Design loaded successfully!") except json.JSONDecodeError: return None, [], gr.update(visible=True, value="Invalid JSON file") def ui(): with gr.Blocks() as demo: gr.Markdown("# Gradio UI Designer") gr.Markdown("Design your Gradio interface by adding and customizing fields. Generate code with a single click!") with gr.Row(): with gr.Column(scale=2): interface_name = gr.Textbox(label="Interface Name", placeholder="Enter the interface name") with gr.Group(): gr.Markdown("### Add/Edit Field") component_type = gr.Dropdown( choices=["Textbox", "Number", "Dropdown", "Slider", "Checkbox", "Radio"], label="Field Type" ) field_label = gr.Textbox(label="Field Label", placeholder="Enter field label") placeholder_text = gr.Textbox( label="Placeholder (for Textbox)", visible=False, placeholder="Enter placeholder text" ) min_value = gr.Number(label="Min Value (for Slider/Number)", value=0, visible=False) max_value = gr.Number(label="Max Value (for Slider/Number)", value=100, visible=False) choices = gr.Textbox( label="Choices (comma-separated for Dropdown/Radio)", visible=False, placeholder="e.g., Option 1, Option 2" ) components_list = gr.State([]) add_button = gr.Button("Add Field") edit_index = gr.Number(label="Field Index to Edit/Delete", value=0) edit_button = gr.Button("Edit Field") delete_button = gr.Button("Delete Field") feedback = gr.Textbox(label="Feedback", visible=True) with gr.Column(scale=3): components_display = gr.JSON(label="Component List") generated_code = gr.Code(label="Generated Code", language="python") generate_button = gr.Button("Generate Code") with gr.Row(): save_button = gr.Button("Save Design") load_button = gr.UploadButton("Load Design", file_types=[".json"]) # Event handlers component_type.change( update_visibility, inputs=[component_type], outputs=[placeholder_text, min_value, choices, max_value] ) add_button.click( add_field, inputs=[component_type, field_label, placeholder_text, min_value, max_value, choices, components_list], outputs=[components_display, components_list, feedback] ) edit_button.click( edit_field, inputs=[edit_index, component_type, field_label, placeholder_text, min_value, max_value, choices, components_list], outputs=[components_display, components_list, feedback] ) delete_button.click( delete_field, inputs=[edit_index, components_list], outputs=[components_display, components_list, feedback] ) generate_button.click( generate_gradio_code, inputs=[interface_name, components_list], outputs=generated_code ) save_button.click( save_design, inputs=[interface_name, components_list], outputs=[feedback] ) load_button.upload( load_design, inputs=[load_button], outputs=[interface_name, components_list, feedback] ) return demo # Launch the Gradio app if __name__ == "__main__": ui().launch()