3

I am developing a Flask application with Flask-SocketIO library to real time communication between a server background task and clients.

I need to access to my database inside the background task and I don't know how to achieve it as no application context is initialized.

My code is:

@socketio.on('connect', namespace='/rt/notifications/')
def start_notifications_thread():
    global thread
    with thread_lock:
        if thread is None:
            thread = socketio.start_background_task(target=notifications_job)

def notifications_job():
    last_alert_id = None
    while True:
        socketio.sleep(60)
        last_id = Alert.get_last_alert_id()  # Flask-SQLAlchemy model
        if last_alert_id is not None and last_id != last_alert_id:
            socketio.emit('new_alerts', {'msg': 'New alert', 'id': last_id}, namespace='/rt/notifications/')
        last_alert_id = last_id
j2logo
  • 649
  • 4
  • 9

1 Answers1

5

According to flask-socketio's author, miguelgrinberg, the following is the correct approach. Simply, I have to pass an instance of my app to notifications_job method as following:

from threading import Lock

from flask import current_app

from .. import socketio

thread = None
thread_lock = Lock()

def notifications_job(app):
    last_alert_id = None
    with app.app_context():
        while True:
            socketio.sleep(60)
            last_id = Alert.get_last_alert_id()  # Flask-SQLAlchemy   model
            if last_alert_id is not None and last_id != last_alert_id:
                socketio.emit('new_alerts', {'msg': 'New alert', 'id': last_id}, namespace='/rt/notifications/')
            last_alert_id = last_id

@socketio.on('connect', namespace='/rt/notifications/')
def start_notifications_thread():
    global thread
    with thread_lock:
        if thread is None:
            thread = socketio.start_background_task(notifications_job, current_app._get_current_object())
j2logo
  • 649
  • 4
  • 9