Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -223,15 +223,17 @@ demo = gr.Interface(
|
|
| 223 |
"""
|
| 224 |
}
|
| 225 |
|
| 226 |
-
#
|
| 227 |
def create_main_app():
|
| 228 |
-
with gr.Blocks(title="Dynamic Gradio App Generator"
|
| 229 |
gr.Markdown("# 🔄 Dynamic Gradio App Generator")
|
| 230 |
-
gr.Markdown("Select an app type to load it dynamically")
|
| 231 |
|
| 232 |
-
#
|
| 233 |
-
|
| 234 |
-
|
|
|
|
|
|
|
| 235 |
|
| 236 |
with gr.Row():
|
| 237 |
with gr.Column(scale=1):
|
|
@@ -261,12 +263,15 @@ def create_main_app():
|
|
| 261 |
|
| 262 |
# Status message
|
| 263 |
status_msg = gr.Markdown("Select an app and click 'Load Selected App'")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 264 |
|
| 265 |
-
#
|
| 266 |
-
with gr.Row(id="app-container"):
|
| 267 |
-
app_placeholder = gr.Markdown("No app loaded yet. Select an app and click 'Load Selected App'.")
|
| 268 |
-
|
| 269 |
-
# Update description when selection changes
|
| 270 |
def update_description_and_code(selection):
|
| 271 |
return (
|
| 272 |
f"**{APP_REGISTRY[selection]['title']}**: {APP_REGISTRY[selection]['description']}",
|
|
@@ -279,124 +284,112 @@ def create_main_app():
|
|
| 279 |
outputs=[app_description, code_display]
|
| 280 |
)
|
| 281 |
|
| 282 |
-
#
|
| 283 |
-
|
| 284 |
-
|
| 285 |
-
return (
|
| 286 |
-
gr.update(value="App not found!"),
|
| 287 |
-
f"Error: App '{app_name}' not found",
|
| 288 |
-
previous_app_name,
|
| 289 |
-
previous_app_instance
|
| 290 |
-
)
|
| 291 |
-
|
| 292 |
-
# If we already have this app loaded, just return it
|
| 293 |
-
if app_name == previous_app_name and previous_app_instance is not None:
|
| 294 |
-
return (
|
| 295 |
-
gr.update(visible=False),
|
| 296 |
-
f"{APP_REGISTRY[app_name]['title']} is already loaded",
|
| 297 |
-
app_name,
|
| 298 |
-
previous_app_instance
|
| 299 |
-
)
|
| 300 |
-
|
| 301 |
try:
|
| 302 |
-
# Create
|
| 303 |
-
|
|
|
|
| 304 |
|
| 305 |
-
#
|
| 306 |
-
return
|
| 307 |
-
|
| 308 |
-
|
| 309 |
-
|
| 310 |
-
new_app_instance
|
| 311 |
-
)
|
| 312 |
except Exception as e:
|
| 313 |
error_msg = str(e)
|
| 314 |
-
return
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
|
| 318 |
-
previous_app_instance
|
| 319 |
-
)
|
| 320 |
-
|
| 321 |
-
# Handle app loading when button is clicked
|
| 322 |
-
load_btn.click(
|
| 323 |
-
load_app,
|
| 324 |
-
inputs=[app_selection, current_app_name, current_app_instance],
|
| 325 |
-
outputs=[app_placeholder, status_msg, current_app_name, current_app_instance]
|
| 326 |
-
)
|
| 327 |
|
| 328 |
-
#
|
| 329 |
-
demo.load(None,
|
| 330 |
function() {
|
| 331 |
-
|
| 332 |
-
|
| 333 |
-
const appContainer = document.getElementById('app-container');
|
| 334 |
-
if (!appContainer) return;
|
| 335 |
-
|
| 336 |
-
// Clear existing app container
|
| 337 |
-
while (appContainer.firstChild) {
|
| 338 |
-
appContainer.removeChild(appContainer.firstChild);
|
| 339 |
-
}
|
| 340 |
-
|
| 341 |
-
// Add new app to container
|
| 342 |
-
if (appInstance && appInstance.wrapper) {
|
| 343 |
-
appContainer.appendChild(appInstance.wrapper);
|
| 344 |
-
}
|
| 345 |
-
};
|
| 346 |
-
|
| 347 |
-
// Function to check for app updates
|
| 348 |
-
window.checkAppUpdates = function() {
|
| 349 |
-
const gradioEl = document.querySelector("gradio-app");
|
| 350 |
-
if (!gradioEl) return;
|
| 351 |
-
|
| 352 |
-
const shadowRoot = gradioEl.shadowRoot || gradioEl;
|
| 353 |
-
const appContainer = shadowRoot.querySelector("#app-container");
|
| 354 |
-
if (!appContainer) return;
|
| 355 |
-
|
| 356 |
-
// Find any newly loaded app by looking for interface/blocks elements
|
| 357 |
-
const newAppElements = shadowRoot.querySelectorAll(".gradio-container:not([id='main-container'])");
|
| 358 |
|
| 359 |
-
|
| 360 |
-
|
| 361 |
-
|
| 362 |
-
|
| 363 |
-
|
| 364 |
-
|
| 365 |
-
|
| 366 |
-
|
| 367 |
-
|
| 368 |
-
}
|
| 369 |
-
});
|
| 370 |
|
| 371 |
-
|
| 372 |
-
|
| 373 |
-
|
| 374 |
-
|
| 375 |
-
placeholder.style.display = "none";
|
| 376 |
}
|
| 377 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 378 |
}
|
| 379 |
-
};
|
| 380 |
-
|
| 381 |
-
// Set up an interval to check for app updates
|
| 382 |
-
setInterval(window.checkAppUpdates, 500);
|
| 383 |
}
|
| 384 |
""")
|
| 385 |
|
| 386 |
return demo
|
| 387 |
|
| 388 |
-
#
|
| 389 |
-
def
|
| 390 |
-
|
| 391 |
-
|
| 392 |
-
|
| 393 |
-
|
| 394 |
-
|
| 395 |
-
|
| 396 |
-
|
| 397 |
-
|
| 398 |
-
|
|
|
|
|
|
|
|
|
|
| 399 |
|
| 400 |
# Launch the app
|
| 401 |
if __name__ == "__main__":
|
| 402 |
-
|
|
|
|
|
|
| 223 |
"""
|
| 224 |
}
|
| 225 |
|
| 226 |
+
# Create an app selector that loads apps dynamically
|
| 227 |
def create_main_app():
|
| 228 |
+
with gr.Blocks(title="Dynamic Gradio App Generator") as demo:
|
| 229 |
gr.Markdown("# 🔄 Dynamic Gradio App Generator")
|
| 230 |
+
gr.Markdown("Select an app type to load it dynamically without refreshing the page")
|
| 231 |
|
| 232 |
+
# Create placeholders for dynamic app loading
|
| 233 |
+
app_blocks_container = gr.Blocks(visible=False)
|
| 234 |
+
with app_blocks_container:
|
| 235 |
+
# This container will be dynamically replaced
|
| 236 |
+
app_placeholder = gr.Markdown("Loading app...")
|
| 237 |
|
| 238 |
with gr.Row():
|
| 239 |
with gr.Column(scale=1):
|
|
|
|
| 263 |
|
| 264 |
# Status message
|
| 265 |
status_msg = gr.Markdown("Select an app and click 'Load Selected App'")
|
| 266 |
+
|
| 267 |
+
with gr.Column(scale=2):
|
| 268 |
+
# This is where our dynamically loaded app will appear
|
| 269 |
+
app_container = gr.Group(visible=True)
|
| 270 |
+
with app_container:
|
| 271 |
+
gr.Markdown("### App Preview")
|
| 272 |
+
gr.Markdown("No app loaded yet. Select an app and click 'Load Selected App'.")
|
| 273 |
|
| 274 |
+
# Update description and code when selection changes
|
|
|
|
|
|
|
|
|
|
|
|
|
| 275 |
def update_description_and_code(selection):
|
| 276 |
return (
|
| 277 |
f"**{APP_REGISTRY[selection]['title']}**: {APP_REGISTRY[selection]['description']}",
|
|
|
|
| 284 |
outputs=[app_description, code_display]
|
| 285 |
)
|
| 286 |
|
| 287 |
+
# Load the selected app
|
| 288 |
+
@gr.on(load_btn, "click")
|
| 289 |
+
def load_selected_app(selection):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 290 |
try:
|
| 291 |
+
# Create the app
|
| 292 |
+
app_func = APP_REGISTRY[selection]["function"]
|
| 293 |
+
app = app_func()
|
| 294 |
|
| 295 |
+
# Update the container content (this is done via JavaScript)
|
| 296 |
+
return {
|
| 297 |
+
status_msg: f"Successfully loaded {APP_REGISTRY[selection]['title']}",
|
| 298 |
+
app_container: gr.update(visible=False), # Hide temporarily for replacement
|
| 299 |
+
}
|
|
|
|
|
|
|
| 300 |
except Exception as e:
|
| 301 |
error_msg = str(e)
|
| 302 |
+
return {
|
| 303 |
+
status_msg: f"Error loading app: {error_msg}",
|
| 304 |
+
app_container: gr.update(visible=True),
|
| 305 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 306 |
|
| 307 |
+
# This uses Gradio's JavaScript event handling to dynamically mount the app
|
| 308 |
+
demo.load(None, js="""
|
| 309 |
function() {
|
| 310 |
+
let loadedAppIframe = null;
|
| 311 |
+
let intervalId = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 312 |
|
| 313 |
+
// Function to handle the "Load Selected App" button click
|
| 314 |
+
document.addEventListener('click', function(event) {
|
| 315 |
+
// Find button by text or class
|
| 316 |
+
if (event.target.textContent === 'Load Selected App' ||
|
| 317 |
+
(event.target.parentElement && event.target.parentElement.textContent === 'Load Selected App')) {
|
| 318 |
+
|
| 319 |
+
// Get the selected app
|
| 320 |
+
const radioButtons = document.querySelectorAll('input[type="radio"]');
|
| 321 |
+
let selectedApp = null;
|
|
|
|
|
|
|
| 322 |
|
| 323 |
+
for (const radio of radioButtons) {
|
| 324 |
+
if (radio.checked) {
|
| 325 |
+
selectedApp = radio.value;
|
| 326 |
+
break;
|
|
|
|
| 327 |
}
|
| 328 |
}
|
| 329 |
+
|
| 330 |
+
if (!selectedApp) return;
|
| 331 |
+
|
| 332 |
+
// Stop any previous timer
|
| 333 |
+
if (intervalId) {
|
| 334 |
+
clearInterval(intervalId);
|
| 335 |
+
}
|
| 336 |
+
|
| 337 |
+
// Show loading indicator
|
| 338 |
+
const appContainer = document.querySelector('.app-preview');
|
| 339 |
+
if (appContainer) {
|
| 340 |
+
appContainer.innerHTML = '<p>Loading app...</p>';
|
| 341 |
+
}
|
| 342 |
+
|
| 343 |
+
// Create route for app
|
| 344 |
+
const appUrl = '/' + selectedApp;
|
| 345 |
+
|
| 346 |
+
// Clean up previous iframe if exists
|
| 347 |
+
if (loadedAppIframe) {
|
| 348 |
+
loadedAppIframe.remove();
|
| 349 |
+
}
|
| 350 |
+
|
| 351 |
+
// Create an iframe and load the app
|
| 352 |
+
loadedAppIframe = document.createElement('iframe');
|
| 353 |
+
loadedAppIframe.style.width = '100%';
|
| 354 |
+
loadedAppIframe.style.height = '600px';
|
| 355 |
+
loadedAppIframe.style.border = 'none';
|
| 356 |
+
loadedAppIframe.src = appUrl;
|
| 357 |
+
|
| 358 |
+
// Find the app container column (second column)
|
| 359 |
+
const columns = document.querySelectorAll('.gradio-column');
|
| 360 |
+
if (columns.length > 1) {
|
| 361 |
+
columns[1].innerHTML = ''; // Clear existing content
|
| 362 |
+
columns[1].appendChild(loadedAppIframe);
|
| 363 |
+
}
|
| 364 |
+
|
| 365 |
+
// Update the status
|
| 366 |
+
const statusEl = document.querySelector('#status-message');
|
| 367 |
+
if (statusEl) {
|
| 368 |
+
statusEl.textContent = 'App loaded successfully';
|
| 369 |
+
}
|
| 370 |
}
|
| 371 |
+
});
|
|
|
|
|
|
|
|
|
|
| 372 |
}
|
| 373 |
""")
|
| 374 |
|
| 375 |
return demo
|
| 376 |
|
| 377 |
+
# Function to create and mount all apps
|
| 378 |
+
def create_app():
|
| 379 |
+
# Create the main selector app
|
| 380 |
+
main_app = create_main_app()
|
| 381 |
+
|
| 382 |
+
# Create all the individual apps
|
| 383 |
+
for app_name, app_info in APP_REGISTRY.items():
|
| 384 |
+
app_func = app_info["function"]
|
| 385 |
+
if app_func:
|
| 386 |
+
app_instance = app_func()
|
| 387 |
+
# This is for Gradio 4.x - it mounts each app at its own route
|
| 388 |
+
main_app = gr.mount_gradio_app(main_app, app_instance, f"/{app_name}")
|
| 389 |
+
|
| 390 |
+
return main_app
|
| 391 |
|
| 392 |
# Launch the app
|
| 393 |
if __name__ == "__main__":
|
| 394 |
+
demo = create_app()
|
| 395 |
+
demo.launch(server_name="0.0.0.0", server_port=7860)
|