运行 celery worker 使用 pyinstaller 编译 python 模块

Run celery worker with a compiled python module compiled using pyinstaller

我有一个简单的芹菜模块 (worker.py),看起来像:

from celery import Celery

app = Celery('celery')

@app.task(bind=True)
def some_task(self):
    print('HELLO WORLD')

我正在使用 pyinstaller:

编译模块
python3 -m PyInstaller --onefile worker.py

然后,我可以 运行 使用 python 模块的 celery worker 很容易地使用命令:

celery -A worker.app worker -l info

我的问题是: 我怎样才能 运行 使用编译版本的模块(由 PyInstaller 创建)的 celery worker?

我不认为这是可能的(但如果是的话请纠正我)。

首先,pyinstaller 生成一个可执行文件,因此来自 pyinstaller 输出的文件是一个硬编码的 bin,可以 运行 完美地没有解释器、依赖项等。

来自pypi

PyInstaller bundles a Python application and all its dependencies into a single package. The user can run the packaged app without installing a Python interpreter or any modules.

Celery 需要使用 python 解释器来 运行 python 代码,即 Celery 是一个简单的库,它被导入并与现有 python 代码集成到 运行 文件中。因此,用 pyinstaller 编译的可执行文件在这种情况下不应该工作。

这个问题的解决方案是从 python 模块中 运行 工人,例如:

from celery import Celery

app = Celery('celery', fixups=[])

@app.task(bind=True)
def some_task(self):
    print('HELLO WORLD')

if __name__ == "__main__":
    app.worker_main(argv=['worker', '--loglevel=info'])

然后我们就可以使用pyinstaller来编译这个模块了:

pyinstaller --one-file module.py --additional-hooks-dir=pyinstaller_hooks_folder

additional-hooks-dir标志是让pyinstaller知道如何收集celery的子模块等。我们需要在我们的项目文件夹中有pyinstaller_hooks_folder和一个celery hook文件:

Project_folder
└── pyinstaller_hooks_folder
    └──hook-celery.py 

hook-celery.py 文件:

from PyInstaller.utils.hooks import collect_all

datas, binaries, hiddenimports = collect_all('celery')