Can a callback function call another callback function to create e.g. a progress bar?

My use case is to fire a function with a for loop once a user has clicked a button. The for loop is intensive so I would like to provide a progress bar to the user once each loop has ended. Is this possible or is there a work around?

It isn’t possible to update a component during a callback (i.e. update a progress bar while inside a callback that updates a graph). This might be available in the future if we we add web-socket support, but it isn’t possible now.

In the meantime, I recommend using a generic loading screen. If you know the maximum time that your function might take, then you could use a generic CSS progress bar that is timed to progress over that time. See 📣 Dash Loading States for a loading screen example.

1 Like

Thank you for your reply @chriddyp

Is this feature on the roadmap? I understand there is a roadmap section on your Winter workshops but unfortunately I am in the UK and cannot attend. Would you be able to share this with the community?

This isn’t on the immediate roadmap (as it is a substantial amount of work) and we don’t yet have a commercial sponsor lined up to cover this particular feature.

I have somewhat of a workaround for this issue but it isn’t the most accurate/effective. Also, I haven’t tested it myself so I’m unsure if it’ll work.

My workaround concept:

  • During the long callback function, cache “loop number” in redis
  • Use a dcc.Interval component in your dash layout that constantly fetches loop number from your redis cache and updates a html.Div component

It might not be synchronous but at least it’ll give you some indication of the loop you’re on. What do you guys think?

Update: Just tried it and it worked.

You may want to use the python redis library.

  • Use r.set("loop",0) at the beginning of your callback to reset the counter at the beginning of the function.
  • You can increment loop by 1 using the r.incr("loop") function.
  • Eventually, if you end up having many users, you will need a separate redis cache for each session ID.

Here’s a useful video (it’s really long but you can skip over most of it):