Launch a second Dash from a first dash app on the fly

Hi all,

I am interested in a dash app that generates code for buidling a dashapp. As part of this Dash app, I would like to be able to run the generated code and link the main app to see an interactive rendering in the main app. What I tried:

  • Having a div generated and link it to the main page layout. It works but does not all call backs to be linked & interact with the first app which creates potential errors.
  • Adding a management of registration of the callbakcs from the secondary to the main app. It works but it does not allow refresh or removal of non valid callback anymore from the new iteration of generated code
  • Create a full second app, launch it by sub process to isolate both & link to an Iframe. It seems the best solution, but I can"t get the second app launched properly & linked to the Iframe working. Here is the code

app1.py

import dash
from dash import html, dcc, Input, Output, State
import subprocess
import time
import socket
import threading
import sys

def find_available_port():
    """Finds an available port on the system."""
    sock = socket.socket()
    sock.bind(('', 0))
    return sock.getsockname()[1]

available_port = 8055 #find_available_port()

app = dash.Dash(__name__)

app.layout = html.Div([
    html.H1("Dash App 1"),
    html.Button("Launch App 2", id="launch-button"),
    html.Div(id="status-div"),
    html.Div(id="iframe-container", children=[]), # Placeholder for iframe
])

app2_process = None  # Variable to store the subprocess
app2_launched = False # Flag to ensure the second app isn't started multiple times


import subprocess
import sys

def launch_app2(port):
    global app2_process, app2_launched
    print(port)
    # Run app2.py in the background
    if not app2_launched:
        try:
            app2_process = subprocess.Popen([sys.executable, "app2.py", f"--port={port}"], creationflags=subprocess.CREATE_NEW_PROCESS_GROUP, close_fds=True, start_new_session=True)
            app2_launched = True
            return "App 2 launched successfully!", True
        except Exception as e:
           return f"Error launching App 2: {e}", False
    else:
        return "App 2 is already launched", True
    
@app.callback(
    [Output("status-div", "children"),
     Output("iframe-container", "children")],
    Input("launch-button", "n_clicks"),
    State("iframe-container", "children")
)
def update_iframe(n_clicks, current_iframe):
    global available_port
    if n_clicks is None:
        return "Click the button to launch App 2.", current_iframe
    
    status_msg, success = launch_app2(available_port)
    
    if success:
        time.sleep(1)
        # Replace '192.168.x.x' with your local IP address
        iframe = html.Iframe(src=f"http://<your_local_ip>:{available_port}", style={"width": "100%", "height": "600px"})
        return status_msg, [iframe]
    else:
        return status_msg, current_iframe


if __name__ == "__main__":
    app.run_server(debug=True)

app2.py


import dash
from dash import html
import argparse

parser = argparse.ArgumentParser(description="Run the second dash application")
parser.add_argument("--port", type=int, required=True, help="Port number")
args = parser.parse_args()

app = dash.Dash(__name__)

app.layout = html.Div("Hello World")

if __name__ == "__main__":
     try:
         print("starting app2 server") # Debug line
         app.run_server(debug=True, port=args.port, host="127.0.0.1")
     except Exception as e:
         print(f"Error on run_server: {e}")

However, it creates the following error I can’t get rid of. Is there a way that would work ?
Error on run_server: [WinError 10038] An operation has been tried on a non Socket element.

Thanks!

1 Like

Do you know all possible apps that can be launched when the “mother” app is launched?