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?
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!
Most helpful comment
Yes, that is a pretty common issue. You need to add the
import electionAdministrationafter the place where thesocketioinstance is created. You can put it right above theif __name__ == '__main__'for example.