@@ -32,20 +32,23 @@ Important Warning about Time Zones
32
32
==================================
33
33
34
34
.. warning ::
35
+ If you change the Django ``TIME_ZONE `` setting your periodic task schedule
36
+ will still be based on the old timezone.
35
37
36
- If you change the Django ``TIME_ZONE `` setting your periodic task schedule
37
- will still be based on the old timezone.
38
+ To fix that you would have to reset the "last run time" for each periodic task:
38
39
39
- To fix that you would have to reset the "last run time" for each periodic
40
- task::
40
+ .. code-block :: Python
41
41
42
42
>> > from django_celery_beat.models import PeriodicTask, PeriodicTasks
43
43
>> > PeriodicTask.objects.all().update(last_run_at = None )
44
44
>> > for task in PeriodicTask.objects.all():
45
45
>> > PeriodicTasks.changed(task)
46
46
47
- Note that this will reset the state as if the periodic tasks have never run
48
- before.
47
+
48
+
49
+ .. note ::
50
+ This will reset the state as if the periodic tasks have never run before.
51
+
49
52
50
53
Models
51
54
======
@@ -76,24 +79,28 @@ incremented, which tells the ``celery beat`` service to reload the schedule
76
79
from the database.
77
80
78
81
If you update periodic tasks in bulk, you will need to update the counter
79
- manually::
82
+ manually:
83
+
84
+ .. code-block :: Python
80
85
81
- >>> from django_celery_beat.models import PeriodicTasks
82
- >>> PeriodicTasks.update_changed()
86
+ >> > from django_celery_beat.models import PeriodicTasks
87
+ >> > PeriodicTasks.update_changed()
83
88
84
89
Example creating interval-based periodic task
85
90
---------------------------------------------
86
91
87
92
To create a periodic task executing at an interval you must first
88
- create the interval object::
93
+ create the interval object:
89
94
90
- >>> from django_celery_beat.models import PeriodicTask, IntervalSchedule
95
+ .. code-block :: Python
91
96
92
- # executes every 10 seconds.
93
- >>> schedule, created = IntervalSchedule.objects.get_or_create(
94
- ... every=10,
95
- ... period=IntervalSchedule.SECONDS,
96
- ... )
97
+ >> > from django_celery_beat.models import PeriodicTask, IntervalSchedule
98
+
99
+ # executes every 10 seconds.
100
+ >> > schedule, created = IntervalSchedule.objects.get_or_create(
101
+ ... every = 10 ,
102
+ ... period = IntervalSchedule.SECONDS ,
103
+ ... )
97
104
98
105
That's all the fields you need: a period type and the frequency.
99
106
@@ -107,46 +114,52 @@ You can choose between a specific set of periods:
107
114
- ``IntervalSchedule.MICROSECONDS ``
108
115
109
116
.. note ::
110
-
111
117
If you have multiple periodic tasks executing every 10 seconds,
112
118
then they should all point to the same schedule object.
113
119
114
120
There's also a "choices tuple" available should you need to present this
115
- to the user::
121
+ to the user:
122
+
123
+
124
+ .. code-block :: Python
116
125
117
- >>> IntervalSchedule.PERIOD_CHOICES
126
+ >> > IntervalSchedule.PERIOD_CHOICES
118
127
119
128
120
129
Now that we have defined the schedule object, we can create the periodic task
121
- entry::
130
+ entry:
122
131
123
- >>> PeriodicTask.objects.create(
124
- ... interval=schedule, # we created this above.
125
- ... name='Importing contacts', # simply describes this periodic task.
126
- ... task='proj.tasks.import_contacts', # name of task.
127
- ... )
132
+ .. code-block :: Python
133
+
134
+ >> > PeriodicTask.objects.create(
135
+ ... interval = schedule, # we created this above.
136
+ ... name = ' Importing contacts' , # simply describes this periodic task.
137
+ ... task = ' proj.tasks.import_contacts' , # name of task.
138
+ ... )
128
139
129
140
130
141
Note that this is a very basic example, you can also specify the arguments
131
142
and keyword arguments used to execute the task, the ``queue `` to send it
132
143
to[*], and set an expiry time.
133
144
134
145
Here's an example specifying the arguments, note how JSON serialization is
135
- required::
146
+ required:
147
+
148
+ .. code-block :: Python
136
149
137
- >>> import json
138
- >>> from datetime import datetime, timedelta
150
+ >> > import json
151
+ >> > from datetime import datetime, timedelta
139
152
140
- >>> PeriodicTask.objects.create(
141
- ... interval=schedule, # we created this above.
142
- ... name='Importing contacts', # simply describes this periodic task.
143
- ... task='proj.tasks.import_contacts', # name of task.
144
- ... args=json.dumps(['arg1', 'arg2']),
145
- ... kwargs=json.dumps({
146
- ... 'be_careful': True,
147
- ... }),
148
- ... expires=datetime.utcnow() + timedelta(seconds=30)
149
- ... )
153
+ >> > PeriodicTask.objects.create(
154
+ ... interval = schedule, # we created this above.
155
+ ... name = ' Importing contacts' , # simply describes this periodic task.
156
+ ... task = ' proj.tasks.import_contacts' , # name of task.
157
+ ... args = json.dumps([' arg1' , ' arg2' ]),
158
+ ... kwargs = json.dumps({
159
+ ... ' be_careful' : True ,
160
+ ... }),
161
+ ... expires = datetime.utcnow() + timedelta(seconds = 30 )
162
+ ... )
150
163
151
164
152
165
.. [* ] you can also use low-level AMQP routing using the ``exchange `` and
@@ -157,37 +170,43 @@ Example creating crontab-based periodic task
157
170
158
171
A crontab schedule has the fields: ``minute ``, ``hour ``, ``day_of_week ``,
159
172
``day_of_month `` and ``month_of_year ``, so if you want the equivalent
160
- of a ``30 * * * * `` (execute every 30 minutes) crontab entry you specify::
161
-
162
- >>> from django_celery_beat.models import CrontabSchedule, PeriodicTask
163
- >>> schedule, _ = CrontabSchedule.objects.get_or_create(
164
- ... minute='30',
165
- ... hour='*',
166
- ... day_of_week='*',
167
- ... day_of_month='*',
168
- ... month_of_year='*',
169
- ... timezone=pytz.timezone('Canada/Pacific')
170
- ... )
173
+ of a ``30 * * * * `` (execute every 30 minutes) crontab entry you specify:
174
+
175
+ .. code-block :: Python
176
+
177
+ >> > from django_celery_beat.models import CrontabSchedule, PeriodicTask
178
+ >> > schedule, _ = CrontabSchedule.objects.get_or_create(
179
+ ... minute = ' 30' ,
180
+ ... hour = ' *' ,
181
+ ... day_of_week = ' *' ,
182
+ ... day_of_month = ' *' ,
183
+ ... month_of_year = ' *' ,
184
+ ... timezone = pytz.timezone(' Canada/Pacific' )
185
+ ... )
171
186
172
187
The crontab schedule is linked to a specific timezone using the 'timezone' input parameter.
173
188
174
189
Then to create a periodic task using this schedule, use the same approach as
175
190
the interval-based periodic task earlier in this document, but instead
176
- of ``interval=schedule ``, specify ``crontab=schedule ``::
191
+ of ``interval=schedule ``, specify ``crontab=schedule ``:
192
+
193
+ .. code-block :: Python
177
194
178
- >>> PeriodicTask.objects.create(
179
- ... crontab=schedule,
180
- ... name='Importing contacts',
181
- ... task='proj.tasks.import_contacts',
182
- ... )
195
+ >> > PeriodicTask.objects.create(
196
+ ... crontab = schedule,
197
+ ... name = ' Importing contacts' ,
198
+ ... task = ' proj.tasks.import_contacts' ,
199
+ ... )
183
200
184
201
Temporarily disable a periodic task
185
202
-----------------------------------
186
203
187
- You can use the ``enabled `` flag to temporarily disable a periodic task::
204
+ You can use the ``enabled `` flag to temporarily disable a periodic task:
205
+
206
+ .. code-block :: Python
188
207
189
- >>> periodic_task.enabled = False
190
- >>> periodic_task.save()
208
+ >> > periodic_task.enabled = False
209
+ >> > periodic_task.save()
191
210
192
211
193
212
Example running periodic tasks
@@ -202,24 +221,20 @@ Both the worker and beat services need to be running at the same time.
202
221
203
222
1. Start a Celery worker service (specify your Django project name)::
204
223
205
-
206
- $ celery -A [project-name] worker --loglevel=info
224
+ $ celery -A [project-name] worker --loglevel=info
207
225
208
226
209
227
2. As a separate process, start the beat service (specify the Django scheduler)::
210
228
211
-
212
- $ celery -A [project-name] beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler
213
-
229
+ $ celery -A [project-name] beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler
214
230
215
231
**OR** you can use the -S (scheduler flag), for more options see ``celery beat --help``)::
216
232
217
- $ celery -A [project-name] beat -l info -S django
233
+ $ celery -A [project-name] beat -l info -S django
218
234
219
235
Also, as an alternative, you can run the two steps above (worker and beat services)
220
236
with only one command (recommended for **development environment only**)::
221
237
222
-
223
238
$ celery -A [project-name] worker --beat --scheduler django --loglevel=info
224
239
225
240
@@ -234,35 +249,47 @@ Installation
234
249
You can install django-celery-beat either via the Python Package Index (PyPI)
235
250
or from source.
236
251
237
- To install using ``pip ``::
252
+ To install using ``pip ``:
253
+
254
+ .. code-block :: bash
238
255
239
- $ pip install -U django-celery-beat
256
+ $ pip install -U django-celery-beat
240
257
241
258
Downloading and installing from source
242
259
--------------------------------------
243
260
244
261
Download the latest version of django-celery-beat from
245
262
http://pypi.python.org/pypi/django-celery-beat
246
263
247
- You can install it by doing the following,::
264
+ You can install it by doing the following :
265
+
266
+ .. code-block :: bash
248
267
249
- $ tar xvfz django-celery-beat-0.0.0.tar.gz
250
- $ cd django-celery-beat-0.0.0
251
- $ python setup.py build
252
- # python setup.py install
268
+ $ tar xvfz django-celery-beat-0.0.0.tar.gz
269
+ $ cd django-celery-beat-0.0.0
270
+ $ python setup.py build
271
+ # python setup.py install
253
272
254
273
The last command must be executed as a privileged user if
255
274
you are not currently using a virtualenv.
256
275
257
276
258
- After installation, add ``django_celery_beat `` to Django settings file: :
277
+ After installation, add ``django_celery_beat `` to Django's settings module :
259
278
260
- INSTALLED_APPS = [
261
- ...,
262
- 'django_celery_beat',
263
- ]
264
279
265
- python manage.py migrate django_celery_beat
280
+ .. code-block :: Python
281
+
282
+ INSTALLED_APPS = [
283
+ ... ,
284
+ ' django_celery_beat' ,
285
+ ]
286
+
287
+
288
+ Run the ``django_celery_beat `` migrations using:
289
+
290
+ .. code-block :: bash
291
+
292
+ $ python manage.py migrate django_celery_beat
266
293
267
294
268
295
Using the development version
@@ -272,17 +299,21 @@ With pip
272
299
~~~~~~~~
273
300
274
301
You can install the latest snapshot of django-celery-beat using the following
275
- pip command::
302
+ pip command:
303
+
304
+ .. code-block :: bash
276
305
277
- $ pip install https://github.com/celery/django-celery-beat/zipball/master#egg=django-celery-beat
306
+ $ pip install https://github.com/celery/django-celery-beat/zipball/master#egg=django-celery-beat
278
307
279
308
280
309
Developing django-celery-beat
281
310
-----------------------------
282
311
283
- To spin up a local development copy of django-celery-beat with Django admin at http://127.0.0.1:58000/admin/ run::
312
+ To spin up a local development copy of django-celery-beat with Django admin at http://127.0.0.1:58000/admin/ run:
313
+
314
+ .. code-block :: bash
284
315
285
- $ docker-compose up --build
316
+ $ docker-compose up --build
286
317
287
318
Log-in as user ``admin `` with password ``admin ``.
288
319
0 commit comments