python-socketio: Invalid async_mode specified

hello! Everything was OK when I run my python file, but it raised error run after be packed with pyinstaller:

Traceback (most recent call last):

  File "ems\core\task.py", line 67, in add
  File "ems\ems_socket_service.py", line 26, in __init__
  File "site-packages\socketio\server.py", line 72, in __init__
  File "site-packages\engineio\server.py", line 100, in __init__
ValueError: Invalid async_mode specified

the code :self.socketio = socketio.Server(async_mode='gevent')

I tried self.socketio = socketio.Server(), it’s also useless, and i have installed gevent.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 8
  • Comments: 45 (9 by maintainers)

Commits related to this issue

Most upvoted comments

just importing gevent from engineio.async_drivers worked for me.

from engineio.async_drivers import gevent

It works!!! I add ‘engineio.async_gevent’ to hiddenimports in spec file. very, very grateful for your help!! lol hahahahaha

I use eventlet. None of the above solved my problem. Finally I got it run by these 3 steps:

Modify app.spec file:

hiddenimports=['engineio.async_drivers.eventlet'],

Modify app.py file

Add these lines at file head, it’s useless to the python file, but it’s necessary for pyinstaller packing.

from eventlet.hubs import epolls, kqueue, selects
from dns import dnssec, e164, hash, namedict, tsigkeyring, update, version, zone

Running pyinstaller

pyinstaller app.spec

Do NOT run pyinstaller app.py, it will overwrite app.spec.

@Popkultur You need to ensure engineio.async_eventlet is included in the installer package.

@miguelgrinberg Perfect. All I had to do was add from engineio import async_threading to the top of my script file to trick PyInstaller into pulling it, and that did the trick. Thanks so much!

It appears you now need

‘engineio.async_drivers.eventlet’ not ‘engineio.async_eventlet’

in hidden imports using the below version:

python-engineio 3.3.0 python-socketio 3.1.2 eventlet 0.24.1

Right! If you have to use multi-threading mode like me, you can add line as below and pyinstall it:

from engineio.async_drivers import threading

and also force it to use threading mode when create it:

        socketio = SocketIO(
            app,
            async_mode="threading"
        )

@crobertsbmw make sure the engineio/async_threading.py module is also imported, so that pyinstaller pulls it, along with all of its dependencies.

Maybe the solution is just as simple as importing that module like this: from engineio.async_drivers import gevent

https://stackoverflow.com/a/55642042/8667243

pip install eventlet did the trick for me

I couldn’t get around all the errors with eventlet & PyInstaller, so I uninstalled eventlet, and am trying to use the async_mode="threading". I also put import threading in my main script file. When I try to run after pyinstaller--onefile socket_app.py, I get a Invalid async_mode specified error. This comes from \site-packages\engineio\server.py __init__ method. I’m baffled. Any ideas?

Right! If you have to use multi-threading mode like me, you can add line as below and pyinstall it:

from engineio.async_drivers import threading

and also force it to use threading mode when create it:

        socketio = SocketIO(
            app,
            async_mode="threading"
        )

This solved my issue, thanks!!!

just importing gevent from engineio.async_drivers worked for me.

from engineio.async_drivers import gevent

Thank you very much !!!

I solved this issue by copy whole “engineio” directory to my dist/app/“engineio” For example, copy your {{python installl dir}}/Lib/site-packages/engineio to /dist/{{your app}}/engineio. then run your app

I’m still struggling with this. I’m using the following command:

python -m PyInstaller -F signage.py --hidden-import=engineio.async_drivers.eventlet

My versions:

eventlet==0.24.1
PyInstaller==3.4
python-engineio==3.4.3
python-socketio==3.1.2

Error result:

Traceback (most recent call last):
  File "W:\Source\Sign\signage.py", line 21, in <module>
    socketio = SocketIO(app)
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\site-packages\flask_socketio\__init__.py", line 163, in __init__
    self.init_app(app, **kwargs)
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\site-packages\flask_socketio\__init__.py", line 221, in init_app
    self.server = socketio.Server(**self.server_options)
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\site-packages\socketio\server.py", line 89, in __init__
    self.eio = self._engineio_server_class()(**engineio_options)
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\site-packages\engineio\server.py", line 129, in __init__
    raise ValueError('Invalid async_mode specified')
ValueError: Invalid async_mode specified
[4936] Failed to execute script signage

I did not investigate this particular issue any further because I switched to using an alternate library supported by flask-socketio which worked for me with pyinstaller (gevent). However I can point you towards a solution

The key for pyinstaller support is to avoid this -> os.path.dirname(__file__) as __file__ is not defined in the expected way in a “bundled” environment. You need to do a run-time check for if you are in a bundled environment and go from there. The relevant info that should allow a good fix is in this section of the pyinstaller docs.

http://pyinstaller.readthedocs.io/en/stable/runtime-information.html

It may just be that when in a “bundled” environment (sys.frozen exists) just a different path evaluation to the eventlet.support.dns module is needed (based off sys._MEIPASS and not __file__) and the sys.path temporary modification is still usable

Hope this helps