django-celery-beat


Namedjango-celery-beat JSON
Version 2.7.0 PyPI version JSON
download
home_pagehttps://github.com/celery/django-celery-beat
SummaryDatabase-backed Periodic Tasks.
upload_time2024-08-22 11:12:24
maintainerNone
docs_urlNone
authorAsif Saif Uddin, Ask Solem
requires_python>=3.8
licenseBSD
keywords django celery beat periodic task database
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            =====================================================================
 Database-backed Periodic Tasks
=====================================================================

|build-status| |coverage| |license| |wheel| |pyversion| |pyimp|

:Version: 2.7.0
:Web: http://django-celery-beat.readthedocs.io/
:Download: http://pypi.python.org/pypi/django-celery-beat
:Source: http://github.com/celery/django-celery-beat
:Keywords: django, celery, beat, periodic task, cron, scheduling

About
=====

This extension enables you to store the periodic task schedule in the
database.

The periodic tasks can be managed from the Django Admin interface, where you
can create, edit and delete periodic tasks and how often they should run.

Using the Extension
===================

Usage and installation instructions for this extension are available
from the `Celery documentation`_.

.. _`Celery documentation`:
    http://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html#using-custom-scheduler-classes

Important Warning about Time Zones
==================================

.. warning::
   If you change the Django ``TIME_ZONE`` setting your periodic task schedule
   will still be based on the old timezone.

   To fix that you would have to reset the "last run time" for each periodic task:

.. code-block:: Python

        >>> from django_celery_beat.models import PeriodicTask, PeriodicTasks
        >>> PeriodicTask.objects.all().update(last_run_at=None)
        >>> PeriodicTasks.update_changed()



.. note::
   This will reset the state as if the periodic tasks have never run before.


Models
======

- ``django_celery_beat.models.PeriodicTask``

This model defines a single periodic task to be run.

It must be associated with a schedule, which defines how often the task should
run.

- ``django_celery_beat.models.IntervalSchedule``

A schedule that runs at a specific interval (e.g. every 5 seconds).

- ``django_celery_beat.models.CrontabSchedule``

A schedule with fields like entries in cron:
``minute hour day-of-week day_of_month month_of_year``.

- ``django_celery_beat.models.PeriodicTasks``

This model is only used as an index to keep track of when the schedule has
changed.

Whenever you update a ``PeriodicTask`` a counter in this table is also
incremented, which tells the ``celery beat`` service to reload the schedule
from the database.

If you update periodic tasks in bulk, you will need to update the counter
manually:

.. code-block:: Python

        >>> from django_celery_beat.models import PeriodicTasks
        >>> PeriodicTasks.update_changed()

Example creating interval-based periodic task
---------------------------------------------

To create a periodic task executing at an interval you must first
create the interval object:

.. code-block:: Python

        >>> from django_celery_beat.models import PeriodicTask, IntervalSchedule

        # executes every 10 seconds.
        >>> schedule, created = IntervalSchedule.objects.get_or_create(
        ...     every=10,
        ...     period=IntervalSchedule.SECONDS,
        ... )

That's all the fields you need: a period type and the frequency.

You can choose between a specific set of periods:


- ``IntervalSchedule.DAYS``
- ``IntervalSchedule.HOURS``
- ``IntervalSchedule.MINUTES``
- ``IntervalSchedule.SECONDS``
- ``IntervalSchedule.MICROSECONDS``

.. note::
    If you have multiple periodic tasks executing every 10 seconds,
    then they should all point to the same schedule object.

There's also a "choices tuple" available should you need to present this
to the user:


.. code-block:: Python

        >>> IntervalSchedule.PERIOD_CHOICES


Now that we have defined the schedule object, we can create the periodic task
entry:

.. code-block:: Python

        >>> PeriodicTask.objects.create(
        ...     interval=schedule,                  # we created this above.
        ...     name='Importing contacts',          # simply describes this periodic task.
        ...     task='proj.tasks.import_contacts',  # name of task.
        ... )


Note that this is a very basic example, you can also specify the arguments
and keyword arguments used to execute the task, the ``queue`` to send it
to[*], and set an expiry time.

