Just wondering if anyone has tried to use background callbacks with flask_login? I would like to use the current_user object in a background callback but I haven’t found a way to do this so far. Basically I am using Redis and Celery to do some back-end data parsing and saving of files on the server but I would like to first check that the user is logged in and has the right permissions.
I can almost achieve something similar by using a normal callback first as an intermediate step but of course there is still a security weakness that theoretically a well informed person could directly call the background callback even if not through the UI.
Does anybody have an idea or suggestion for getting the current_user object available in the celery worker?
Hi @andredfb, I don’t have any solution for you unfortunately, but I’m interested if you made progress on this? I’m going down the path of incorporating access controls in a dash app and so will likely be running into this soon as well.
The ‘request’ context should be propagated to the background callback environment, imo. This would be a good feature request. I’m having the same problem.
A part of my user login process requires a bit of time to execute (getting preferences) so I’m hoping to make that run in a background callback. However, because the request context isn’t in the background callback, the user session ID isn’t available and the user can’t log in.
I could use localStorage but then I’m implementing stuff outside of the scope of what’s managed automatically by Flask-Login, which I don’t want to do by default.
I believe that background_callbacks are invoked via a standard callback targeting the _dash-update-component endpoint.
It also appears that the background_callback context could be enriched with the calling callback’s ‘request’ object via the following AttributeDict:
Given that at:
the background_callback is kicked off with the ‘context’ object available.
This suggests a relatively painless feature update that would require an architect green light: pass the then-contemporary request object into the background_callback because it’s reasonable given the abstraction that a background_callback is aiming to be, e.g. as though it were just a regular callback that doesn’t hog app server threads.
@benn0 I did not make much progress on this actually. At the moment I am using a dcc.Store to pass the current username to the background callback but this is not secure.
@jkunstle seems like a reasonable request and I think this would be quite useful for implementing either checks that a user is allowed to invoke the background callback but also having user or user group specific actions. Maybe we should raise an issue on GitHub?
I finally got around to trying this and while it seems to work with Disk Cache, I cant seem to get it to work with celery at all. I tried passing both the request and the app context in the callback function but neither of them work. I still get operating outside the request context when trying to access the request. Will post back if I find anything useful.
Yep I passed request=flask.request and then tried to print(request). Got the error complaining about being out of the request context. I suspect my celery workers do not have either the app or request context but despite my googling I haven’t figured out a solution yet. I reverted to using diskcache for the moment.
Will stay on it, but any suggestions are most appreciated.