Ui / app.py
xtreme86's picture
update
9ab5cea
raw
history blame contribute delete
No virus
10.9 kB
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()