I have being trying to setup django + celery + redis + celery_beats but it is giving me trouble. The documentation is quite straightforward, but when I run the django server, redis, celery and celery beats, nothing gets printed or logged (all my test task does its log something).
This is my folder structure:
- aenima
- aenima
- __init__.py
- celery.py
- criptoball
- tasks.py
celery.py looks like this:
from __future__ import absolute_import, unicode_literals
import os
from django.conf import settings
from celery import Celery
# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'aenima.settings')
app = Celery("criptoball")
app.conf.broker_url = 'redis://localhost:6379/0'
# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
# should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')
# Load task modules from all registered Django app configs.
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
app.conf.timezone = 'UTC'
@app.task(bind=True)
def debug_task(self):
print('Request: {0!r}'.format(self.request))
app.conf.beat_schedule = {
'test-every-30-seconds': {
'task': 'tasks.test_celery',
'schedule': 30.0,
'args': (16, 16)
}, }
and tasks.py looks like this:
from __future__ import absolute_import, unicode_literals
from datetime import datetime, timedelta
from celery import shared_task
import logging
from django_celery_beat.models import PeriodicTask, IntervalSchedule
cada_10_seg = IntervalSchedule.objects.create(every=10, period=IntervalSchedule.SECONDS)
test_celery_periodic = PeriodicTask.objects.create(interval=cada_10_seg, name='test_celery', task='criptoball.tasks.test_celery',
expires=datetime.utcnow()+timedelta(seconds=30))
@shared_task
def test_celery(x, y):
logger = logging.getLogger("AENIMA")
print("EUREKA")
logger.debug("EUREKA")
This is the django_celery_beat docs
Not sure what am I missing. When I run
celery -A aenima beat -l debug --scheduler django_celery_beat.schedulers:DatabaseScheduler
celery -A aenima worker -l debug
redis-cli ping PONG
django runserver and redis server, I get nothing printed.
settings.py
CELERY_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 = TIME_ZONE
CELERY_IMPORTS = ('criptoball.tasks',)
Haven't found any authorative answer to this topic in SO so far.
I would like to solve it all, this error may be just one of many. Thanks a lot for your help!
Edit:
Added settings for redis, declared the the task differently and increased debug level. Now the error is:
Received unregistered task of type u'tasks.test_celery'. The message has been ignored and discarded.
Did you remember to import the module containing this task? Or maybe you're using relative imports? KeyError: u'aenima.criptoball.tasks.test_celery'
I believe Celery's documentation is poor.
EDIT 2 After trying everything, it worked when I put all the tasks inside the same celery.py file. the @shared_task doesn't work, had to use @app.task .
There is one thing you should fix, use:
to tell Celery which apps' tasks do you want it to discover if you're using Celery 3.x.
Using
virtualenv
for this would be handy.First like @Gal said you need to make sure you have
celery 4.x
.You can install this doing it through
pip
:Of course you can also install the
4.x
version adding it in yourrequirements.txt
like so:Or higher versions if available in the future.
Then you could reinstall all your packages using:
pip install -r requirements.txt
Which will make sure you have that certain celery package installed.
Now the Celery part, although your code might not be wrong, but I will write in a way how I got my Celery app to work.
__init __.py:
celery_conf.py:
tasks.py:
As I explained in the code as well, the regular
taskregistry
did not work thats built in the Celery 4.x, so I made use of the demo taskregistry. You can of course also not use classes to make tasks, but I prefered to use a class.settings.py:
I start my worker with the following commands:
I hope this information may help you or anyone out that's struggling with Celery.
EDIT:
Note that I start the worker as daemon, so you won't actually be able to see the logs in the console. For me it's logged in a
.txt
file.Plus note as well the paths to use for example for some you need to include the path to your app like so:
And for other cases you need to include the tasks.py without the
.py
as well, I wrote down when to exclude this file and when not to.EDIT 2:
Notice that
@shared_task
does not have access to the app of the user. The app you're currently trying to register doesn't have access to your app. The method you actually want to use to register a task is:Maybe your task path is incorrect, should be:
tasks.test_celery
should be full path:criptoball.tasks.test_celery
I had those issues before. It's not your code. It's usually a problem with the environment. You should run everything under
virtualenv
, adding arequirements.txt
file with the specific package versions.There is a know issue regarding
celery 4.x
anddjango 1.x
, so you should consider the packages you are using.This tutorial will explain in detail how to build
virtualenv
with celery.If you can tell me your packages versions I might try and help in a different way.
Edit:
I think its something about the way you run your celery. If we fixed the first problem, try play with this:
or
The latest error you are getting is something to do with your module discovery. Try it first.