7
votes

Hello! I just started to use Celery with Django. I've a task that i need to be periodic. In admin interface I can see my task in dropdown list named "Task (registered):". But when Celery Beat tries to execute it NotRegistered exception is thrown.

Python 3.5.2, Django 1.11.4, Celery 4.1, django-celery-beat 1.1.0, django-celery-results 1.0.1

Part of settings.py related to celery:

CELERY_BROKER_URL = 'amqp://user:*****@192.168.X.X/proj'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_RESULT_BACKEND = 'django-db'
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = 'Europe/Moscow'

celery.py and proj/__init__.py are identical to documentation examples.

proj/celery.py:

from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
from django.conf import settings

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proj.settings')

app = Celery('proj')

app.config_from_object(settings, namespace='CELERY')

app.autodiscover_tasks()

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

proj/__init__.py:

from __future__ import absolute_import, unicode_literals
from .celery import app as celery_app

__all__ = ['celery_app']

tasks.py:

from celery import shared_task
from core.backend.files import SFTP

@shared_task
def load_files_from_sftp():
    ftp = SFTP()
    ftp.get_files()

I get the following json result: {"exc_message": "'core.tasks.load_files_from_sftp'", "exc_type": "NotRegistered"}

If I try to use celery.task.control.inspect() from shell, it is only debug_task() there. Just stuck! ( I'll be grateful for any help.

2
from django.apps import apps app.config_from_object(settings) app.autodiscover_tasks(lambda: [n.name for n in apps.get_app_configs()]) - Muhammad Shoaib
@MuhammadShoaib Bless You! Thats it! Thank you! Why official docs doesnt have it? - Den Gavrilov
Yeah, not sure, we also have that in our project, instead of Autodiscover, we are manually passing the apps to autodiscovery function. Glad it worked for you. - Muhammad Shoaib
@MuhammadShoaib Yes, now the tasks are registered, but the periodic tasks are not started on time. Just few times a day, while period is every minute ((( Oh, but thats another story... - Den Gavrilov
Fun fact: if your tasks.py has any import errors in it, celery will fail to register the whole file and will never tell you about it. They try to import tasks.py and if there is any import error, they assume the whole file does not exist and carry on. It's actually a common design mistake in python projects. - Chris Sattinger

2 Answers

5
votes

As @MuhammadShoaib wrote, it's just one thing:

from django.apps import apps 

app.config_from_object(settings)
app.autodiscover_tasks(lambda: [n.name for n in apps.get_app_configs()])

instead of

app.autodiscover_tasks()

why this is not in the documentation?...

5
votes

This might hopefully help someone. I modified my code and neglected to restart the celery worker. Restarting the celery workers helped.