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 endpoint to get the app configuration def get_app_config(app_name): if app_name not in APP_REGISTRY: return {"error": f"App '{app_name}' not found"} return { "title": APP_REGISTRY[app_name]["title"], "description": APP_REGISTRY[app_name]["description"], "code": APP_CODES[app_name] } # Create an endpoint to load an app def load_app_interface(app_name): if app_name not in APP_REGISTRY: return None try: # Capture stdout/stderr to prevent it from polluting the response stdout_buffer = io.StringIO() stderr_buffer = io.StringIO() with redirect_stdout(stdout_buffer), redirect_stderr(stderr_buffer): app = APP_REGISTRY[app_name]["function"]() return app except Exception as e: return None # Main app with dynamic loading capabilities def create_main_app(): with gr.Blocks(title="Dynamic Gradio App Generator", css="#app-container { min-height: 400px; }") as demo: gr.Markdown("# 🔄 Dynamic Gradio App Generator") gr.Markdown("Select an app type to load it without refreshing the page") # Create a state variable to track the current app current_app = gr.State("none") 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): # App container (where the dynamic app will be loaded) app_container = gr.HTML( value="

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

", label="App Preview" ) # Update description and code when selection changes def update_description_and_code(selection): config = get_app_config(selection) return ( f"**{config['title']}**: {config['description']}", config['code'] ) app_selection.change( update_description_and_code, inputs=app_selection, outputs=[app_description, code_display] ) # Function to dynamically load the selected app def load_selected_app(app_name): try: # Clear the previous app gr.update(value="

Loading app...

") # Create a new app instance selected_app = load_app_interface(app_name) if selected_app is None: return ( gr.update(value="

Error loading app. Please try again.

"), f"Error: Could not load {APP_REGISTRY[app_name]['title']}", app_name ) # Generate a unique ID for this app instance app_id = f"app-{app_name}-{id(selected_app)}" # Create a custom JavaScript function that will inject the app js_code = f"""

Loading {APP_REGISTRY[app_name]['title']}...

""" return ( gr.update(value=js_code), f"Successfully loaded {APP_REGISTRY[app_name]['title']}", app_name ) except Exception as e: error_msg = str(e) return ( gr.update(value=f"

Error: {error_msg}

"), f"Error: {error_msg}", app_name ) # Handle the load button click load_btn.click( load_selected_app, inputs=app_selection, outputs=[app_container, status_msg, current_app] ) return demo # Create and launch the main app demo = create_main_app() # Add endpoints for direct API access to apps for app_name, app_info in APP_REGISTRY.items(): app_func = app_info["function"] if app_func: app = app_func() demo = gr.mount_gradio_app(demo, app, f"/{app_name}") # Launch the app if __name__ == "__main__": demo.launch(server_name="0.0.0.0", server_port=7860)