Flask-socketio: Must all events be in one file?

Created on 8 Oct 2017  路  7Comments  路  Source: miguelgrinberg/Flask-SocketIO

Hi, I have the following structure:

socketservice.py:

from flask import Flask, render_template
from flask_socketio import SocketIO, emit
from backend.database import db

app = Flask(__name__)
socketio = SocketIO(app, engineio_logger=True)

@socketio.on('connect')
def handle_connection():
    from backend.electionAdministration import syncElections
    syncElections()

if __name__ == '__main__':
    socketio.run(app)

electionAdministration.py:

from flask_socketio import SocketIO, emit
from bson.json_util import dumps
from backend.socketservice import socketio
from backend.database import db

def syncElections():
    elections = db.elections.find()
    emit('syncElections',dumps(res) , broadcast=True)

@socketio.on('createElection')
def createElection(data):
    db.elections.insert({'title': data["title"]})
    syncElections()

The problem is, that the createElection event is never being called, when it is within the file electionAdministration.py. When I move it into socketservice.py, it suddenly works.

Does that mean all events must be in the same file that created the socketio instance?

question

Most helpful comment

Yes, that is a pretty common issue. You need to add the import electionAdministration after the place where the socketio instance is created. You can put it right above the if __name__ == '__main__' for example.

All 7 comments

You can have the events on any modules, but make sure all modules that have Socket.IO events are imported, because any modules that are not imported will not registered their events with the framework.

Hmmm, for some reason I don't succeed...when I import createElection in socketservice.py and at the same time from backend.socketservice import socketio for the annotation, I have a circular import.

Do you see what I'm doing wrong?

Yes, that is a pretty common issue. You need to add the import electionAdministration after the place where the socketio instance is created. You can put it right above the if __name__ == '__main__' for example.

Thank you!

I first thought it has been working; however, I might have ended up forgetting to delete the event in the main file. With the following code, the event is still not being called:

main.py:

from flask import Flask, render_template
from flask_socketio import SocketIO, emit

app = Flask(__name__)
socketio = SocketIO(app, engineio_logger=True)

import secondfile

if __name__ == '__main__':
    socketio.run(app)

secondfile.py:

from main import socketio

@socketio.on('test')
def test(data):
    print("HELLO")

when I emit a test message, it is shown in the console, however, the function test is never called. If I move it into the main.py, it works.

That's another common issue. The main.py module is not going to be named main. In Python, the main module is always named __main__, regardless of the name of the file. When you do from main import ... you are effectively importing a second copy of the module. If you change the import in the second file to the following, everything will work:

from __main__ import socketio

Thank you!

Was this page helpful?
0 / 5 - 0 ratings