RuntimeError: "list" должен быть None или list, а не <class 'str'> при попытке запустить работника сельдерея

Я пытаюсь добавить задачу сельдерея, следуя Первые шаги с Django, но я получаю следующую ошибку:

Traceback (most recent call last):
  File "/Users/amrullahzunzunia/virtualenvs/flyrobe_new/bin/celery", line 11, in <module>
    sys.exit(main())
  File "/Users/amrullahzunzunia/virtualenvs/flyrobe_new/lib/python3.5/site-packages/celery/__main__.py", line 30, in main
    main()
  File "/Users/amrullahzunzunia/virtualenvs/flyrobe_new/lib/python3.5/site-packages/celery/bin/celery.py", line 81, in main
    cmd.execute_from_commandline(argv)
  File "/Users/amrullahzunzunia/virtualenvs/flyrobe_new/lib/python3.5/site-packages/celery/bin/celery.py", line 770, in execute_from_commandline
    super(CeleryCommand, self).execute_from_commandline(argv)))
  File "/Users/amrullahzunzunia/virtualenvs/flyrobe_new/lib/python3.5/site-packages/celery/bin/base.py", line 311, in execute_from_commandline
    return self.handle_argv(self.prog_name, argv[1:])
  File "/Users/amrullahzunzunia/virtualenvs/flyrobe_new/lib/python3.5/site-packages/celery/bin/celery.py", line 762, in handle_argv
    return self.execute(command, argv)
  File "/Users/amrullahzunzunia/virtualenvs/flyrobe_new/lib/python3.5/site-packages/celery/bin/celery.py", line 694, in execute
    ).run_from_argv(self.prog_name, argv[1:], command=argv[0])
  File "/Users/amrullahzunzunia/virtualenvs/flyrobe_new/lib/python3.5/site-packages/celery/bin/worker.py", line 179, in run_from_argv
    return self(*args, **options)
  File "/Users/amrullahzunzunia/virtualenvs/flyrobe_new/lib/python3.5/site-packages/celery/bin/base.py", line 274, in __call__
    ret = self.run(*args, **kwargs)
  File "/Users/amrullahzunzunia/virtualenvs/flyrobe_new/lib/python3.5/site-packages/celery/bin/worker.py", line 212, in run
    state_db=self.node_format(state_db, hostname), **kwargs
  File "/Users/amrullahzunzunia/virtualenvs/flyrobe_new/lib/python3.5/site-packages/celery/worker/__init__.py", line 95, in __init__
    self.app.loader.init_worker()
  File "/Users/amrullahzunzunia/virtualenvs/flyrobe_new/lib/python3.5/site-packages/celery/loaders/base.py", line 128, in init_worker
    self.import_default_modules()
  File "/Users/amrullahzunzunia/virtualenvs/flyrobe_new/lib/python3.5/site-packages/celery/loaders/base.py", line 116, in import_default_modules
    signals.import_modules.send(sender=self.app)
  File "/Users/amrullahzunzunia/virtualenvs/flyrobe_new/lib/python3.5/site-packages/celery/utils/dispatch/signal.py", line 166, in send
    response = receiver(signal=self, sender=sender, **named)
  File "/Users/amrullahzunzunia/virtualenvs/flyrobe_new/lib/python3.5/site-packages/amqp/utils.py", line 42, in __call__
    self.set_error_state(exc)
  File "/Users/amrullahzunzunia/virtualenvs/flyrobe_new/lib/python3.5/site-packages/amqp/utils.py", line 39, in __call__
    **dict(self.kwargs, **kwargs) if self.kwargs else kwargs
  File "/Users/amrullahzunzunia/virtualenvs/flyrobe_new/lib/python3.5/site-packages/celery/app/base.py", line 330, in _autodiscover_tasks
    self.loader.autodiscover_tasks(packages, related_name)
  File "/Users/amrullahzunzunia/virtualenvs/flyrobe_new/lib/python3.5/site-packages/celery/loaders/base.py", line 252, in autodiscover_tasks
    related_name) if mod)
  File "/Users/amrullahzunzunia/virtualenvs/flyrobe_new/lib/python3.5/site-packages/celery/loaders/base.py", line 273, in autodiscover_tasks
    return [find_related_module(pkg, related_name) for pkg in packages]
  File "/Users/amrullahzunzunia/virtualenvs/flyrobe_new/lib/python3.5/site-packages/celery/loaders/base.py", line 273, in <listcomp>
    return [find_related_module(pkg, related_name) for pkg in packages]
  File "/Users/amrullahzunzunia/virtualenvs/flyrobe_new/lib/python3.5/site-packages/celery/loaders/base.py", line 295, in find_related_module
    _imp.find_module(related_name, pkg_path)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/imp.py", line 270, in find_module
    "not {}".format(type(name)))
RuntimeError: 'list' must be None or a list, not <class 'str'>

Это моя структура проекта:

  • Проект
    • конфигурации
      • Настройки
        • base.py
        • local.py
        • production.py
      • celery.py # имеет приложение для сельдерея.
      • urls.py
      • wsgi.py
    • разное
      • models.py
      • views.py
      • tasks.py # есть задача celery

Это мой config/celery.py:

from __future__ import absolute_import
import os
from celery import Celery

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.local')

from django.conf import settings

app = Celery('config')

app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)


@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))

Это моя конфигурация /settings/base.py:

THIRD_PARTY_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.postgres',
    'django.contrib.gis',
    'oauth2_provider',
    'rest_framework',
    'rest_framework_gis',
    'import_export',
    'braces',
    'social.apps.django_app.default',
    'rest_framework_social_oauth2',
]

CUSTOM_APPS = [
    'miscellaneous',
    # more apps
]

INSTALLED_APPS = THIRD_PARTY_APPS + CUSTOM_APPS

BROKER_URL = 'redis://localhost:6379'
CELERY_RESULT_BACKEND = 'redis://localhost:6379'
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = 'Asia/Kolkata'

Это моя конфигурация /settings/local.py:

from .base import *
LOCAL_APPS = [
    'debug_toolbar',
]
INSTALLED_APPS.extend(LOCAL_APPS)

Это мое разное /tasks.py:

from celery import shared_task

@shared_task
def log_request_meta(request_meta):
    # this is not complete yet
    return {"a": "b"}

Я использую python-3.5 и django 1.9. Я не могу понять, что я пропустил, или где я ошибаюсь, потому что я сделал именно то, что было в упомянутом выше руководстве.

Update: Версия для сельдерея - 3.1.20

Ответ 1

Вот как я решил проблему:

Я видел, что отсутствовало одно из моих приложений __init__.py, что вызвало проблему с app.autodiscover_tasks(settings.INSTALLED_APPS)

Я добавил отсутствующего __init__.py и работника сельдерея без проблем.

Ответ 2

Эта ошибка возникает при использовании Celery autodiscover_tasks, когда по какой-то причине невозможно загрузить один из ваших INSTALLED_APPS. В моем случае это был каталог с файлом tasks.py, но отсутствовали другие файлы приложений (models.py и т.д.) Из-за неполного Git commit.

Ответ 3

Первая проблема - я считаю, что строка должна быть

app.autodiscover_tasks(settings.INSTALLED_APPS)

Почему вы использовали лямбда?

Вторая трассировка - в miscellaneous/middleware.py вы вызываете задачу celery, которая передает объект wsgiref.util.FileWrapper, однако вы используете сериализатор JSON, который не может сериализовать экземпляры объекта, вместо этого вам придется использовать сериализатор рассола.

См. соответствующий раздел в docs.