0
# REST API Views
1
2
HTTP endpoints for checking task and group execution status, returning JSON responses suitable for web applications and AJAX requests. These views provide programmatic access to task status without requiring direct database queries.
3
4
## Core Imports
5
6
```python
7
from django_celery_results.views import (
8
task_status,
9
is_task_successful,
10
group_status,
11
is_group_successful
12
)
13
```
14
15
## Capabilities
16
17
### Task Status Views
18
19
Views for checking individual task execution status and retrieving detailed results.
20
21
```python { .api }
22
def task_status(request, task_id):
23
"""
24
Get detailed task status and result in JSON format.
25
26
Args:
27
request: Django HttpRequest object
28
task_id (str): Celery task ID to check
29
30
Returns:
31
JsonResponse: JSON with task status, result, and error information
32
{
33
"task": {
34
"id": "task-id",
35
"status": "SUCCESS|PENDING|FAILURE|...",
36
"result": "task result data",
37
# For failed tasks:
38
"exc": "exception class name",
39
"traceback": "full traceback string"
40
}
41
}
42
"""
43
44
def is_task_successful(request, task_id):
45
"""
46
Check if a task completed successfully.
47
48
Args:
49
request: Django HttpRequest object
50
task_id (str): Celery task ID to check
51
52
Returns:
53
JsonResponse: JSON with boolean success status
54
{
55
"task": {
56
"id": "task-id",
57
"executed": true|false
58
}
59
}
60
"""
61
```
62
63
#### Usage Examples
64
65
```python
66
# URL configuration
67
from django.urls import path, include
68
69
urlpatterns = [
70
path('celery/', include('django_celery_results.urls')),
71
]
72
73
# JavaScript/AJAX usage
74
fetch('/celery/task/status/abc123/')
75
.then(response => response.json())
76
.then(data => {
77
console.log('Task status:', data.task.status);
78
console.log('Task result:', data.task.result);
79
if (data.task.status === 'FAILURE') {
80
console.log('Error:', data.task.exc);
81
console.log('Traceback:', data.task.traceback);
82
}
83
});
84
85
// Check if task succeeded
86
fetch('/celery/task/done/abc123/')
87
.then(response => response.json())
88
.then(data => {
89
if (data.task.executed) {
90
console.log('Task completed successfully');
91
} else {
92
console.log('Task not yet completed or failed');
93
}
94
});
95
```
96
97
### Group Status Views
98
99
Views for checking group task execution status and retrieving results for all tasks in a group.
100
101
```python { .api }
102
def group_status(request, group_id):
103
"""
104
Get detailed status for all tasks in a group.
105
106
Args:
107
request: Django HttpRequest object
108
group_id (str): Celery group ID to check
109
110
Returns:
111
JsonResponse: JSON with group ID and all task results
112
{
113
"group": {
114
"id": "group-id",
115
"results": [
116
{
117
"result": "task 1 result",
118
"status": "SUCCESS"
119
},
120
{
121
"result": "task 2 result",
122
"status": "FAILURE"
123
}
124
]
125
}
126
}
127
"""
128
129
def is_group_successful(request, group_id):
130
"""
131
Check if all tasks in a group completed successfully.
132
133
Args:
134
request: Django HttpRequest object
135
group_id (str): Celery group ID to check
136
137
Returns:
138
JsonResponse: JSON with group ID and per-task execution status
139
{
140
"group": {
141
"id": "group-id",
142
"results": [
143
{
144
"id": "task-1-id",
145
"executed": true
146
},
147
{
148
"id": "task-2-id",
149
"executed": false
150
}
151
]
152
}
153
}
154
"""
155
```
156
157
#### Usage Examples
158
159
```python
160
# Check detailed group status
161
fetch('/celery/group/status/group123/')
162
.then(response => response.json())
163
.then(data => {
164
console.log('Group ID:', data.group.id);
165
data.group.results.forEach((task, index) => {
166
console.log(`Task ${index}: ${task.status} - ${task.result}`);
167
});
168
});
169
170
// Check if all group tasks succeeded
171
fetch('/celery/group/done/group123/')
172
.then(response => response.json())
173
.then(data => {
174
const allSuccessful = data.group.results.every(task => task.executed);
175
if (allSuccessful) {
176
console.log('All group tasks completed successfully');
177
} else {
178
console.log('Some group tasks are still pending or failed');
179
data.group.results.forEach(task => {
180
if (!task.executed) {
181
console.log(`Task ${task.id} not completed`);
182
}
183
});
184
}
185
});
186
```
187
188
## URL Configuration
189
190
### URL Patterns
191
192
The package provides predefined URL patterns for all views:
193
194
```python
195
# django_celery_results.urls
196
urlpatterns = [
197
# Task status endpoints
198
path('task/status/<task_pattern:task_id>/', views.task_status,
199
name='celery-task_status'),
200
path('task/done/<task_pattern:task_id>/', views.is_task_successful,
201
name='celery-is_task_successful'),
202
203
# Group status endpoints
204
path('group/status/<task_pattern:group_id>/', views.group_status,
205
name='celery-group_status'),
206
path('group/done/<task_pattern:group_id>/', views.is_group_successful,
207
name='celery-is_group_successful'),
208
]
209
```
210
211
### Custom Path Converter
212
213
A custom path converter handles task and group ID patterns:
214
215
```python { .api }
216
class TaskPatternConverter:
217
"""Custom path converter for task and group IDs."""
218
219
regex: str # Regular expression pattern: r'[\w\d\-\.]+'
220
221
def to_python(self, value):
222
"""
223
Convert URL value to Python string.
224
225
Args:
226
value: URL path component
227
228
Returns:
229
str: Task or group ID as string
230
"""
231
232
def to_url(self, value):
233
"""
234
Convert Python value to URL component.
235
236
Args:
237
value: Task or group ID
238
239
Returns:
240
str: URL-safe string
241
"""
242
```
243
244
### Legacy URL Support
245
246
The package includes deprecated ID-first URL patterns for backward compatibility:
247
248
```python
249
# Legacy URLs (deprecated, controlled by setting)
250
DJANGO_CELERY_RESULTS_ID_FIRST_URLS = True # Default
251
252
# Legacy patterns (will be removed in future versions):
253
# /<task_id>/done/
254
# /<task_id>/status/
255
# /<group_id>/group/done/
256
# /<group_id>/group/status/
257
```
258
259
## Integration Examples
260
261
### Django Template Usage
262
263
```html
264
<!-- task_status.html -->
265
<div id="task-status" data-task-id="{{ task_id }}">
266
<p>Status: <span id="status">Loading...</span></p>
267
<p>Result: <span id="result">-</span></p>
268
<div id="error-info" style="display: none;">
269
<p>Error: <span id="error-type"></span></p>
270
<pre id="traceback"></pre>
271
</div>
272
</div>
273
274
<script>
275
function checkTaskStatus(taskId) {
276
fetch(`/celery/task/status/${taskId}/`)
277
.then(response => response.json())
278
.then(data => {
279
document.getElementById('status').textContent = data.task.status;
280
281
if (data.task.status === 'SUCCESS') {
282
document.getElementById('result').textContent = data.task.result;
283
} else if (data.task.status === 'FAILURE') {
284
document.getElementById('error-type').textContent = data.task.exc;
285
document.getElementById('traceback').textContent = data.task.traceback;
286
document.getElementById('error-info').style.display = 'block';
287
}
288
});
289
}
290
291
// Poll for status updates
292
const taskId = document.getElementById('task-status').dataset.taskId;
293
const interval = setInterval(() => {
294
checkTaskStatus(taskId);
295
}, 2000);
296
</script>
297
```
298
299
### React Component Usage
300
301
```javascript
302
// TaskStatus.jsx
303
import React, { useState, useEffect } from 'react';
304
305
function TaskStatus({ taskId }) {
306
const [status, setStatus] = useState(null);
307
const [loading, setLoading] = useState(true);
308
309
useEffect(() => {
310
const checkStatus = async () => {
311
try {
312
const response = await fetch(`/celery/task/status/${taskId}/`);
313
const data = await response.json();
314
setStatus(data.task);
315
setLoading(false);
316
317
// Stop polling if task is complete
318
if (['SUCCESS', 'FAILURE', 'REVOKED'].includes(data.task.status)) {
319
return;
320
}
321
} catch (error) {
322
console.error('Error checking task status:', error);
323
setLoading(false);
324
}
325
};
326
327
checkStatus();
328
const interval = setInterval(checkStatus, 2000);
329
330
return () => clearInterval(interval);
331
}, [taskId]);
332
333
if (loading) return <div>Loading...</div>;
334
335
return (
336
<div>
337
<h3>Task Status: {status.status}</h3>
338
{status.status === 'SUCCESS' && (
339
<div>Result: {JSON.stringify(status.result)}</div>
340
)}
341
{status.status === 'FAILURE' && (
342
<div>
343
<div>Error: {status.exc}</div>
344
<pre>{status.traceback}</pre>
345
</div>
346
)}
347
</div>
348
);
349
}
350
```
351
352
## Response Formats
353
354
### Task Status Response
355
356
```json
357
{
358
"task": {
359
"id": "550e8400-e29b-41d4-a716-446655440000",
360
"status": "SUCCESS",
361
"result": "Task completed successfully"
362
}
363
}
364
```
365
366
### Failed Task Response
367
368
```json
369
{
370
"task": {
371
"id": "550e8400-e29b-41d4-a716-446655440000",
372
"status": "FAILURE",
373
"result": "ValueError: Invalid input",
374
"exc": "ValueError",
375
"traceback": "Traceback (most recent call last):\n File ...\nValueError: Invalid input"
376
}
377
}
378
```
379
380
### Group Status Response
381
382
```json
383
{
384
"group": {
385
"id": "group-550e8400-e29b-41d4-a716-446655440000",
386
"results": [
387
{
388
"result": "First task result",
389
"status": "SUCCESS"
390
},
391
{
392
"result": "Second task result",
393
"status": "SUCCESS"
394
}
395
]
396
}
397
}
398
```