Schedule Caching Flask_Caching & Redis

I’m trying to schedule caching to be set at a DateTime which led me down the road of CeleryManager. Essentially I’m using cache.memoize from flask caching which is currently triggered by a callback. This is not ideal as the first user each day will experience a few minutes of load time. Is there an alternative way to trigger the cache or what is the best way forward?

Yep, I actually have the same question at the same time haha ( How to Populate Celery Cache in Background - Dash Python - Plotly Community Forum). Would love if @adamschroeder might be able to weigh in and help us out? I think I’d get pretty heavy usage out of this functionality, so seems worthwhile to grab a good example or explanation before forging out on my own with this one.

Edit: Might be an example worthwhile adding to the docs under the Background callback caching section.

@dash-beginner I just saw your post a few minutes ago! Hoping we can get an answer from @adamschroeder as well!

@dash-beginner have you seen this?

Never seen that before, thanks for the link! Hm, I think I’m missing something, because I see the Cache class imported from flask_caching, but I don’t see it instantiated anywhere in that snipped of code (and then the decorator cache is being used later on? I guess generally speaking this approach still feels like it uses the method of setting up all of this outside of the background callback context like is used here: Background Callback Caching | Dash for Python Documentation | Plotly. It’s totally fine for me to avoid using the in-build methods in the callback decorator, but I figured it would be nice to write things in the most Dash-esque way.

hey there,
This is an interesting question. I’ll ask my colleagues, as some of them have more experience with Flask and caching. I’ll get back to you with an answer as soon as I find one.

Appreciate it, thanks Adam! :slight_smile:

I’ve never tried to warm-up a cache from flask-caching automatically and I don’t think there’s a “flask_caching” way to do it but you could probably create a POST request to app-url/_dash-update-component automatically to simulate a callback every morning. E.g create a cron job on a server to send a POST request using cURL and the JSON payload that you grab from a callback request (i.e a request to /_dash-update-component) in the chrome devtools.

That won’t solve the issue of the cache expiring in the middle of the day though so you might want to start the scheduled POST requests right after the app starts and perform them using the same period as the cache resets.

Instead of trying to warm-up a flask-caching cache, I’ve created my own cache using a redis db that I update on a schedule using celery before saving whatever data I want available. It’s a bit slower than flask caching, and more complicated to setup (you need a different process to run your dash app, celery worker and celery scheduler) but at least the end user experience is consistent and the data gets updated regularly. Here’s an old example app that does that GitHub - plotly/dash-redis-celery-periodic-updates: Demo apps now maintained in https://github.com/plotly/dash-enterprise-docs

1 Like

thanks for this @michaelbabyn, i found that repo a few hours ago after some digging and have been trying to get things up and running. out of curiosity, do you have your setup running in containers? if so, do you have celery running in the same container as the dash app or did you follow something like this:

Hm, so that makes sense and I’ll definitely poke a bit deeper into it, but I do generally kind of like using flask-caching and if I’m unable to access the caching key used directly in the background callback caching notation, I assume that your cache generating solution would work similarly to the process I had envisioned of having a separate file that uses apscheduler, pinging each of the functions on a certain interval to populate their caches (probably inside some sort of flask app_context clause). Haven’t quite tried it out yet, so something could very easily run into issues, but it should have the same user-experience as what you described, just with the slightly more confusing developer experience, I think

1 Like

Yeah, my setup was using three separate containers. One was running the dash app, one running the celery worker and one running the celery scheduler. That app uses a buildpack similar to Heroku to create the containers and they are defined in the Procfile.