I am building a web app using Flask and Dash. The main Flask app handles user login and authentication, and protects the routes of the Dash app. The Dash app is served from within the Flask app.
The main Flask app was built using the Flask Mega Tutorial example (https://github.com/miguelgrinberg/microblog), with the app factory pattern. I stripped out everything except the login/authentication stuff and the app works fine at that stage.
I then added a simple Dash app within the Flask app following the example here: https://github.com/okomarov/dash_on_flask. The Dash app can be access at /dashboard, and the dashboard is properly protected against unauthorised access and redirects back to the main Flask login page as expected.
My challenge is now to access the Flask app's context and other things like the database session from within the Dash app. This is so the Dash app can access and display information from the main database.
I am currently stuck trying to follow examples that I have found online, and how to adapt them to the particular pattern of my app.
I have tried to follow examples linked here: https://github.com/plotly/dash/issues/214#issuecomment-391223557.
However, these examples seem to all be based on a flat app structure where the Flask and Dash apps are created in the same file.
All of my code is located here: https://github.com/danielcopelin/dacy-budget
At the moment, my main Flask app looks like:
dacybudget.py
from app import create_app, db
from app.models import User
app = create_app()
@app.shell_context_processor
def make_shell_context():
return {'db': db, 'User': User}
create_app() looks like:
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
register_dashapps(app)
db.init_app(app)
migrate.init_app(app, db)
login.init_app(app)
mail.init_app(app)
bootstrap.init_app(app)
... and register_dashapps() looks like:
def register_dashapps(app):
from app.dashapp1.layout import layout
from app.dashapp1.callbacks import register_callbacks
# Meta tags for viewport responsiveness
meta_viewport = {
"name": "viewport",
"content": "width=device-width, initial-scale=1, shrink-to-fit=no",
}
external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
dashapp1 = dash.Dash(
__name__,
server=app,
url_base_pathname="/dashboard/",
assets_folder=get_root_path(__name__) + "/dashboard/assets/",
meta_tags=[meta_viewport],
external_stylesheets=external_stylesheets,
)
dashapp1.title = "Dashapp 1"
dashapp1.layout = layout
dashapp1.url_base_pathname = "/dashboard/" # I dont know why I had to do this
register_callbacks(dashapp1)
_protect_dashviews(dashapp1)
From within app.dashapp1.layout and app.dashapp1.callbacks I want to be able to access the main Flask app's session and database, etc.
If I try various imports from within app.dashapp1.layout, for example "from .. import db" and then try to do something with that db object, I get errors like:
RuntimeError: No application found. Either work inside a view function or push an application context. See http://flask-sqlalchemy.pocoo.org/contexts/.
Could anyone offer any suggestions on how to navigate this issue?