TC Fox
TC Fox

Reputation: 1030

celery task decorator throws "TypeError: 'Module object is not callable"

I'm trying desperately to get Celery to play nicely with Django, but to no avail. I am getting tripped up on the following:

project/settings.py:

...

import djcelery
djcelery.setup_loader()

BROKER_URL = 'django://'
CELERY_RESULT_BACKEND = 'django://'
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_ENABLE_UTC = True

...

app/tasks.py:

from celery.task import task

@task()
def scheduled_task(param1, param2):
    ...
    return something

Calling scheduled_task(param1, param2) directly (without the decorator) works as expected. However when adding the decorator and firing up the 'development' celery worker like so:

python manage.py celery worker --loglevel=info

...I get the following error:

TypeError: 'module' object is not callable

I've pinned this down to the @task decorator. Every combination I try fails, including:

from celery import task
from celery.task import task
from celery.task.base import task

@task
@task()
@task.task
@task.task()
@celery.task
@celery.task()

Nothing seems to make any difference to the call stack in the exception, they all appear to think that task is a module, and not callable! To make things even more frustrating:

>>> from celery.task import task
>>> task
<function task at 0x10aa2a758>

That sure looks callable to me! Any idea what might be happening? If I've missed anything, I'm happy to post additional logs, files or clarify anything else.

Upvotes: 5

Views: 11932

Answers (3)

Greg Holst
Greg Holst

Reputation: 974

Just in case somebody is using Celery beat and gets the same error message. In my app I used

command=/opt/python/run/venv/bin/celery beat -A appname --loglevel=INFO --workdir=/tmp -S django --pidfile /tmp/celerybeat.pid

and got this error message. Since I copied most of the code for daemonizing Celery beat using supervisord (you need a special config for this), I did not realize that the "-S django" presumes the use of django_celery_beat package, which I had not installed before. I installed it because it anyway has advantages for production use and the error disappeared.

Upvotes: 2

glowka
glowka

Reputation: 730

It's a bit old question, but I got into similar trouble and that worked for me:

project/settings.py:

...

import djcelery
djcelery.setup_loader()

BROKER_URL = 'django://'
CELERY_RESULT_BACKEND = 'djcelery.backends.database:DatabaseBackend'
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_ENABLE_UTC = True

...

Upvotes: 0

Lukas Graf
Lukas Graf

Reputation: 32590

(Converted to an answer from comments)

From the stack trace I take it that the line return backend(app=self, url=url) is where the exception happens.

So whatever backend is, it doesn't seem to be a callable. I would try to set a pdb breakpoint in that file (celery/app/base.py) by wrapping that line in

try:
    backend(app=self, url=url)
except:
    import pdb; pdb.set_trace(),

and then inspecting backend, and moving up the stack (u command in pdb, d to go down again, w to display call stack) to debug where it all goes wrong.

The celery docs also mention this:

How do I import the task decorator?

The task decorator is available on your Celery instance, if you don’t know what that is then please read First Steps with Celery.

If you’re using Django or are still using the “old” module based celery API, then you can import the task decorator like this:

from celery import task

@task
def add(x, y):
    return x + y

So that should clear up any amiguity about what way to import the task decorator is the right one.

Upvotes: 1

Related Questions