使用cx_Freeze打包Flask应用时出现"ValueError: Invalid async_mode specified"错误。

5

我正在构建一个使用Waitress、Flask和Flask_SocketIO的API,运行环境是Windows。在命令行中一切正常,但当我尝试使用cx_Freeze将我的API打包成.exe文件并运行时,出现以下错误:

ValueError: Invalid async_mode specified

我所能找到的关于这个问题的唯一信息是一个python-socketio的Github帖子。在那个帖子中有很多好的建议可以尝试来解决这个问题,但我已经尝试了每一件事情,但仍然有同样的结果。
我怀疑我缺少一个模块,但我不知道如何具体找出缺少哪个模块。有人有什么建议吗?即使它不能直接解决我的问题,知道如何深入堆栈跟踪以找到缺少的模块也会很有帮助。

你包含了哪些模块? - Miguel Grinberg
sys,datetime,flask,flask_socketio,jwt,ConfigParser,pyodbc和uuid - Brian
1
这不是问题,你需要导入python-engineio包的特定子模块才能使其正常工作。在你提供的帖子中评论的人解释了他们所做的事情以使其正常工作。 - Miguel Grinberg
我刚刚回顾了一下那个线程,并尝试了几种不同的async_modes,包括将它们各自的模块包含到cx_freeze包中,但仍然得到相同的错误。 - Brian
异步模块的位置已经改变,您是否将导入名称调整为当前位置? - Miguel Grinberg
3个回答

7
在使用pyInstaller时,这个问题一直困扰着我。我尝试了很多不同的模块来隐藏导入,但后来发现你只需要在你的py文件中添加以下内容即可:
from engineio.async_drivers import gevent

希望这也适用于cx_Freeze。

3

编辑:

尝试将 engineiosocketioflask_socketiothreadingtimequeue 添加到你的设置脚本中传递给 setup 调用的 build_exe 选项packages 列表中:

...

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}})

如espretto在你提供的帖子中所述:

显然,engineio使用importlib模块根据所选择的async_mode动态导入相应的模块。

cx_Freeze不解释这段代码,因此不知道需要包含engineio的子模块,您需要告诉它。

engineio.async_drivers.threading导入threadingtimequeue,但是cx_Freeze可能看不到,因为engineio.async_drivers.threading是动态导入的。

如果queue不起作用,请替换为Queue

您可能仍然需要将进一步的软件包添加到packages列表中,例如eventletgeventuwsgisixurllib3等。

请发布您收到的错误消息的完整堆栈跟踪。查看错误发生的地方并查看engineio的源代码可能有助于找到缺失的软件包。


我尝试将async_mode显式设置为“threading”,并导入async_threading,但仍然出现相同的错误。 - Brian
@Brian,你尝试将 engineio 及其余 socketioflask_socketio 添加到设置脚本的 packages 列表中吗?你还是得到同样的错误吗?至少 engineio 进行了一些动态导入,这可能不被 cx_Freeze 所识别,仅导入 async_threading 可能不足够。 - jpeg
@brian 我已经编辑了我的答案并提出了进一步的建议。 - jpeg

2

要安装Eventlet,请先使用以下命令:

pip install eventlet


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接