pyinstaller 打包发布flask 应用
安装
bash
pip install pyinstaller
入口程序,启动程序:app.py
python
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == '__main__':
app.run()
1 打包成一个二进制文件,没有静态文件和模板
bash
pyinstaller --onefile app.py
PyInstaller 会在 dist 目录下生成一个 app 文件,直接运行
2 打包成一个软件包dist,有静态文件和模板
flaskr 文件夹下的结构:
-
instance 实例数据库
-
static 静态文件
-
templates 模版
-
uploads 上传的文件夹
bash
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
目录
bash
/proj/flaskr/
/proj/run.py
入口文件 run.py
bash
from flaskr import create_app
app = create_app()
if __name__ == '__main__':
app.run(debug=True)
打包:
1 配置路径:create_app 入口函数配置路径:
修改 flaskr/init.py :
python
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 config
SECRET_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
bash
pyinstaller --specpath=. run.py
3 修改run.spec 添加以下内容,把静态文件和模板文件打包进去
bash
datas=[
('flaskr/static', 'flaskr/static'),
('flaskr/templates', 'flaskr/templates'),
('flaskr/instance', 'flaskr/instance'),
('flaskr/uploads', 'flaskr/uploads'),
],
修改后完整的run.spec :
bash
# -*- 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
bash
pyinstaller run.spec
5 生成的dist目录结构
bash
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
直接运行
bash
dist/run/run