Hi @miguelgrinberg!
Firstly, congratulations for Flask SocketIO.
I have followed the example in https://github.com/miguelgrinberg/Flask-SocketIO/blob/master/example/app.py and it runs ok but I need to access to my database inside the background task and I don't know how to achieve it.
This is the connect event:
@socketio.on('connect', namespace='/rt/notifications/')
def start_notifications_thread():
logger.info('entra a start')
global thread
with thread_lock:
if thread is None:
thread = socketio.start_background_task(target=notifications_job)
And this the "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
If I execute the previous code then I receive the next error message:
"No application found. Either work inside a view function or push"
I think I have found a solution. Simply, I have created an instance of my app inside the notifications_job method and pushed the application context:
def notifications_job():
last_alert_id = None
settings_module = os.getenv('FLASK_SETTINGS_MODULE')
app = create_app(settings_module)
while True:
with app.app_context():
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
Is this the best approach?
Yes, this is actually the correct approach. You can consider swapping the while and the with, so that a single application context is used, instead of a new one for each while loop iteration, but other than that this looks good.
OK! Thank you very much :-)
The correct answer:
def notifications_job():
last_alert_id = None
settings_module = os.getenv('FLASK_SETTINGS_MODULE')
app = create_app(settings_module)
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
Most helpful comment
OK! Thank you very much :-)
The correct answer: