'"ValueError: Invalid async_mode specified" when bundling a Flask app using cx_Freeze

I am building an API that uses Waitress, Flask, and Flask_SocketIO in Windows. Everything works fine from the command line, but when I try to bundle my API into an .exe using cx_Freeze and then run it, I get the error:

ValueError: Invalid async_mode specified

The only thing I've been able to find about this issue is a python-socketio github thread. There are a ton of good suggestions in that thread to try in order to fix this issue, but I've tried each and every thing but still have the same result.

I suspect I have a missing module, but I have no idea how to find out specifically which module is missing. Does anyone have any suggestions of things to try? Even if it doesn't directly fix my problem, knowing how to drill into the stack trace to find the missing module would be helpful.



Solution 1:[1]

This troubled me a lot while using pyInstaller. I tried adding many different modules to hidden imports, but realized later that you just need to mention below in your py file:

from engineio.async_drivers import gevent

Hope this works for cx_Freeze as well.

Solution 2:[2]

EDIT:

Try to add engineio, socketio, flask_socketio, threading, time, queue to the packages list of the build_exe options passed to the setup call in your setup script:

...

packages = []  # Add here the list of packages you have already included
packages += ['engineio', 'socketio', 'flask_socketio', 'threading', 'time', 'queue']

...

setup(...,
      options={'build_exe': {...,
                             'packages'=packages}})

As posted by espretto in the thread you linked:

apparently engineio uses the importlib module to dynamically import whichever module corresponds to the chosen async_mode

cx_Freeze does not interpret this code and thus does not know that sub-modules of engineio need to be included, you need to tell it.

engineio.async_drivers.threading imports threading, time and queue, but cx_Freeze probably won't see that because engineio.async_drivers.threading is imported dynamically.

If queue does not work, replace by Queue.

You might still need to add further packages to the packages list, such as eventlet, gevent, uwsgi, six, urllib3, ...

Please post the full stack trace of the error message you get. Seeing where the error happens and looking into the source code of engineio might help to find the missing package.

Solution 3:[3]

For eventlet install it first using:

pip install eventlet

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 jpeg
Solution 2
Solution 3 PSN