What is the proper way to handle user-defined app configuration options from a file in Plotly Dash?

What is the proper way to handle user-defined app configuration options from a file in Plotly Dash? Specifically, I would like for these options to be loaded/accessible when the Dash object is being instantiated so that I can pass arguments to its constructor (e.g. url_base_pathname when instantiating Dash app object), as well as be accessible inside of callbacks.

In Flask, according to its documentation, we have this method:
Configuration Handling — Flask Documentation (2.3.x) (palletsprojects.com)

I tried to check the Dash object if it has Flask’s from_file method and found that it doesn’t have it. (So I can’t follow what’s outlined in the Flask docs)

If I was in a hurry and only cared about the short-term, I would just create a global variable at the top of my app.py file that loads in the data from the json file and call it a day. However, we have this in Plotly Documentation: Why Global Variables will break your app
So I want to confirm with the community/subject-matter-experts what indeed is the proper approach.

Minimum Reproducible Example of what I’m talking about:

import json

from dash import Dash, html, callback, Input, Output


# with open("config.json", "r") as file:
#     config = json.load(file)

# Actually loaded from the file using the above commented code
config = {
    "option_1": "something1",
    "url_base_pathname": "/somebasepath/"
}

app = Dash(
    __name__, 
    url_base_pathname=config['url_base_pathname']
)

app.layout = html.Div(
    children=[
        html.P(
            id='paragraph-1',
            children=f"Hello World"
        ),
        html.P(
            id='paragraph-2',
            children=""
        )
    ]
)

@callback(
    Output('paragraph-2','children'),
    Input('paragraph-1', 'children')
)
def update_paragraph_2(p_1_child):
    return config['option_1']

if __name__ == "__main__":
    app.run()

Hello @human42,

What is your use case for this? Is this something that pages and pathname variables could handle?

The whole app is in stateless form, this is true, but the routes have to be setup, which is what you are trying to alter based upon request. This is more aligned with how pathname variables of pages works.

4 use cases:

  1. To have a configurable url base pathname. Technically, the pathname variables would work, but I would have to manually append the base path name to each of the pathname variables, which I’m not sure is the intended method? And I would have to make each .py file of each page read the json file to get the base pathname too. Not sure this feels right…
  2. To have a configurable name of the table in the database that the callbacks fetch data from using Python to MariaDB Connector | MariaDB
  3. To have a configurable numerical limit of how many rows the Dash app can fetch from the database. Again, this condition is checked in the callbacks.
  4. To have configurable database authentication credentials.

All of those configurable things I am defining in a config.json, which i want to read and load into my app once only in one place in the code.

It’s not only just the base route path but also other config options i want to compare against from inside of my callbacks.

I can’t just use dcc.Store because there are auth credentials, and dcc.Store data is accessible to the client.

Here is the specific format of the .json file:
wesnoth/wesnoth-multiplayer-data-dashboard: This is a dashboard that allows you to query and visualize data that the Wesnoth Project collects about multiplayer games played on the official server. (github.com)

You can use a serverSide store to hold the config so that this data is not accessible.

The routes are all determined at runtime to the app, especially the configuration or url base pathname… This is how the app works, in order to listen to multiple base paths you would need to be running multiple servers.

okay, i think i know what to do, ill post back when im done

1 Like