Hello everyone,
let me try to explain what is my issue in simple words and if it’s really solvable or not in a different way I already did but it doesn’t convince much.
Because this is not a personal project, I will not share the exact code I am using but I think we will make an idea with some adjustments.
I have a Plotly Dash application embedded into a Flask application with following routes:
# This includes all the login for performing authorisation flow with an identity provider
@app.before_request
def protect_views():
# Protect all the views
@app.route(LOGIN_URL_PATH)
def login():
# Login
@app.route(LOGOUT_URL_PATH)
def logout():
# Logout
The app.py entrypoint is roughly the following:
# Startup and run the Flask server attached with some configuration
app = Dash(__name__, server=Flask(), suppress_callback_exceptions=True). # using a flask server
app.layout = serve_layout
callbacks.register_callbacks(app)
if __name__ == "__main__":
app.run_server(debug=True, host="0.0.0.0", port=5000)
as you can see, I use two functions: serve_layout
for serving the layout I prepared into into a layout.py
file and register_callbacks
for registering my callbacks into a callbacks.py
file. Specifically, my layout.py
looks like this:
def serve_layout():
result = get_data_from_database() # Pseudocode, getting data from a DB
input_data = result.to_dict("records")
table = pac.DataTable(
id='dash_table',
data=input_data,
columns=prepare_columns(input_data),
editable=True,
filter_action="native",
sort_action="native",
sort_mode="multi",
column_selectable="multi",
row_selectable="multi",
page_action="native",
page_current=0,
page_size=10,
style_table={'overflowY': 'scroll'},
)
out = html.Div(id='output', style={'display': 'none'})
layout = html.Div(children=[
html.H4(id='page-id', children=["Hello"], style={'text-align': 'right'}),
html.Div(id="page-content",children=[html.Div(children=[table]), out])
]
)
return layout
So, I am able to run the server but when it comes to get_data_from_database()
my code fails because I have a dependency from my authorisation flow: in other words, I have to perform my authorisation flow first, get a token that I need to provide to my function in order to establish a connection, retrieve the data and visualise them. Even if I am not providing the full code, my question is clear: is it possible to do something like this? I actually was able to solve it by authenticating first and performing my query afterwards if I included my table rendering in a callback, in order to render it after I have a Flask session available and I included all the pieces in my application context. It means, like this:
@dashapp.callback(
Output('page-content', 'children'),
Input("output", "children"),
)
def display_table(children):
result = get_data_from_database() # Pseudocode, getting data from a DB
return pac.DataTable(
id='dash_table',
data=input_data,
columns=prepare_columns(input_data),
editable=True,
filter_action="native",
sort_action="native",
sort_mode="multi",
column_selectable="multi",
row_selectable="multi",
page_action="native",
page_current=0,
page_size=10,
style_table={'overflowY': 'scroll'},
)
But, this solution doesn’t convince me because of two reasons:
- I want to achieve something different. The use of
serve_layout
helped me a bit because it enables dynamic layout, when I run the server and try to access my application locally, it tries to build my layout first other than start the routing. I found a few similar examples but not exact as I need. I know and understand how Plotly Dash applications work but I was wondering if there’s some kind of workaround to do it or a nicer solution. - The proposed solutions is extremely slow
I hope that someone can give me some insights? Maybe aslo something I didn’t understand properly. Thanks