Drop in, dependency-free progress bars for your Django/Celery applications.
Super simple setup. Lots of customization available.
Celery Progress Bar demo on Build With Django
pip install celery-progress
First add celery_progress
to your INSTALLED_APPS
in settings.py
.
Then add the following url config to your main urls.py
:
url(r'^celery-progress/', include('celery_progress.urls')), # the endpoint is configurable
In your task you should add something like this:
from celery import shared_task
from celery_progress.backend import ProgressRecorder
import time
@shared_task(bind=True)
def my_task(self, seconds):
progress_recorder = ProgressRecorder(self)
result = 0
for i in range(seconds):
time.sleep(1)
result += i
progress_recorder.set_progress(i + 1, seconds)
return result
In the view where you call the task you need to get the task ID like so:
views.py
def progress_view(request):
result = my_task.delay(10)
return render(request, 'display_progress.html', context={'task_id': result.task_id})
Then in the page you want to show the progress bar you just do the following.
display_progress.html
<div class='progress-wrapper'>
<div id='progress-bar' class='progress-bar' style="background-color: #68a9ef; width: 0%;"> </div>
</div>
<div id="progress-bar-message">Waiting for progress to start...</div>
display_progress.html
<script src="{% static 'celery_progress/celery_progress.js' %}"></script>
// vanilla JS version
document.addEventListener("DOMContentLoaded", function () {
var progressUrl = "{% url 'celery_progress:task_status' task_id %}";
CeleryProgressBar.initProgressBar(progressUrl);
});
or
// JQuery
$(function () {
var progressUrl = "{% url 'celery_progress:task_status' task_id %}";
CeleryProgressBar.initProgressBar(progressUrl)
});
If you'd like you can also display the result of your task on the front end.
To do that follow the steps below. Result handling can also be customized.
This is all that's needed to render the result on the page.
display_progress.html
<div id="celery-result"></div>
But more likely you will want to customize how the result looks, which can be done as below:
// JQuery
var progressUrl = "{% url 'celery_progress:task_status' task_id %}";
function customResult(resultElement, result) {
$( resultElement ).append(
$('<p>').text('Sum of all seconds is ' + result)
);
}
$(function () {
CeleryProgressBar.initProgressBar(progressUrl, {
onResult: customResult,
})
});
The initProgressBar
function takes an optional object of options. The following options are supported:
Option | What it does | Default Value |
---|---|---|
pollInterval | How frequently to poll for progress (in milliseconds) | 500 |
progressBarId | Override the ID used for the progress bar | 'progress-bar' |
progressBarMessageId | Override the ID used for the progress bar message | 'progress-bar-message' |
progressBarElement | Override the element used for the progress bar. If specified, progressBarId will be ignored. | document.getElementById(progressBarId) |
progressBarMessageElement | Override the element used for the progress bar message. If specified, progressBarMessageId will be ignored. | document.getElementById(progressBarMessageId) |
resultElementId | Override the ID used for the result | 'celery-result' |
resultElement | Override the element used for the result. If specified, resultElementId will be ignored. | document.getElementById(resultElementId) |
onProgress | function to call when progress is updated | CeleryProgressBar.onProgressDefault |
onSuccess | function to call when progress successfully completes | CeleryProgressBar.onSuccessDefault |
onError | function to call when progress completes with an error | CeleryProgressBar.onErrorDefault |
onResult | function to call when returned non emty result | CeleryProgressBar.onResultDefault |
This library has experimental WebSocket support using Django Channels courtesy of @EJH2.
A working example project leveraging WebSockets is available here.
To use WebSockets, install with pip install celery-progress[websockets,redis]
or
pip install celery-progress[websockets,rabbitmq]
(depending on broker dependencies).
See WebSocketProgressRecorder
and celery_progress_websockets.js
for details.