pyinstaller打包Flask项目

pyinstaller打包Flask项目踩坑实记

    • 环境
    • pyinstaller打包
    • Flask项目的改造
    • 打包后无法运行的问题

环境

Flask + socketio + pyinstaller

pip freeze
altgraph==0.16.1
cffi==1.11.5
chardet==3.0.4
click==6.7
Flask==1.0.2
Flask-Cors==3.0.6
Flask-SocketIO==3.0.2
Flask-Sockets==0.2.1
future==0.17.1
gevent==1.3.7
gevent-websocket==0.10.1
greenlet==0.4.15
ice==0.0.2
itsdangerous==0.24
Jinja2==2.10
macholib==1.11
MarkupSafe==1.0
pefile==2018.8.8
Pillow==5.2.0
py2exe==0.9.2.2
pycparser==2.19
PyInstaller==3.4
pyserial==3.4
python-engineio==2.3.2
python-socketio==2.0.0
pywin32==224
pywin32-ctypes==0.2.0
simplejson==3.16.0
six==1.11.0
urllib3==1.24.1
Werkzeug==0.14.1
xlrd==1.1.0
xlwt==1.3.0
zeroc-ice==3.7.1

pyinstaller打包

pyinstaller的安装,打包等操作在此不再详细介绍。网上相关介绍已经很多,例如:
https://www.jb51.net/article/137497.htm

简要步骤如下:

#安装pyinstaller
pip install pyinstaller

#安装pywin32
pip install pywin32

#项目打包
进入项目入口文件夹
pyinstaller run.py

Flask项目的改造

我的Flask项目采用的是Flask官方文档示例的形式。采用__init__.py文件作为入口,整个项目作为一个pyServer模块使用。在使用pyinstaller打包时无法打包模块,所以需要将__init__.py文件进行改造,制作可以独立运行的项目入口,所以我制作了run.py文件。大致如下(业务相关代码没有贴进来)

from flask import Flask
app = Flask(__name__, static_folder='webApp', static_url_path='', instance_relative_config=True)
socketio = SocketIO(app, async_mode='gevent')
if __name__ == '__main__':
    socketio.run(app)

如此改造之后,有很多相关模块的import会出现问题,全部手工处理了一遍,之后终于能打包啦~

打包后无法运行的问题

项目打包后生成exe文件,执行时发生如下报错
Invalid async_mode specified
解决方案如下链接:
https://github.com/miguelgrinberg/python-socketio/issues/35

保证有这样一行关键代码,指定了async_mode

socketio = SocketIO(app, async_mode='gevent')

检查并修改自己的spec文件,关键在hiddenimports部分

hiddenimports=['gevent', 'geventwebsocket', 'gevent.ssl', 'gevent.builtins', 'engineio.async_gevent']

重新生成exe文件,可以正确启动项目啦~

你可能感兴趣的:(Python,Flask)