Search code examples
pythondjangodjango-modelsscheduled-taskspytz

How to execute a command at exact time once a day in Django?


I am working on a Django web based project in which i need to build a application which work in the following sequence:

1) user open a page in which he need to enter a command and a time

2) Django application will execute that command at a given time on each day till user off the scheduler (by default it is True)

What i am facing the problem is that :

1) How should i execute the commands on a time but on each day. To save the commands and time i created a following model in my models.py

class commands(models.Model):
    username = models.ForeignKey(User)
    command = models.CharField(max_length=30)
    execution_time = models.DateField()

I have the same time but i am not getting the right way to execute it on each day at the given time

and is it possible to do with pytz library?

For executing the commands i am using paramiko library

PS: I don't want to use any external library


Solution

  • While you could have your django app add and remove cron jobs on the system, another more django-ish approach would be to use Celery. It is a task queue system that can run both synch and async tasks.

    One specific feature of Celery is scheduled tasks: http://packages.python.org/celery/userguide/periodic-tasks.html

    from datetime import timedelta
    
    CELERYBEAT_SCHEDULE = {
        "runs-every-30-seconds": {
            "task": "tasks.add",
            "schedule": timedelta(seconds=30),
            "args": (16, 16)
        },
    }
    

    They also have a more granular version of the period task that replicates the scheduling of a crontab:

    from celery.schedules import crontab
    
    CELERYBEAT_SCHEDULE = {
        # Executes every Monday morning at 7:30 A.M
        'every-monday-morning': {
            'task': 'tasks.add',
            'schedule': crontab(hour=7, minute=30, day_of_week=1),
            'args': (16, 16),
        },
    }
    

    Celery by itself is stand-alone but there is the django-celery specific verison

    The benefit of this solution is that you do not need to edit and maintain a system-level cron tab. This is a solution that is highly integrated into django for this exact use.

    Also a huge win over using a cron is that Celery can scale with your system. If you were using a basic system crontab, then the tasks would be located on the server that hosts the application. But what if you needed to ramp up your site and run it on 5 web application nodes? You would need to centralize that crontab. If you are using Celery, you have a large number of options for how to transport and store tasks. It is inherently distributed, and available in sync to all your application servers. It is portable.