pythonhtmlflaskplotly-dashdash-leaflet

Integrating Dash and Flask by inserting Dash chart into div block of Flask template


My team is currently working on a project but recently we've got the following problem. To begin with, we're creating a website via Flask. We've already done a lot of work and have some nice html templates. However, the thing is that now we need to add Dash map (to be more precise, Dash Leaflet but I strongly believe that they're quite similar) to the certain div block of our page. Unfortunately, we have no idea how to realize it...

So, we already have a structured and designed html template for the page. As it was said above, the only thing we need to do is to insert Dash map into the certain div block:


...
<body>
    ...

    <div class="map">
    
        <!-- ??? ??? ??? ??? ??? ??? -->
        <!-- ???   Your Dash map ??? -->
        <!-- ??? ??? ??? ??? ??? ??? -->
    
    </div>
    
    ...
</body>
...

We have no ability to recreate the website as we have a lot of created things which would be quite sad and disappointing to rewrite:(

How can we integrate Flask app and Dash by inserting map to the certain div block? Is there any easy solution for this?


Solution

  • As some folks in the comments have suggested, using leaflet.js directly is a cleaner approach to doing this. One thing to bear in mind is that if you go down the Dash route, you're dependant on the dash-leaflet library continuing to be maintained and updated supporting new versions of Leaflet.

    But if you've got folks who've already put some effort into building a Dash Leaflet app then can totally see why you'd wanna at least explore whether getting them to play together is viable.

    If you want to place the Dash app in a <div>, I suspect the best way is probably just to use an <iframe> that points to the endpoint your app is running.

    Conveniently, Dash uses Flask under the hood, so a trick you might find handy is that you can get your existing Flask server to serve your Dash app under a specific path, by passing the Flask server instance to your Dash instance's server param, and setting the url_base_pathname param to a prefix to mount the Dash app at. Here's a simple example:

    app.py

    from flask import Flask
    
    from dash_app import make_dash, make_layout, define_callbacks
    
    app = Flask(__name__)
    
    @app.route("/")
    def hello_world():
        return "<p>Hello, World!</p>"
    
    dash_app = make_dash(app)
    dash_app.layout = make_layout()
    define_callbacks()
    

    dash_app.py

    from dash import Dash, html, callback, dcc, Input, Output
    
    
    def make_dash(server):
        return Dash(
            server=server,
            url_base_pathname='/dash/'
        )
    
    def make_layout():
        return html.Div(                                                                                                                                                                                                 
            [                                                                                                                                                                                                            
                html.P("Hey this is a Dash app :)"),                                                                                                                                                                     
                dcc.Input(id="input"),                                                                                                                                                                                   
                html.Div(id="output"),                                                                                                                                                                                   
            ]                                                                                                                                                                                                            
        )
    
    def define_callbacks():
        @callback(
            Output("output", "children"),
            Input("input", "value"),
        )
        def show_output(text):
            return f"you entered: '{text}'"
    

    When you navigate to /, you'll see the Flask route, and navigating to /dash will show you the Dash app. You could either have users go directly to the Dash URL, or use that path as the location of the iframe if you need to embed it within an existing page.