I posted a question :How to execute a command at exact time once a day in Django?
I got my answer that the Celery is the easiest option to do it, but now i have another question regarding the celery:
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),
},
}
I have three question in regarding the above code i.e:
I have to execute execute_command(User, command) method. I want that this method will execute at the given scheduled time.
What if i want to change the schedule at 7:30 AM but every weekdays?.
What about the args. In my case should i pass the value of User and command from args. Or i can simply pass from the task key ?
I just read the docs of celery, but didn't got my answer. Would you please help me?
Did you find the Celery periodic tasks documentation?
You'll have to use the identifier of your method to register a scheduler entry. If your execute_command task lives in a module named foobar, the task value of the CELERYBEAT_SCHEDULE structure should be foobar.execute_command.
Celery will import the task for you, provided that import foobar.execute_command would work.
Check the celery.schedule.crontab API; the following should execute on weekdays at 07:30 am:
crontab(minute=30, hour=7, day_of_week=’mon-fri’)
Remember that this task is going to be performed asynchronously. You cannot query for a database object when you schedule this task and expect it to be there still when the task is called.
Thus, you should only pass in python values that remain constant, and have your task connect to the database and look things up based on the arguments you pass in.
If this task is only ever going to execute tasks for one specific user, then by all means pass in the identifier for that user (user id, email, whatever you can use to look up the user from the database).
Related
I am in the process of writing my own task app using Django and would like a few specific functions to be executed every day at a certain time (updating tasks, checking due dates, etc.). Is there a way to have Django run functions on a regular basis or how do I go about this in general?
Does it make sense to write an extra program with an infinite loop for this or are there better ways?
Celery is a good option here:
First steps with Django
Periodic Tasks
app.conf.beat_schedule = {
'add-every-30-seconds': {
'task': 'tasks.add',
'schedule': 30.0,
'args': (16, 16)
},
}
app.conf.timezone = 'UTC'
With celery you can define periodic tasks at any given interval. Celery workers will then pick up those tasks when needed. You will need to run something like RabbitMQ or Redis to support the celery workers.
The alternative, simpler, way is to add an entry to your urls.py that catches any url you don't otherwise use, and use that as a prompt to check your database as to whether another task is due. This leverages the fact that your website will be hit by a lot of bot traffic. The timing isn't entirely reliable but it doesn't require any extra set up.
you can use django-cronjobs or maybe Schedule your job with schedule library.
I have configured Django + Celery: all works, i can execute tasks, that called from views.py i.e. mul.apply_async((2, 5), queue='celery', countdown=5)
I need to shedule periodic task that will chain simple tasks with argument that passed from users.
I read docs http://docs.celeryproject.org/en/latest/userguide/canvas.html and know how to chain, i know how to make periodic task without parameters #periodic_task(run_every=(crontab(hour="*", minute="*", day_of_week="*")))
But how to combine this?
What i want workflow:
User creates project with parameters. 5 tasks executed, using that parameters.
Then i need shedule to repeat all 5 tasks every 24 hours. So here i dont know how to pass parameters (they save to db).
In other answer i saw this syntax:
CELERYBEAT_SCHEDULE = {
# crontab(hour=0, minute=0, day_of_week='saturday')
'schedule-name': { # example: 'file-backup'
'task': 'some_django_app.tasks....', # example: 'files.tasks.cleanup'
'schedule': crontab(...)
'args': (2, 3)
},
}
But the problem here is that it located in settings.py of Django but not in tasks.py and i cannot dynamically pass args.
The celerybeat task you register could be a wrapper and perform the project/task logic inside of it, firing off other tasks as appropriate. You could fetch the project tasks inside of your celery beat job.
CELERYBEAT_SCHEDULE.task -> 'some_django_app.project_beat_task'
Then project beat task could retrieve the correct projects and all tasks associated with them, perhaps spawning a chain of tasks for each project
I have a code which deletes an api column when executed. Now I want it to execute after some time lets say two weeks. Any idea or directions how do I implement it?
My code:
authtoken = models.UserApiToken.objects.get(api_token=token)
authtoken.delete()
This is inside a function and executed when a request is made.
There are two main ways to get this done:
Make it a custom management command, and trigger it through crontab.
Use celery, make it a celery task, and use celerybeat to trigger the job after 2 weeks.
I would recommend celery, as it provides a better control of your task queues and jobs.
got a simple question, I believe, but it got me stuck anyways.
Say I have a simple model:
class myModel(models.Model):
expires = models.DateTimeField(...)
and I want, say on the specified time do something: send an email, delete model, change some of the models fields... Something. Is there a tool in django core, allowing me to do so?
Or, if not, I think some task queuing tool might be in order. I have djcelery working in my project, though I'm a completely newbie in it, and all I was able to perform so far, is to run django-celery-email package, in order to send my mail asynchronically. Though I can't say I'm fully capable of defining task and workers to work in background and be reliable.
If any ideas, on how to solve such problem, please, do not hesitate =)
Write a custom management command to do the task that you desire. When you are done, you should be able to run your task with python manage.py yourtaskname.
Use cron, at, periodic tasks in celery, django-cron, djangotaskscheduler or django-future to schedule your tasks.
I think the best is a background-task the reads the datime and executes a task if a datetime is or has been reached.
See the solution given here for a scheduled task
So the workflow would be:
Create the task you want to apply on objects whose date has been reached
Create a managment command that checks the datetimes in your DB, and execute the above task for every object the datetime has been reached
Use cron (Linux) or at(Windows) to schedule the command call
If you're on a UNIX-like machine, it's possible that you have access to cronjobs. If you're on Windows, I hear there's a program called at that can do similar things. If this doesn't suit your needs, there are a number of ways to do things every X hours using the time library (time.sleep(SOME_NUMBER_OF_SECONDS) in a loop with whatever else you want to do will do it if you want something done regularly, otherwise you'll need to look at time.localtime() and check for conditions).
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
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.
It seems to me that the proper way to do this would be write a Django custom command and execute it via cron. But you seem to be under luck as others have felt similar need and have written custom django apps. Take django-cron for example.
The solution for your problem is standard cron application (task planner on *nix systems). You can schedule a script using cron (by adding it to crontab).
If your script must perform in you Django application environment, it's possible to tell him to do that with setup_environment function. You can read more about standalone scripts for Django applications here.