Search code examples
flaskpython-3.8flask-socketioflask-session

Flask-SocketIO access session from background task


I have a Flask app for http and web socket (Flask-SocketIO) communication between client and server using gevent. I also use server side session with Flask-Session extension for the app. I run a background task using SocketIO.start_background_task. And from this task, I need to access session information which will be used to emit message using socketio. I get error when accessing session from the task "RuntimeError: Working outside of request context." This typically means that you attempted to use functionality that needed an active HTTP request.

Socket IO instance is created as below- socket_io = SocketIO(app, async_mode='gevent', manage_session=False)

Is there any issue with this usage. How this issue could be addressed?

Thanks


Solution

  • This is not related to Flask-SocketIO, but to Flask. The background task that you started does not have request and application contexts, so it does not have access to the session (it doesn't even know who the client is).

    Flask provides the copy_current_request_context decorator duplicate the request/app contexts from the request handler into a background task.

    The example from the Flask documentation uses gevent.spawn() to start the task, but this would be the same for a task started with start_background_task().

    import gevent
    from flask import copy_current_request_context
    
    @app.route('/')
    def index():
        @copy_current_request_context
        def do_some_work():
            # do some work here, it can access flask.request or
            # flask.session like you would otherwise in the view function.
            ...
        gevent.spawn(do_some_work)
        return 'Regular response'