Here's an example specifying the arguments, note how JSON serialization is
required:

.. code-block:: Python

        >>> import json
        >>> from datetime import datetime, timedelta

        >>> PeriodicTask.objects.create(
        ...     interval=schedule,                  # we created this above.
        ...     name='Importing contacts',          # simply describes this periodic task.
        ...     task='proj.tasks.import_contacts',  # name of task.
        ...     args=json.dumps(['arg1', 'arg2']),
        ...     kwargs=json.dumps({
        ...        'be_careful': True,
        ...     }),
        ...     expires=datetime.utcnow() + timedelta(seconds=30)
        ... )


.. [*] you can also use low-level AMQP routing using the ``exchange`` and
       ``routing_key`` fields.

Example creating crontab-based periodic task
--------------------------------------------

A crontab schedule has the fields: ``minute``, ``hour``, ``day_of_week``,
``day_of_month`` and ``month_of_year``, so if you want the equivalent
of a ``30 * * * *`` (execute 30 minutes past every hour) crontab entry you specify:

.. code-block:: Python

        >>> from django_celery_beat.models import CrontabSchedule, PeriodicTask
        >>> schedule, _ = CrontabSchedule.objects.get_or_create(
        ...     minute='30',
        ...     hour='*',
        ...     day_of_week='*',
        ...     day_of_month='*',
        ...     month_of_year='*',
        ...     timezone=zoneinfo.ZoneInfo('Canada/Pacific')
        ... )

The crontab schedule is linked to a specific timezone using the 'timezone' input parameter.

Then to create a periodic task using this schedule, use the same approach as
the interval-based periodic task earlier in this document, but instead
of ``interval=schedule``, specify ``crontab=schedule``:

.. code-block:: Python

        >>> PeriodicTask.objects.create(
        ...     crontab=schedule,
        ...     name='Importing contacts',
        ...     task='proj.tasks.import_contacts',
        ... )

Temporarily disable a periodic task
-----------------------------------

You can use the ``enabled`` flag to temporarily disable a periodic task:

.. code-block:: Python

        >>> periodic_task.enabled = False
        >>> periodic_task.save()


Example running periodic tasks
-----------------------------------

The periodic tasks still need 'workers' to execute them.
So make sure the default **Celery** package is installed.
(If not installed, please follow the installation instructions
here: https://github.com/celery/celery)

Both the worker and beat services need to be running at the same time.

1. Start a Celery worker service (specify your Django project name)::

   $ celery -A [project-name] worker --loglevel=info


2. As a separate process, start the beat service (specify the Django scheduler)::

    $ celery -A [project-name] beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler

   **OR** you can use the -S (scheduler flag), for more options see ``celery beat --help``)::

    $ celery -A [project-name] beat -l info -S django

   Also, as an alternative, you can run the two steps above (worker and beat services)
   with only one command (recommended for **development environment only**)::

    $ celery -A [project-name] worker --beat --scheduler django --loglevel=info


3. Now you can add and manage your periodic tasks from the Django Admin interface.




Installation
============

You can install django-celery-beat either via the Python Package Index (PyPI)
or from source.

To install using ``pip``:

.. code-block:: bash

        $ pip install --upgrade django-celery-beat

Downloading and installing from source
--------------------------------------

Download the latest version of django-celery-beat from
http://pypi.python.org/pypi/django-celery-beat

You can install it by doing the following :

.. code-block:: bash

        $ python3 -m venv .venv
        $ source .venv/bin/activate
        $ pip install --upgrade build pip
        $ tar xvfz django-celery-beat-0.0.0.tar.gz
        $ cd django-celery-beat-0.0.0
        $ python -m build
        $ pip install --upgrade .

After installation, add ``django_celery_beat`` to Django's settings module:


.. code-block:: Python

        INSTALLED_APPS = [
            ...,
            'django_celery_beat',
        ]


Run the ``django_celery_beat`` migrations using:

.. code-block:: bash

        $ python manage.py migrate django_celery_beat


