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' # 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"] ] ) """ } # Create an app selector that loads apps via iframe def create_main_app(): with gr.Blocks(title="Dynamic Gradio App Generator", css="#app-iframe { width: 100%; height: 600px; border: none; }") as demo: gr.Markdown("# 🔄 Dynamic Gradio App Generator") gr.Markdown("Select an app type to load it dynamically without refreshing the page") # App selection and display state current_app = gr.State("") with gr.Row(): with gr.Column(scale=1): # App selection area gr.Markdown("### 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'") with gr.Column(scale=2, elem_id="app-container"): # This HTML component will hold the iframe app_iframe = gr.HTML( value="

No app loaded yet. Select an app and click 'Load Selected App'.

", label="App Preview" ) # Update description and code 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] ) # Load the selected app using an iframe def load_app_in_iframe(app_name, previous_app): if app_name not in APP_REGISTRY: return ( f"Error: App '{app_name}' not found", "

App not found!

", previous_app ) # If the same app is already loaded, just notify the user if app_name == previous_app: return ( f"{APP_REGISTRY[app_name]['title']} is already loaded", f'', app_name ) # Create iframe HTML iframe_html = f'' return ( f"Successfully loaded {APP_REGISTRY[app_name]['title']}", iframe_html, app_name ) # Connect the button to the load function load_btn.click( load_app_in_iframe, inputs=[app_selection, current_app], outputs=[status_msg, app_iframe, current_app] ) return demo # Function to create and mount all apps def create_app(): # Create the main selector app main_app = create_main_app() # Create all the individual apps and mount them at their respective paths for app_name, app_info in APP_REGISTRY.items(): app_func = app_info["function"] if app_func: app_instance = app_func() main_app = gr.mount_gradio_app(main_app, app_instance, f"/{app_name}") return main_app # Launch the app if __name__ == "__main__": demo = create_app() demo.launch(server_name="0.0.0.0", server_port=7860)