L. P.
L. P.

Reputation: 164

Django-Celery Scheduling Daily Tasks on Windows Server

I have to schedule a task to run every Monday through Saturday. I downloaded django-celery to accomplish the task. I followed the tutorial on the Celery site and I used and looked at a few stack overflow posts, for example: here & here

I did a mix and match with the above posts and with this two great tutorials: Rhatore and Freitas

This is my folder structure:

Application
    | apps
         | app1
              | __init__.py
              | tasks.py
              | urls.py
              | views.py    
    | Application
         | __init__.py
         | celery.py
         | settings.py
         | urls.py
         | wsgi.py

Settings.py

INSTALLED_APPS = [
    'django_celery_beat',
    'apps.app1',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True    
USE_TZ = True

CELERY_BROKER_URL = 'amqp://localhost'
CELERY_RESULT_BACKEND = 'amqp://localhost'
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = 'UTC'

__init__.py In the init under the Application

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

from .celery import app as celery_app

    __all__ = ('celery_app',)

celery.py

from __future__ import absolute_import, unicode_literals
import os
from celery import Celery

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

app = Celery('Application')

app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()

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

tasks.py - for simplicity sake I reduced the task to a simple print command

from celery import shared_task
from celery.utils.log import get_task_logger
from celery.schedules import crontab
from celery.task import periodic_task
from celeryapp.emails import send_feedback_email
from django.http import HttpResponse
from .models import *

logger=get_task_logger(__name__)

@periodic_task(run_every=crontab(hour=21, minute=32, day_of_week=0-5))
def simple_print():
    print("Hello World!")

I ran:

celery -A Application -1 info

And then python manage.py runserver 21:32 UTC passed and it did not print. I expected to see "Hello World" printed at 21:32 UTC in the terminal as per the task specified in tasks.py. It did not print.

I also ran:

celery -A Application worker -l info
celery -A Application beat -l info
python manage.py runserver

in different terminals. It did not execute the task.

Guidance would be much appreciated.

Upvotes: 4

Views: 1922

Answers (2)

L. P.
L. P.

Reputation: 164

The code was correct. The problem was due to the OS. I'm using Windows and Celery 4.0 does not support Windows. This question was very useful: How to Run Celery on Windows. I installed gevent and it worlks now.

pip install gevent
celery -A Application beat -l info
celery -A Application worker -l info -P gevent

If you get another error along the lines of "Fatal error in launcher..." try:

python -m celery -A Application beat -l info
python -m celery -A Application worker -l info -P gevent

Upvotes: 1

Alex
Alex

Reputation: 2474

You need to have both the worker and the beat running, so that celery will know if it has to run a periodic task at a certain time.

Something like this should help you in your local environment.

celery -A Application worker -l info -B

Alternatively, you can start both workers as individual services

celery -A Application worker -l info

celery -A Application beat -l info

Upvotes: 1

Related Questions