pyinstaller 打包发布flask 应用
安装
pip install pyinstaller
入口程序,启动程序:app.py
from flask import Flaskapp = Flask(__name__)@app.route('/')
def hello_world():return 'Hello, World!'if __name__ == '__main__':app.run()
1 打包成一个二进制文件,没有静态文件和模板
pyinstaller --onefile app.py
PyInstaller 会在 dist 目录下生成一个 app 文件,直接运行
2 打包成一个软件包dist,有静态文件和模板
flaskr 文件夹下的结构:
- instance 实例数据库
- static 静态文件
- templates 模版
- uploads 上传的文件夹
flaskr/
├── a.py
├── b.py
├── c.py
├── __init__.py
├── instance
│ └── a.sqlite
├── tt
│ ├── xxx.py
├── schema.sql
├── static
│ ├── 1.css
│ ├── 2.css
│ ├── 3.css
│ ├── editormd
│ ├── images
│ │ ├── 1.jpg
│ │ ├── 2.png
│ │ ├── 3.jpg
│ │ ├── 4.jpg
│ │ └── 5.jpg
│ ├── index.css
│ └── style.css
├── templates
│ ├── a
│ │ ├── 1.html
│ │ └── 2.html
│ ├── b.html
│ └── c
│ ├── 1.html
│ ├── 2.html
│ ├── 3.html
│ ├── 4.html
│ ├── 5.html
│ └── 6.html
├── upload.py
└── uploads├── txt2img-20240828-175415-0.png├── txt2img-20240828-211041-0.png├── txt2img-20240828-213517-0.png
目录
/proj/flaskr/
/proj/run.py
入口文件 run.py
from flaskr import create_appapp = create_app()if __name__ == '__main__':app.run(debug=True)
打包:
1 配置路径:create_app 入口函数配置路径:
修改 flaskr/init.py :
import os
import sys
from flask import Flask# 指定 basedir
if getattr(sys, 'frozen', False): # 检查是否在打包后的环境中运行exedir = os.path.dirname(sys.executable)basedir = os.path.join(exedir,'_internal','flaskr')
else:basedir = os.path.abspath(os.path.dirname(__file__))def create_app(test_config=None):"""Create and configure an instance of the Flask application."""app = Flask(__name__, instance_relative_config=True)app.config.from_mapping(# a default secret that should be overridden by instance configSECRET_KEY="dev",DATABASE=os.path.join(basedir,'instance', "flaskr.sqlite"),UPLOAD_FOLDER=os.path.join(basedir, 'uploads'), TEMPLATE_FOLDER=os.path.join(basedir, 'templates'),STATIC_FOLDER=os.path.join(basedir, 'static'),)# 省略其它代码return app
2 生成 run.spec
pyinstaller --specpath=. run.py
3 修改run.spec 添加以下内容,把静态文件和模板文件打包进去
datas=[('flaskr/static', 'flaskr/static'),('flaskr/templates', 'flaskr/templates'),('flaskr/instance', 'flaskr/instance'),('flaskr/uploads', 'flaskr/uploads'),],
修改后完整的run.spec :
# -*- mode: python ; coding: utf-8 -*-a = Analysis(['run.py'],pathex=[],binaries=[],datas=[('flaskr/static', 'flaskr/static'),('flaskr/templates', 'flaskr/templates'),('flaskr/instance', 'flaskr/instance'),('flaskr/uploads', 'flaskr/uploads'),],hiddenimports=[],hookspath=[],hooksconfig={},runtime_hooks=[],excludes=[],noarchive=False,optimize=0,
)
pyz = PYZ(a.pure)exe = EXE(pyz,a.scripts,[],exclude_binaries=True,name='run',debug=False,bootloader_ignore_signals=False,strip=False,upx=True,console=True,disable_windowed_traceback=False,argv_emulation=False,target_arch=None,codesign_identity=None,entitlements_file=None,
)
coll = COLLECT(exe,a.binaries,a.datas,strip=False,upx=True,upx_exclude=[],name='run',
)
4 生成软件包 dist
pyinstaller run.spec
5 生成的dist目录结构
dist/run/run
dist/run/_internal/flaskr/├── instance│ └── a.sqlite├── static│ ├── 1.css│ ├── 2.css│ ├── 3.css│ ├── editormd│ ├── images│ │ ├── 1.jpg│ │ ├── 2.png│ │ ├── 3.jpg│ │ ├── 4.jpg│ │ └── 5.jpg│ ├── index.css│ └── style.css├── templates│ ├── a│ │ ├── 1.html│ │ └── 2.html│ ├── b.html│ └── c│ ├── 1.html│ ├── 2.html│ ├── 3.html│ ├── 4.html│ ├── 5.html│ └── 6.html├── upload.py└── uploads├── txt2img-20240828-175415-0.png├── txt2img-20240828-211041-0.png├── txt2img-20240828-213517-0.png
直接运行
dist/run/run