Serve layout after Flask routing

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