Using the development version
-----------------------------

With pip
~~~~~~~~

You can install the latest main version of django-celery-beat using the following
pip command:

.. code-block:: bash

        $ pip install git+https://github.com/celery/django-celery-beat#egg=django-celery-beat


Developing django-celery-beat
-----------------------------

To spin up a local development copy of django-celery-beat with Django admin at http://127.0.0.1:58000/admin/ run:

.. code-block:: bash

        $ docker-compose up --build

Log-in as user ``admin`` with password ``admin``.


TZ Awareness:
-------------

If you have a project that is time zone naive, you can set ``DJANGO_CELERY_BEAT_TZ_AWARE=False`` in your settings file.


.. |build-status| image:: https://github.com/celery/django-celery-beat/actions/workflows/test.yml/badge.svg
    :alt: Build status
    :target: https://github.com/celery/django-celery-beat/actions/workflows/test.yml

.. |coverage| image:: https://codecov.io/github/celery/django-celery-beat/coverage.svg?branch=master
    :target: https://codecov.io/github/celery/django-celery-beat?branch=master

.. |license| image:: https://img.shields.io/pypi/l/django-celery-beat.svg#foo
    :alt: BSD License
    :target: https://opensource.org/licenses/BSD-3-Clause

.. |wheel| image:: https://img.shields.io/pypi/wheel/django-celery-beat.svg#foo
    :alt: django-celery-beat can be installed via wheel
    :target: http://pypi.python.org/pypi/django-celery-beat/

.. |pyversion| image:: https://img.shields.io/pypi/pyversions/django-celery-beat.svg#foo
    :alt: Supported Python versions.
    :target: http://pypi.python.org/pypi/django-celery-beat/

.. |pyimp| image:: https://img.shields.io/pypi/implementation/django-celery-beat.svg#foo
    :alt: Support Python implementations.
    :target: http://pypi.python.org/pypi/django-celery-beat/

django-celery-beat as part of the Tidelift Subscription
-------------------------------------------------------

The maintainers of django-celery-beat and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. `Learn more`_.

