This is my version of COVID19 tracker using Plotly Dash for the United States. I leveraged several features of Dash to put together my first Dash web application. After using Dash, I developed a much deeper appreciation for the framework.
I think one of the most powerful features is Row + Col to create collapsable components or widgets on the web application. The web app is hosted on Digital Ocean running on Ubuntu 18.04 server with nginx and uWSGI. I’m also using SSL through Cloudfare. I have a cron job running daily to update the covid19 data in my MongoDB instance.
I could not quite figure out how to update my web app with the new data even after reading through the use of Redis, hidden divs, and so forth. Essentially, I wrote a few data transformation classes in Python to manipulate raw John’s Hopkin’s covid19 data into what I wanted for my dashboard.
In my mind, I would need a full reload to pull the new data into the web app, which would also trigger all my data transformation layers, and this would work because the custom data transformation process isn’t heavy-duty. I ended up using touch-reload in uWSGI .ini file to enable graceful reloading and just scheduled “touch uwsgi.ini” as a cron job to run daily. This is working for me.
If anyone has a scalable approach to this, please let me know. Additionally, let me know if you have any feedback! Thanks, guys!
Here’s a pattern that can work well if, as you say, the data transformation isn’t too heavy-duty.
Step 1 - fetch data on app load: You can assign a function to app.layout which is called whenever a user loads the app. This function should return the layout. You can fetch the data inside this function, and store it in the layout using dcc.Store. This mean when each new user visits your site, they have a copy of the data loaded into their browser’s memory ready for use in the graphs.
data = requests.get(...) # or whatever you need to do
# return the layout with the data in a Store component
return html.Div([dcc.Store(data=data, id="store"), ...])
# lack of () is not a typo, assign the function, not the return value
app.layout = build_layout
Step 2 - read data from store in callbacks: Now when you want to generate your graphs, you can set the store as State and read the data from there
def make_graph(dropdown_value, data):
# make the graph from `data`
Of course, if the data transformation isn’t near instant, then maybe you want to do something like have your cron process regenerate the data every day / hour or whatever and save the processed data to disk, then inside build_layout you simply read in the latest version of the processed data. Hope that all makes sense!