使用Pyinstaller把FastAPI项目(PaddleOcr文字识别)打包成exe文件遇坑汇总

本人所用的环境为win11
python3.7

在打包过程中遇到了很多坑,现在把遇到的一些问题总结一下。

首先确保代码在本地虚拟环境中能够成功运行。

基本步骤

一、下载安装pyinstaller

pip install pyinstaller -i https://pypi.tuna.tsinghua.edu.cn/simple/

二、修改项目运行参数,即reload改为False

uvicorn.run("main:app", host='127.0.0.1', port=8000, reload=False)

三、生成可执行文件(-F 打包单个文件,我觉得太慢了而且不方便测试故使用-D)

pyinstaller -D main.py
首先第一步运行pyinstaller -D xxx.py 打包完成后运行会遇到第一个问题

未截图 用了他人的截图

在这里插入图片描述

这个问题的解决方案是因为setuptools工具版本太高重新安装58.0.0版本可以解决此问题

pip install setuptools==58.0.0

Tips: 不要双击启动main.exe 否则控制台一闪而过不方便调试。使用CMD命令启动 main 并将输出打印到控制台

main.exe | more
问题二:

提示:

FileNotFoundError: [WinError 2] 系统找不到指定的文件。: ‘D:\PaddleOCR\dist\checknum\paddle\fluid\…\libs’

解决办法:将你所在虚拟环境下的libs文件拷贝到与fluid同级目录下

我的目录为:E:\Anaconda_exe\setup\envs\PdFast\Lib\site-packages\paddle\libs

问题三
# No module named 'framework_pb2'

解决办法:将在你环境中的Lib下的site-packages下面的paddle中fluid中的proto拷贝到你打包好的文件目录下面的paddle中的fliud中

...\venv\Lib\site-packages\paddle\fluid\proto
放到
...\dist\imgGrab\paddle\fluid中即可
问题四
ModuleNotFoundError: No module named 'ppocr'

或者是

在这里插入图片描述
关于 No module named xxx 这个问题 ,比如你有一些模型model或者静态文件static之类的东西 如果不想打包好在拷贝相应文件的话,也可以在main.spec文件中datas修改,这个datas的作用是将本地文件打包时拷贝到目标路径下。
datas是一个元素为元组的列表,每个元组有两个元素,都必须是字符串类型,元组的第一个元素为数据文件或文件夹,元组的第二个元素为运行时这些文件或文件夹的位置。例如:datas=[(’./src/a.txt’, ‘./dst’)],表示打包时将"./src/a.txt"文件添加(copy)到相对于exe目录下的dst目录中。也可以使用通配符:datas= [ (’/mygame/sfx/*.mp3’, ‘sfx’ ) ],表示将/mygame/sfx/目录下的所有.mp3文件都copy到sfx文件夹中。也可以添加整个文件夹:datas= [ (’/mygame/data’, ‘data’ ) ],表示将/mygame/data文件夹下所有的文件都copy到data文件夹下。同命令“–add-data”。
例如 刚才所说的ppocr还有我项目中的用到的一些static 可以这样定义:


datas=[('E:\\Ocr_script\\venv\\Lib\\site-packages\\pyzbar','pyzbar'),('E:\\Ocr_script\\venv\\Lib\\site-packages\\paddleocr\\ppocr','ppocr'),('E:\\Ocr_script\\static','static')]

这样写将会在exe的同级目录下将创建你自己定义的文件夹

问题五

在这里插入图片描述

解决方法:

在生成的main.spec文件hiddenimports中添加

hiddenimports=['framework_pb2','scipy.special.cython_special','skimage','skimage.feature._orb_descriptor_positions','skimage.filters.edges']

使用-y命令重新打包

pyinstaller -y main.spec
问题六

img

解决办法:这个在生成的spec文件中的pathex中添加,记得路径换成自己的环境路径

我自己的文件为:

a = Analysis(
    ['main.py'],
    pathex=['E:\\Anaconda_exe\\setup\\envs\\PdFast\\Lib\\site-packages\\paddleocr','E:\\Anaconda_exe\\setup\\envs\\PdFast\\Lib\\site-packages\\paddle\\libs'],
    binaries=[('E:\\Anaconda_exe\\setup\\envs\\PdFast\\Lib\\site-packages\\paddle\\libs','.')],
    datas=[],
    hiddenimports=['framework_pb2','scipy.special.cython_special','skimage','skimage.feature._orb_descriptor_positions','skimage.filters.edges'],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)

同理 修改之后再用 - y 打包 重复一遍 ~ (真坑)

问题七

运行main.exe后出现

Error loading ASGI app. Could not import module "main".

解决方法:把项目的main.py文件放进main.exe同级目录下就可以了

问题八 (很重要)

启动的时候终于没有报错了,然鹅一直卡死在控制台不动 有几次甚至把电脑卡重启!!!排查了半天后发现运行exe时电脑会有10多个 main.exe 进程,电脑内存占用直接90%+

解决办法:关闭多进程! 找到所在环境下的 image.py 文件,把一部分代码注释掉

我的目录是 “D:\virtualenv\Pdocr\Lib\site-packages\paddle\dataset\image.py”

修改代码如下:

# if six.PY3:
#     import subprocess
#     import sys
#     import_cv2_proc = subprocess.Popen(
#         [sys.executable, "-c", "import cv2"],
#         stdout=subprocess.PIPE,
#         stderr=subprocess.PIPE)
#     out, err = import_cv2_proc.communicate()
#     retcode = import_cv2_proc.poll()
#     if retcode != 0:
#         cv2 = None
#     else:
#         import cv2
# else:
#     try:
#         import cv2
#     except ImportError:
#         cv2 = None
try:
    import cv2
except ImportError:
    cv2 = None
import os

得~ 又得重新打包一次

最后 终终终于成功了!

欢迎大家把遇到得问题进行补充,我也会持续跟进 避免更多的老铁踩坑~

你可能感兴趣的:(一些工具和参考用法,fastapi,python,开发语言,paddle)