{"id":13764341,"url":"https://github.com/czue/celery-progress","last_synced_at":"2025-05-14T10:10:34.431Z","repository":{"id":43773161,"uuid":"118240346","full_name":"czue/celery-progress","owner":"czue","description":"Drop in, configurable, dependency-free progress bars for your Django/Celery applications.","archived":false,"fork":false,"pushed_at":"2025-01-30T07:19:25.000Z","size":170,"stargazers_count":486,"open_issues_count":19,"forks_count":91,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-05-14T04:17:53.012Z","etag":null,"topics":["celery","django","hacktoberfest","javascript"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/czue.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-01-20T12:20:49.000Z","updated_at":"2025-04-15T15:39:32.000Z","dependencies_parsed_at":"2024-01-11T23:24:35.945Z","dependency_job_id":"32bf569f-5aa8-46ae-9f8a-4453de6ba418","html_url":"https://github.com/czue/celery-progress","commit_stats":{"total_commits":161,"total_committers":23,"mean_commits":7.0,"dds":0.7142857142857143,"last_synced_commit":"b495ff8c3c7e21bff4f14a4f988ce74c7c36a48b"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/czue%2Fcelery-progress","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/czue%2Fcelery-progress/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/czue%2Fcelery-progress/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/czue%2Fcelery-progress/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/czue","download_url":"https://codeload.github.com/czue/celery-progress/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254120170,"owners_count":22017953,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["celery","django","hacktoberfest","javascript"],"created_at":"2024-08-03T16:00:19.230Z","updated_at":"2025-05-14T10:10:34.390Z","avatar_url":"https://github.com/czue.png","language":"Python","readme":"# Celery Progress Bars for Django\n\nDrop in, dependency-free progress bars for your Django/Celery applications.\n\nSuper simple setup. Lots of customization available.\n\n## Demo\n\n[Celery Progress Bar demo on SaaS Pegasus](https://www.saaspegasus.com/guides/celery-progress-demo/)\n\n### Github demo application: build a download progress bar for Django\nStarting with Celery can be challenging, [eeintech](https://github.com/eeintech) built a complete [Django demo application](https://github.com/eeintech/django-celery-progress-demo) along with a [step-by-step guide](https://eeinte.ch/stream/progress-bar-django-using-celery/) to get you started on building your own progress bar!\n\n## Installation\n\nIf you haven't already, make sure you have properly [set up celery in your project](https://docs.celeryq.dev/en/stable/getting-started/first-steps-with-celery.html#first-steps).\n\nThen install this library:\n\n```bash\npip install celery-progress\n```\n\n## Usage\n\n### Prerequisites\n\nFirst add `celery_progress` to your `INSTALLED_APPS` in `settings.py`.\n\nThen add the following url config to your main `urls.py`:\n\n```python\nfrom django.urls import path, include\n\nurlpatterns = [\n    # your project's patterns here\n    ...\n    path(r'^celery-progress/', include('celery_progress.urls')),  # add this line (the endpoint is configurable)\n]   \n```\n\n### Recording Progress\n\nIn your task you should add something like this:\n\n```python\nfrom celery import shared_task\nfrom celery_progress.backend import ProgressRecorder\nimport time\n\n@shared_task(bind=True)\ndef my_task(self, seconds):\n    progress_recorder = ProgressRecorder(self)\n    result = 0\n    for i in range(seconds):\n        time.sleep(1)\n        result += i\n        progress_recorder.set_progress(i + 1, seconds)\n    return result\n```\n\nYou can add an optional progress description like this:\n\n```python\n  progress_recorder.set_progress(i + 1, seconds, description='my progress description')\n```\n\n### Displaying progress\n\nIn the view where you call the task you need to get the task ID like so:\n\n**views.py**\n```python\ndef progress_view(request):\n    result = my_task.delay(10)\n    return render(request, 'display_progress.html', context={'task_id': result.task_id})\n```\n\nThen in the page you want to show the progress bar you just do the following.\n\n#### Add the following HTML wherever you want your progress bar to appear:\n\n**display_progress.html**\n```html\n\u003cdiv class='progress-wrapper'\u003e\n  \u003cdiv id='progress-bar' class='progress-bar' style=\"background-color: #68a9ef; width: 0%;\"\u003e\u0026nbsp;\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv id=\"progress-bar-message\"\u003eWaiting for progress to start...\u003c/div\u003e\n```\n\n#### Import the javascript file.\n\n**display_progress.html**\n```html\n\u003cscript src=\"{% static 'celery_progress/celery_progress.js' %}\"\u003e\u003c/script\u003e\n```\n\n#### Initialize the progress bar:\n\n```javascript\n// vanilla JS version\ndocument.addEventListener(\"DOMContentLoaded\", function () {\n  var progressUrl = \"{% url 'celery_progress:task_status' task_id %}\";\n  CeleryProgressBar.initProgressBar(progressUrl);\n});\n```\n\nor\n\n```javascript\n// JQuery\n$(function () {\n  var progressUrl = \"{% url 'celery_progress:task_status' task_id %}\";\n  CeleryProgressBar.initProgressBar(progressUrl)\n});\n```\n\n### Displaying the result of a task\n\nIf you'd like you can also display the result of your task on the front end. \n\nTo do that follow the steps below. Result handling can also be customized.\n\n#### Initialize the result block:\n\nThis is all that's needed to render the result on the page.\n\n**display_progress.html**\n```html\n\u003cdiv id=\"celery-result\"\u003e\u003c/div\u003e\n```\n\nBut more likely you will want to customize how the result looks, which can be done as below:\n\n```javascript\n// JQuery\nvar progressUrl = \"{% url 'celery_progress:task_status' task_id %}\";\n\nfunction customResult(resultElement, result) {\n  $( resultElement ).append(\n    $('\u003cp\u003e').text('Sum of all seconds is ' + result)\n  );\n}\n\n$(function () {\n  CeleryProgressBar.initProgressBar(progressUrl, {\n    onResult: customResult,\n  })\n});\n```\n\n### Working with Groups\n\nThis library includes experimental support for working with [Celery groups](https://docs.celeryq.dev/en/stable/userguide/canvas.html#groups).\nYou can use the `\"group_status\"` URL endpoint for this. Here is a basic example:\n\n**Example task:**\n\n```python\n@shared_task(bind=True)\ndef add(self, x, y):\n    return x + y\n```\n\n**Calling view:**\n\n```python\nfrom celery import group\nfrom .tasks import add\n\ndef progress_view(request):\n    task_group = group(add.s(i, i) for i in range(100))\n    group_result = task_group.apply_async()\n    # you must explicitly call the save function on the group_result after calling the tasks\n    group_result.save()\n    return render(request, 'display_progress.html', context={'task_id': group_result.id})\n\n```\n\n**Template:**\n\n```html\ndocument.addEventListener(\"DOMContentLoaded\", function () {\n  var progressUrl = \"{% url 'celery_progress:group_status' task_id %}\";\n  CeleryProgressBar.initProgressBar(progressUrl);\n});\n```\n\n## Customization\n\nThe `initProgressBar` function takes an optional object of options. The following options are supported:\n\n| Option | What it does | Default Value |\n|--------|--------------|---------------|\n| pollInterval | How frequently to poll for progress (in milliseconds) | 500 |\n| progressBarId | Override the ID used for the progress bar | 'progress-bar' |\n| progressBarMessageId | Override the ID used for the progress bar message | 'progress-bar-message' |\n| progressBarElement | Override the *element* used for the progress bar. If specified, progressBarId will be ignored. | document.getElementById(progressBarId) |\n| progressBarMessageElement | Override the *element* used for the progress bar message. If specified, progressBarMessageId will be ignored. | document.getElementById(progressBarMessageId) |\n| resultElementId | Override the ID used for the result | 'celery-result' |\n| resultElement | Override the *element* used for the result. If specified, resultElementId will be ignored. | document.getElementById(resultElementId) |\n| onProgress | function to call when progress is updated | onProgressDefault |\n| onSuccess | function to call when progress successfully completes | onSuccessDefault |\n| onError | function to call on a known error with no specified handler | onErrorDefault |\n| onRetry | function to call when a task attempts to retry | onRetryDefault |\n| onIgnored | function to call when a task result is ignored | onIgnoredDefault |\n| onTaskError | function to call when progress completes with an error | onError |\n| onNetworkError | function to call on a network error (ignored by WebSocket) | onError |\n| onHttpError | function to call on a non-200 response (ignored by WebSocket) | onError |\n| onDataError | function to call on a response that's not JSON or has invalid schema due to a programming error | onError |\n| onResult | function to call when returned non empty result | CeleryProgressBar.onResultDefault |\n| barColors | dictionary containing color values for various progress bar states. Colors that are not specified will defer to defaults | barColorsDefault |\n| defaultMessages | dictionary containing default messages that can be overridden | see below |\n\nThe `barColors` option allows you to customize the color of each progress bar state by passing a dictionary of key-value pairs of `state: #hexcode`. The defaults are shown below.\n\n| State | Hex Code | Image Color | \n|-------|----------|:-------------:|\n| success | #76ce60 | ![#76ce60](https://via.placeholder.com/15/76ce60/000000?text=+) |\n| error | #dc4f63 | ![#dc4f63](https://via.placeholder.com/15/dc4f63/000000?text=+) |\n| progress | #68a9ef | ![#68a9ef](https://via.placeholder.com/15/68a9ef/000000?text=+) |\n| ignored | #7a7a7a | ![#7a7a7a](https://via.placeholder.com/15/7a7a7a/000000?text=+) |\n\nThe `defaultMessages` option allows you to override some default messages in the UI. At the moment these are:\n\n| Message Id | When Shown | Default Value |\n|-------|----------|:-------------:|\n| waiting | Task is waiting to start | 'Waiting for task to start...'\n| started | Task has started but reports no progress | 'Task started...'\n\n# WebSocket Support\n\nAdditionally, this library offers WebSocket support using [Django Channels](https://channels.readthedocs.io/en/latest/)\ncourtesy of [EJH2](https://github.com/EJH2/).\n\nA working example project leveraging WebSockets is [available here](https://github.com/EJH2/cp_ws-example).\n\nTo use WebSockets, install with `pip install celery-progress[websockets,redis]` or\n`pip install celery-progress[websockets,rabbitmq]` (depending on broker dependencies).\n\nSee `WebSocketProgressRecorder` and `websockets.js` for details.\n\n# Securing the get_progress endpoint\nBy default, anyone can see the status and result of any task by accessing `/celery-progress/\u003ctask_id\u003e`\n\nTo limit access, you need to wrap `get_progress()` in a view of your own which implements the permissions check, and create a new url routing to point to your view.  Make sure to remove any existing (unprotected) celery progress urls from your root urlconf at the same time.\n\n\nFor example, requiring login with a class-based view:\n```python\n\n# views.py\nfrom celery_progress.views import get_progress\nfrom django.contrib.auth.mixins import LoginRequiredMixin\nfrom django.views.generic import View\n\nclass TaskStatus(LoginRequiredMixin, View):\n    def get(self, request, task_id, *args, **kwargs):\n        # Other checks could go here\n        return get_progress(request, task_id=task_id)\n```\n\n```python\n# urls.py\nfrom django.urls import path\nfrom . import views\n\nurlpatterns = [\n    ...\n    path('task-status/\u003cuuid:task_id\u003e', views.TaskStatus.as_view(), name='task_status'),\n    ...\n]\n```\n\nRequiring login with a function-based view:\n```python\n\n# views.py\nfrom celery_progress.views import get_progress\nfrom django.contrib.auth.decorators import login_required\n\n@login_required\ndef task_status(request, task_id):\n    # Other checks could go here\n    return get_progress(request, task_id)\n```\n\n```python\n# urls.py\nfrom django.urls import path\n\nfrom . import views\n\nurlpatterns = [\n    ...\n    path('task-status/\u003cuuid:task_id\u003e', views.task_status, name='task_status'),\n    ...\n]\n```\n\n\nAny links to `'celery_progress:task_status'` will need to be changed to point to your new endpoint.\n\n","funding_links":[],"categories":["Administration and Monitoring"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fczue%2Fcelery-progress","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fczue%2Fcelery-progress","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fczue%2Fcelery-progress/lists"}