redis Celery和Pyinstaller

vu8f3i0k  于 7个月前  发布在  Redis
关注(0)|答案(2)|浏览(96)

我想有一个celery 工人(与Redis作为经纪人和后端),将接收来自几个远程celery 生产者的任务(通过使用“.send_task”)。
我尝试用pyinstaller将生产者端打包成一个 *.exe文件。这个想法是运行 *.exe文件,它将向远程Celery worker发送一个任务。
下面是“producer”代码:

from celery import Celery

def main():
    print('Sending Task')
    #celery_app.send_task('add',args=(2,2))
    celery=Celery('redis://:password@redis_server:6379')
    celery.send_task('tasks.add',(2,2))

if __name__=="__main__":
    main()

字符串
然后我用pyinstaller将代码编译成一个文件。不幸的是,当我试图运行可执行文件时,我遇到了一个异常。我得到了以下错误:

Sending Task
Traceback (most recent call last):
  File "sendtask.py", line 11, in <module>
  File "sendtask.py", line 6, in main
  File "celery\app\base.py", line 291, in __init__
  File "celery\app\base.py", line 291, in <listcomp>
  File "kombu\utils\imports.py", line 56, in symbol_by_name
  File "importlib\__init__.py", line 127, in import_module
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 961, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 973, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'celery.fixups'
[5588] Failed to execute script 'sendtask' due to unhandled exception!

  • Python v.3.8.10-64
  • Pyinstaller v. 4.5.1

有人知道是否有可能将Python脚本编译成可执行文件,将任务发送给远程Celery工人吗?
任何帮助将不胜感激
谢谢何塞

dojqjjoe

dojqjjoe1#

我在pyinstaller==4.8,celery==5.2.3和python 3.9.7中遇到了同样的问题。
在我的项目中,我通过在pyinstaller命令行上添加显式hidden-import需求来解决。

pyinstaller.exe --hidden-import celery.fixups --hidden-import celery.fixups.django myprogram.py

字符串
我猜这是由于Pyinstaller不正确的依赖分析,在使用此类工具部署项目时,手动显式某些deps似乎很常见。

yjghlzjz

yjghlzjz2#

我也遇到过这个问题,但是当我用Pyrocode编译celery worker文件时,这个问题就复杂多了。
它不工作,即使我把一些celery 子模块的--hidden-import选项。
最后,我发现这些子模块必须显式地导入到主文件中,所以Python知道要收集哪些模块。

我使用的版本

Python:v4.2
Python:3.9.8

celery_worker.py

from celery import Celery

# PyInstaller friendly imports --start--
import celery.app.amqp
import celery.app.log
import celery.worker.autoscale
import celery.worker.components
import celery.bin
import celery.utils
import celery.utils.dispatch
import celery.contrib.testing
import celery.utils.static
import celery.concurrency.prefork
import celery.app.events
import celery.events.state
import celery.app.control
import celery.backends.redis
import celery.backends
import celery.backends.database
import celery.worker
import celery.worker.consumer
import celery.app
import celery.loaders
import celery.security
import celery.fixups
import celery.concurrency
import celery.events
import celery.contrib
import celery.apps
import celery
import celery.fixups
import celery.fixups.django
import celery.apps.worker
import celery.worker.strategy
import kombu.transport.redis
import sqlalchemy.sql.default_comparator               
import sqlalchemy.ext.baked
# PyInstaller friendly imports --end--

def init_celery_app():
    celery_app = Celery(
        "my-celery-app",
        broker="redis://localhost:6379",
        result_backend="redis://localhost:6379",
    )

    return celery_app

celery_app = init_celery_app()

if __name__ == "__main__":
    celery_app.worker_main(
        argv=[
            "worker",
            "--loglevel=info",
            "--queues=my_queue",
        ]
    )

字符串

Python编译命令

我必须排除djangotkinter,否则构建会失败。
以下是我使用的命令:用途:

/pyinstaller/pyinstaller.sh -F \
    --exclude-module=tkinter \
    --exclude-module=django \
    celery_worker.py

相关问题