import gradio as gr import os import json import importlib import sys from contextlib import redirect_stdout, redirect_stderr import io # Set environment variable to avoid matplotlib permission issues os.environ['MPLCONFIGDIR'] = '/tmp' # Toggle for different applications CURRENT_APP = "selector" # Example app implementations APP_REGISTRY = { "hello_world": { "title": "Hello World", "description": "A simple greeting app", "function": None # will be populated }, "calculator": { "title": "Calculator", "description": "A basic arithmetic calculator", "function": None # will be populated }, "image_filter": { "title": "Image Filter", "description": "Apply visual effects to images", "function": None # will be populated } } # Hello World implementation def create_hello_world(): def greet(name): return f"Hello, {name}!" demo = gr.Interface( fn=greet, inputs=gr.Textbox(label="Your Name"), outputs=gr.Textbox(label="Greeting"), title="Hello World App", description="A simple greeting app", examples=[["World"], ["Friend"], ["Gradio"]] ) return demo # Calculator implementation def create_calculator(): def calculate(num1, num2, operation): if operation == "Add": return num1 + num2 elif operation == "Subtract": return num1 - num2 elif operation == "Multiply": return num1 * num2 elif operation == "Divide": if num2 == 0: return "Error: Division by zero" return num1 / num2 demo = gr.Interface( fn=calculate, inputs=[ gr.Number(label="First Number"), gr.Number(label="Second Number"), gr.Radio(["Add", "Subtract", "Multiply", "Divide"], label="Operation") ], outputs=gr.Textbox(label="Result"), title="Calculator App", description="Perform basic arithmetic operations", examples=[ [5, 3, "Add"], [10, 4, "Subtract"], [6, 7, "Multiply"], [20, 4, "Divide"] ] ) return demo # Image Filter implementation def create_image_filter(): def apply_filter(image, filter_type): if image is None: return None import numpy as np from PIL import Image img_array = np.array(image) if filter_type == "Grayscale": result = np.mean(img_array, axis=2).astype(np.uint8) return Image.fromarray(result) elif filter_type == "Invert": result = 255 - img_array return Image.fromarray(result) elif filter_type == "Sepia": sepia = np.array([[0.393, 0.769, 0.189], [0.349, 0.686, 0.168], [0.272, 0.534, 0.131]]) sepia_img = img_array.dot(sepia.T) sepia_img[sepia_img > 255] = 255 return Image.fromarray(sepia_img.astype(np.uint8)) return image demo = gr.Interface( fn=apply_filter, inputs=[ gr.Image(type="pil"), gr.Radio(["Grayscale", "Invert", "Sepia"], label="Filter") ], outputs=gr.Image(type="pil"), title="Image Filter App", description="Apply different filters to your images", examples=[ ["https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=500", "Grayscale"], ["https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=500", "Invert"], ["https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=500", "Sepia"] ] ) return demo # Register demo creation functions APP_REGISTRY["hello_world"]["function"] = create_hello_world APP_REGISTRY["calculator"]["function"] = create_calculator APP_REGISTRY["image_filter"]["function"] = create_image_filter # Example of code for each app as a string (for display purposes) APP_CODES = { "hello_world": """ import gradio as gr def greet(name): return f"Hello, {name}!" demo = gr.Interface( fn=greet, inputs=gr.Textbox(label="Your Name"), outputs=gr.Textbox(label="Greeting"), title="Hello World App", description="A simple greeting app", examples=[["World"], ["Friend"], ["Gradio"]] ) """, "calculator": """ import gradio as gr def calculate(num1, num2, operation): if operation == "Add": return num1 + num2 elif operation == "Subtract": return num1 - num2 elif operation == "Multiply": return num1 * num2 elif operation == "Divide": if num2 == 0: return "Error: Division by zero" return num1 / num2 demo = gr.Interface( fn=calculate, inputs=[ gr.Number(label="First Number"), gr.Number(label="Second Number"), gr.Radio(["Add", "Subtract", "Multiply", "Divide"], label="Operation") ], outputs=gr.Textbox(label="Result"), title="Calculator App", description="Perform basic arithmetic operations", examples=[ [5, 3, "Add"], [10, 4, "Subtract"], [6, 7, "Multiply"], [20, 4, "Divide"] ] ) """, "image_filter": """ import gradio as gr import numpy as np from PIL import Image def apply_filter(image, filter_type): if image is None: return None img_array = np.array(image) if filter_type == "Grayscale": result = np.mean(img_array, axis=2).astype(np.uint8) return Image.fromarray(result) elif filter_type == "Invert": result = 255 - img_array return Image.fromarray(result) elif filter_type == "Sepia": sepia = np.array([[0.393, 0.769, 0.189], [0.349, 0.686, 0.168], [0.272, 0.534, 0.131]]) sepia_img = img_array.dot(sepia.T) sepia_img[sepia_img > 255] = 255 return Image.fromarray(sepia_img.astype(np.uint8)) return image demo = gr.Interface( fn=apply_filter, inputs=[ gr.Image(type="pil"), gr.Radio(["Grayscale", "Invert", "Sepia"], label="Filter") ], outputs=gr.Image(type="pil"), title="Image Filter App", description="Apply different filters to your images", examples=[ ["https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=500", "Grayscale"], ["https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=500", "Invert"], ["https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=500", "Sepia"] ] ) """ } # Function to create the selector app def create_selector(): with gr.Blocks(title="Gradio App Generator") as demo: gr.Markdown("# 🔄 Dynamic Gradio App Generator") gr.Markdown("Select an app type to load it, or use the LLM to generate one") with gr.Row(): with gr.Column(scale=1): # App selection area gr.Markdown("### 1. Choose an App Template") app_selection = gr.Radio( choices=list(APP_REGISTRY.keys()), value="hello_world", label="Available Templates", info="Select a template to view and run it", interactive=True ) # Description display app_description = gr.Markdown(f"**{APP_REGISTRY['hello_world']['title']}**: {APP_REGISTRY['hello_world']['description']}") # Load button load_btn = gr.Button("Load Selected App", variant="primary") # Code display with gr.Accordion("View Code", open=False): code_display = gr.Code( language="python", value=APP_CODES["hello_world"], label="App Code" ) # Status message status_msg = gr.Markdown("Select an app and click 'Load Selected App'") # Simulated LLM area gr.Markdown("### 2. Or Describe a New App") app_description_input = gr.Textbox( label="Describe the app you want", placeholder="e.g., A calculator app that can add, subtract, multiply and divide", lines=3 ) generate_btn = gr.Button("Generate & Load App") with gr.Column(scale=1): # Preview placeholder preview_box = gr.Markdown( """ ### App Preview No app loaded yet. Select an app template or describe a new app to load. """ ) # Update description when selection changes def update_description_and_code(selection): return f"**{APP_REGISTRY[selection]['title']}**: {APP_REGISTRY[selection]['description']}", APP_CODES[selection] app_selection.change( update_description_and_code, inputs=app_selection, outputs=[app_description, code_display] ) # Function to load the selected app def load_app(app_name): # Save the app name to a file so it persists with open("current_app.txt", "w") as f: f.write(app_name) return f"Loading {APP_REGISTRY[app_name]['title']}... Refresh the page to see it." load_btn.click( load_app, inputs=app_selection, outputs=status_msg ) # Function to handle app generation from description def generate_app(description): if not description: return "Please enter a description first." # Simple keyword matching to choose an app description = description.lower() if "hello" in description or "greet" in description: app_name = "hello_world" elif "calculat" in description or "math" in description or "add" in description: app_name = "calculator" elif "image" in description or "filter" in description or "photo" in description: app_name = "image_filter" else: # Default to hello world app_name = "hello_world" # Save the app name to a file with open("current_app.txt", "w") as f: f.write(app_name) return f"Generated and loading {APP_REGISTRY[app_name]['title']}... Refresh the page to see it." generate_btn.click( generate_app, inputs=app_description_input, outputs=status_msg ) return demo # Check which app to load if os.path.exists("current_app.txt"): try: with open("current_app.txt", "r") as f: app_name = f.read().strip() if app_name in APP_REGISTRY: CURRENT_APP = app_name else: CURRENT_APP = "selector" except: CURRENT_APP = "selector" # Launch the appropriate app if CURRENT_APP == "selector": demo = create_selector() else: try: # Try to create the requested app demo = APP_REGISTRY[CURRENT_APP]["function"]() except Exception as e: # Fall back to selector on error print(f"Error loading app {CURRENT_APP}: {str(e)}") demo = create_selector() # Launch the app if __name__ == "__main__": demo.launch(server_name="0.0.0.0", server_port=7860)