.. _Learn more: https://tidelift.com/subscription/pkg/pypi-django-celery-beat?utm_source=pypi-django-celery-beat&utm_medium=referral&utm_campaign=readme&utm_term=repo

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/celery/django-celery-beat",
    "name": "django-celery-beat",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "django celery beat periodic task database",
    "author": "Asif Saif Uddin, Ask Solem",
    "author_email": "auvipy@gmail.com, ask@celeryproject.org",
    "download_url": "https://files.pythonhosted.org/packages/03/8f/8a18f234173001bd7a7d63826d2d7f456b38031c892514d27c0f7aea10be/django_celery_beat-2.7.0.tar.gz",
    "platform": "any",
    "description": "=====================================================================\n Database-backed Periodic Tasks\n=====================================================================\n\n|build-status| |coverage| |license| |wheel| |pyversion| |pyimp|\n\n:Version: 2.7.0\n:Web: http://django-celery-beat.readthedocs.io/\n:Download: http://pypi.python.org/pypi/django-celery-beat\n:Source: http://github.com/celery/django-celery-beat\n:Keywords: django, celery, beat, periodic task, cron, scheduling\n\nAbout\n=====\n\nThis extension enables you to store the periodic task schedule in the\ndatabase.\n\nThe periodic tasks can be managed from the Django Admin interface, where you\ncan create, edit and delete periodic tasks and how often they should run.\n\nUsing the Extension\n===================\n\nUsage and installation instructions for this extension are available\nfrom the `Celery documentation`_.\n\n.. _`Celery documentation`:\n    http://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html#using-custom-scheduler-classes\n\nImportant Warning about Time Zones\n==================================\n\n.. warning::\n   If you change the Django ``TIME_ZONE`` setting your periodic task schedule\n   will still be based on the old timezone.\n\n   To fix that you would have to reset the \"last run time\" for each periodic task:\n\n.. code-block:: Python\n\n        >>> from django_celery_beat.models import PeriodicTask, PeriodicTasks\n        >>> PeriodicTask.objects.all().update(last_run_at=None)\n        >>> PeriodicTasks.update_changed()\n\n\n\n.. note::\n   This will reset the state as if the periodic tasks have never run before.\n\n\nModels\n======\n\n- ``django_celery_beat.models.PeriodicTask``\n\nThis model defines a single periodic task to be run.\n\nIt must be associated with a schedule, which defines how often the task should\nrun.\n\n- ``django_celery_beat.models.IntervalSchedule``\n\nA schedule that runs at a specific interval (e.g. every 5 seconds).\n\n- ``django_celery_beat.models.CrontabSchedule``\n\nA schedule with fields like entries in cron:\n``minute hour day-of-week day_of_month month_of_year``.\n\n- ``django_celery_beat.models.PeriodicTasks``\n\nThis model is only used as an index to keep track of when the schedule has\nchanged.\n\nWhenever you update a ``PeriodicTask`` a counter in this table is also\nincremented, which tells the ``celery beat`` service to reload the schedule\nfrom the database.\n\nIf you update periodic tasks in bulk, you will need to update the counter\nmanually:\n\n.. code-block:: Python\n\n        >>> from django_celery_beat.models import PeriodicTasks\n        >>> PeriodicTasks.update_changed()\n\nExample creating interval-based periodic task\n---------------------------------------------\n\nTo create a periodic task executing at an interval you must first\ncreate the interval object:\n\n.. code-block:: Python\n\n        >>> from django_celery_beat.models import PeriodicTask, IntervalSchedule\n\n        # executes every 10 seconds.\n        >>> schedule, created = IntervalSchedule.objects.get_or_create(\n        ...     every=10,\n        ...     period=IntervalSchedule.SECONDS,\n        ... )\n\nThat's all the fields you need: a period type and the frequency.\n\nYou can choose between a specific set of periods:\n\n\n- ``IntervalSchedule.DAYS``\n- ``IntervalSchedule.HOURS``\n- ``IntervalSchedule.MINUTES``\n- ``IntervalSchedule.SECONDS``\n- ``IntervalSchedule.MICROSECONDS``\n\n.. note::\n    If you have multiple periodic tasks executing every 10 seconds,\n    then they should all point to the same schedule object.\n\nThere's also a \"choices tuple\" available should you need to present this\nto the user:\n\n\n.. code-block:: Python\n\n        >>> IntervalSchedule.PERIOD_CHOICES\n\n\nNow that we have defined the schedule object, we can create the periodic task\nentry:\n\n.. code-block:: Python\n\n        >>> PeriodicTask.objects.create(\n        ...     interval=schedule,                  # we created this above.\n        ...     name='Importing contacts',          # simply describes this periodic task.\n        ...     task='proj.tasks.import_contacts',  # name of task.\n        ... )\n\n\nNote that this is a very basic example, you can also specify the arguments\nand keyword arguments used to execute the task, the ``queue`` to send it\nto[*], and set an expiry time.\n\nHere's an example specifying the arguments, note how JSON serialization is\nrequired:\n\n.. code-block:: Python\n\n        >>> import json\n        >>> from datetime import datetime, timedelta\n\n        >>> PeriodicTask.objects.create(\n        ...     interval=schedule,                  # we created this above.\n        ...     name='Importing contacts',          # simply describes this periodic task.\n        ...     task='proj.tasks.import_contacts',  # name of task.\n        ...     args=json.dumps(['arg1', 'arg2']),\n        ...     kwargs=json.dumps({\n        ...        'be_careful': True,\n        ...     }),\n        ...     expires=datetime.utcnow() + timedelta(seconds=30)\n        ... )\n\n\n.. [*] you can also use low-level AMQP routing using the ``exchange`` and\n       ``routing_key`` fields.\n\nExample creating crontab-based periodic task\n--------------------------------------------\n\nA crontab schedule has the fields: ``minute``, ``hour``, ``day_of_week``,\n``day_of_month`` and ``month_of_year``, so if you want the equivalent\nof a ``30 * * * *`` (execute 30 minutes past every hour) crontab entry you specify:\n\n.. code-block:: Python\n\n        >>> from django_celery_beat.models import CrontabSchedule, PeriodicTask\n        >>> schedule, _ = CrontabSchedule.objects.get_or_create(\n        ...     minute='30',\n        ...     hour='*',\n        ...     day_of_week='*',\n        ...     day_of_month='*',\n        ...     month_of_year='*',\n        ...     timezone=zoneinfo.ZoneInfo('Canada/Pacific')\n        ... )\n\nThe crontab schedule is linked to a specific timezone using the 'timezone' input parameter.\n\nThen to create a periodic task using this schedule, use the same approach as\nthe interval-based periodic task earlier in this document, but instead\nof ``interval=schedule``, specify ``crontab=schedule``:\n\n.. code-block:: Python\n\n        >>> PeriodicTask.objects.create(\n        ...     crontab=schedule,\n        ...     name='Importing contacts',\n        ...     task='proj.tasks.import_contacts',\n        ... )\n\nTemporarily disable a periodic task\n-----------------------------------\n\nYou can use the ``enabled`` flag to temporarily disable a periodic task:\n\n.. code-block:: Python\n\n        >>> periodic_task.enabled = False\n        >>> periodic_task.save()\n\n\nExample running periodic tasks\n-----------------------------------\n\nThe periodic tasks still need 'workers' to execute them.\nSo make sure the default **Celery** package is installed.\n(If not installed, please follow the installation instructions\nhere: https://github.com/celery/celery)\n\nBoth the worker and beat services need to be running at the same time.\n\n1. Start a Celery worker service (specify your Django project name)::\n\n   $ celery -A [project-name] worker --loglevel=info\n\n\n2. As a separate process, start the beat service (specify the Django scheduler)::\n\n    $ celery -A [project-name] beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler\n\n   **OR** you can use the -S (scheduler flag), for more options see ``celery beat --help``)::\n\n    $ celery -A [project-name] beat -l info -S django\n\n   Also, as an alternative, you can run the two steps above (worker and beat services)\n   with only one command (recommended for **development environment only**)::\n\n    $ celery -A [project-name] worker --beat --scheduler django --loglevel=info\n\n\n3. Now you can add and manage your periodic tasks from the Django Admin interface.\n\n\n\n\nInstallation\n============\n\nYou can install django-celery-beat either via the Python Package Index (PyPI)\nor from source.\n\nTo install using ``pip``:\n\n.. code-block:: bash\n\n        $ pip install --upgrade django-celery-beat\n\nDownloading and installing from source\n--------------------------------------\n\nDownload the latest version of django-celery-beat from\nhttp://pypi.python.org/pypi/django-celery-beat\n\nYou can install it by doing the following :\n\n.. code-block:: bash\n\n        $ python3 -m venv .venv\n        $ source .venv/bin/activate\n        $ pip install --upgrade build pip\n        $ tar xvfz django-celery-beat-0.0.0.tar.gz\n        $ cd django-celery-beat-0.0.0\n        $ python -m build\n        $ pip install --upgrade .\n\nAfter installation, add ``django_celery_beat`` to Django's settings module:\n\n\n.. code-block:: Python\n\n        INSTALLED_APPS = [\n            ...,\n            'django_celery_beat',\n        ]\n\n\nRun the ``django_celery_beat`` migrations using:\n\n.. code-block:: bash\n\n        $ python manage.py migrate django_celery_beat\n\n\nUsing the development version\n-----------------------------\n\nWith pip\n~~~~~~~~\n\nYou can install the latest main version of django-celery-beat using the following\npip command:\n\n.. code-block:: bash\n\n        $ pip install git+https://github.com/celery/django-celery-beat#egg=django-celery-beat\n\n\nDeveloping django-celery-beat\n-----------------------------\n\nTo spin up a local development copy of django-celery-beat with Django admin at http://127.0.0.1:58000/admin/ run:\n\n.. code-block:: bash\n\n        $ docker-compose up --build\n\nLog-in as user ``admin`` with password ``admin``.\n\n\nTZ Awareness:\n-------------\n\nIf you have a project that is time zone naive, you can set ``DJANGO_CELERY_BEAT_TZ_AWARE=False`` in your settings file.\n\n\n.. |build-status| image:: https://github.com/celery/django-celery-beat/actions/workflows/test.yml/badge.svg\n    :alt: Build status\n    :target: https://github.com/celery/django-celery-beat/actions/workflows/test.yml\n\n.. |coverage| image:: https://codecov.io/github/celery/django-celery-beat/coverage.svg?branch=master\n    :target: https://codecov.io/github/celery/django-celery-beat?branch=master\n\n.. |license| image:: https://img.shields.io/pypi/l/django-celery-beat.svg#foo\n    :alt: BSD License\n    :target: https://opensource.org/licenses/BSD-3-Clause\n\n.. |wheel| image:: https://img.shields.io/pypi/wheel/django-celery-beat.svg#foo\n    :alt: django-celery-beat can be installed via wheel\n    :target: http://pypi.python.org/pypi/django-celery-beat/\n\n.. |pyversion| image:: https://img.shields.io/pypi/pyversions/django-celery-beat.svg#foo\n    :alt: Supported Python versions.\n    :target: http://pypi.python.org/pypi/django-celery-beat/\n\n.. |pyimp| image:: https://img.shields.io/pypi/implementation/django-celery-beat.svg#foo\n    :alt: Support Python implementations.\n    :target: http://pypi.python.org/pypi/django-celery-beat/\n\ndjango-celery-beat as part of the Tidelift Subscription\n-------------------------------------------------------\n\nThe maintainers of django-celery-beat and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. `Learn more`_.\n\n.. _Learn more: https://tidelift.com/subscription/pkg/pypi-django-celery-beat?utm_source=pypi-django-celery-beat&utm_medium=referral&utm_campaign=readme&utm_term=repo\n",
    "bugtrack_url": null,
    "license": "BSD",
    "summary": "Database-backed Periodic Tasks.",
    "version": "2.7.0",
    "project_urls": {
        "Homepage": "https://github.com/celery/django-celery-beat"
    },
    "split_keywords": [
        "django",
        "celery",
        "beat",
        "periodic",
        "task",
        "database"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "29f8f5a25472222b19258c3a53ce71c4efd171a12ab3c988bb3026dec0522a64",
                "md5": "8c681c4bec7068d6ddbf6fd77d0ab0af",
                "sha256": "851c680d8fbf608ca5fecd5836622beea89fa017bc2b3f94a5b8c648c32d84b1"
            },
            "downloads": -1,
            "filename": "django_celery_beat-2.7.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "8c681c4bec7068d6ddbf6fd77d0ab0af",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 94097,
            "upload_time": "2024-08-22T11:12:23",
            "upload_time_iso_8601": "2024-08-22T11:12:23.172049Z",
            "url": "https://files.pythonhosted.org/packages/29/f8/f5a25472222b19258c3a53ce71c4efd171a12ab3c988bb3026dec0522a64/django_celery_beat-2.7.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "038f8a18f234173001bd7a7d63826d2d7f456b38031c892514d27c0f7aea10be",
                "md5": "5880c12777caf39b4daf7755c0567197",
                "sha256": "8482034925e09b698c05ad61c36ed2a8dbc436724a3fe119215193a4ca6dc967"
            },
            "downloads": -1,
            "filename": "django_celery_beat-2.7.0.tar.gz",
            "has_sig": false,
            "md5_digest": "5880c12777caf39b4daf7755c0567197",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 163472,
            "upload_time": "2024-08-22T11:12:24",
            "upload_time_iso_8601": "2024-08-22T11:12:24.943046Z",
            "url": "https://files.pythonhosted.org/packages/03/8f/8a18f234173001bd7a7d63826d2d7f456b38031c892514d27c0f7aea10be/django_celery_beat-2.7.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-08-22 11:12:24",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "celery",
    "github_project": "django-celery-beat",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "tox": true,
    "lcname": "django-celery-beat"
}
        
Elapsed time: 0.81888s