✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
⚡️ Concerned about the grid? Kyle Baranko teaches how to predicting peak loads using XGBoost. Register for the August webinar!

Using Dash in Flask App, extend base.html using Jinja2

I want to embed several dash apps into a larger Flask application.

I’ve followed this tutorial to setup the project structure:

In the flask app I am using Jinja2 to extend each page from a base.html file to carry over the navbar, style sheets, etc.

However, when I try to extend the index_string of the dash app in a similar way I run into roadblocks.

I modified the index_string per the dash documentation: https://dash.plotly.com/external-resources

I set my index_string to:

    dashapp1.index_string = '''
    {% extends "base.html" %}
    {% block content %}
        {%app_entry%}
        <footer>
            {%config%}
            {%scripts%}
            {%renderer%}
        </footer>
    {% endblock content %}
    '''

but it fails to pull in the base.html template.

Any help to resolve this would be greatly appreciated

image

1 Like

okay, so I got this to work in a roundabout way but it’s definitely very “hacky”. I’d love to hear suggestions on how to best refactor this.

I implemented a suggestion from this thread: https://github.com/plotly/dash/issues/214#issuecomment-391223557

What I did was returned my two dash apps as part of the create_app() function so I had access to them to modify the app.index() (or dashapp1.index() in my case).

I then added new app.route in my wsgi file and parsed the dashapp.index() to pull out the footer using bs4. I then injected this into a Jinja template using render_template to embed the dash app in my Flask base.html template to carryover all my navbar, css, logo, etc.

This is extremely hacky since I’ve added program logic to my wsgi file but I can’t find a better solution.

any suggestions?

.
.

wsgi.py

"""Application entry point."""
from application import create_app
from bs4 import BeautifulSoup
from flask import render_template

app, dashapp1, dashapp2 = create_app()


@app.route('/dashapp1', methods=['GET', 'POST'])
def dash_app1():
    soup = BeautifulSoup(dashapp1.index(), 'html.parser')
    footer = soup.footer
    return render_template('dash1.html', title='test', footer=footer)


@app.route('/dashapp2', methods=['GET', 'POST'])
def dash_app2():
    soup = BeautifulSoup(dashapp2.index(), 'html.parser')
    footer = soup.footer
    return render_template('dash1.html', title='test', footer=footer)


if __name__ == "__main__":
    # app.run(host='0.0.0.0', debug=True)
    app.run(debug=True)

.
.

dash1.html file

{% extends "base.html" %}
{% block content %}
    <div id="react-entry-point">
        <div class="_dash-loading">
            Loading...
        </div>
    </div>
    {{ footer|safe }}
{% endblock content %}

at least it works :sweat_smile:

1 Like