Muffin-Donald
#############
**Muffin-Donald** is a plugin for the Muffin_ framework that provides support
for asynchronous background tasks, workers, and scheduling.
.. image:: https://github.com/klen/muffin-donald/workflows/tests/badge.svg
:target: https://github.com/klen/muffin-donald/actions
:alt: Tests Status
.. image:: https://img.shields.io/pypi/v/muffin-donald
:target: https://pypi.org/project/muffin-donald/
:alt: PYPI Version
.. image:: https://img.shields.io/pypi/pyversions/muffin-donald
:target: https://pypi.org/project/muffin-donald/
:alt: Python Versions
Contents
========
.. contents::
Features
========
- ✅ Register async tasks
- ✅ Run background workers
- ✅ Schedule periodic tasks (cron or intervals)
- ✅ RPC-style submit and wait for result
- ✅ Muffin plugin integration with lifecycle management
Requirements
============
- python >= 3.10
- muffin >= 0.60.0
- donald >= 0.1.0
Installation
============
Install via pip::
pip install muffin-donald
Usage
=====
Initialize the plugin:
.. code-block:: python
import muffin
from muffin_donald import Plugin
app = muffin.Application("example")
tasks = Plugin(app, backend="redis", backend_params={
"url": "redis://localhost:6379/0"
}, start_worker=True, start_scheduler=True)
Register a task:
.. code-block:: python
@tasks.task()
async def my_task(x, y):
return x + y
Submit task for background execution:
.. code-block:: python
my_task.submit(1, 2)
Submit and wait for result (RPC style):
.. code-block:: python
result = await my_task.submit_and_wait(1, 2)
print("Result:", result) # Result: 3
Schedule a periodic task:
.. code-block:: python
@tasks.task()
async def periodic_task():
print("Periodic task executed")
periodic_task.schedule("*/5 * * * *") # every 5 minutes
Handle task errors with on_error:
.. code-block:: python
@tasks.on_error
async def handle_error(exc):
print("Task error:", exc)
Lifecycle hooks:
.. code-block:: python
@tasks.on_start
async def startup():
print("Tasks manager started")
@tasks.on_stop
async def shutdown():
print("Tasks manager stopped")
Healthcheck command:
Muffin-Donald provides a CLI command for health checks::
muffin <app> tasks-healthcheck
- Returns exit code 0 if healthy
- Returns exit code 1 if unhealthy
Commands
========
+-------------------+-----------------------------+
| Command | Description |
+===================+=============================+
| tasks-worker | Run the worker process |
+-------------------+-----------------------------+
| tasks-scheduler | Run the scheduler |
+-------------------+-----------------------------+
| tasks-healthcheck | Check manager health |
+-------------------+-----------------------------+
Configuration Options
=====================
You can configure the plugin via parameters or Muffin settings (with ``TASKS_`` prefix):
+------------------+-----------+-------------------------------------+
| Name | Default | Description |
+==================+===========+=====================================+
| log_level | INFO | Logger level |
+------------------+-----------+-------------------------------------+
| log_config | None | Logger config |
+------------------+-----------+-------------------------------------+
| backend | memory | Backend: memory, redis, amqp |
+------------------+-----------+-------------------------------------+
| backend_params | {} | Backend connection params |
+------------------+-----------+-------------------------------------+
| worker_params | {} | Worker params |
+------------------+-----------+-------------------------------------+
| start_worker | False | Auto start a worker on startup |
+------------------+-----------+-------------------------------------+
| start_scheduler | False | Auto start a scheduler on startup |
+------------------+-----------+-------------------------------------+
Example in Muffin settings:
.. code-block:: python
TASKS_BACKEND = "redis"
TASKS_BACKEND_PARAMS = {"url": "redis://localhost:6379/0"}
TASKS_START_WORKER = True
TASKS_START_SCHEDULER = True
Testing
=======
Example using ``manage_lifespan``:
.. code-block:: python
import pytest
from asgi_tools.tests import manage_lifespan
async def test_tasks(app, tasks):
async with manage_lifespan(app):
result = await my_task.submit_and_wait(1, 2)
assert result == 3
Bug Tracker
===========
Please report issues or suggestions at https://github.com/klen/muffin-donald/issues
Contributing
============
Development happens at: https://github.com/klen/muffin-donald
Contributors
============
- klen_ (Kirill Klenov)
License
=======
Licensed under the MIT license.
.. _klen: https://github.com/klen
.. _Muffin: https://github.com/klen/muffin
Raw data
{
"_id": null,
"home_page": "https://github.com/klen/muffin-donald",
"name": "muffin-donald",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.9",
"maintainer_email": null,
"keywords": "muffin, asyncio, trio, curio",
"author": "Kirill Klenov",
"author_email": "horneds@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/2c/c6/cf5fc6c31c370b106923bc79f47f1e18c1a276e604e97967a6999a009f37/muffin_donald-1.0.1.tar.gz",
"platform": null,
"description": "Muffin-Donald\n#############\n\n**Muffin-Donald** is a plugin for the Muffin_ framework that provides support\nfor asynchronous background tasks, workers, and scheduling.\n\n.. image:: https://github.com/klen/muffin-donald/workflows/tests/badge.svg\n :target: https://github.com/klen/muffin-donald/actions\n :alt: Tests Status\n\n.. image:: https://img.shields.io/pypi/v/muffin-donald\n :target: https://pypi.org/project/muffin-donald/\n :alt: PYPI Version\n\n.. image:: https://img.shields.io/pypi/pyversions/muffin-donald\n :target: https://pypi.org/project/muffin-donald/\n :alt: Python Versions\n\nContents\n========\n\n.. contents::\n\nFeatures\n========\n\n- \u2705 Register async tasks\n- \u2705 Run background workers\n- \u2705 Schedule periodic tasks (cron or intervals)\n- \u2705 RPC-style submit and wait for result\n- \u2705 Muffin plugin integration with lifecycle management\n\nRequirements\n============\n\n- python >= 3.10\n- muffin >= 0.60.0\n- donald >= 0.1.0\n\nInstallation\n============\n\nInstall via pip::\n\n pip install muffin-donald\n\nUsage\n=====\n\nInitialize the plugin:\n\n.. code-block:: python\n\n import muffin\n from muffin_donald import Plugin\n\n app = muffin.Application(\"example\")\n\n tasks = Plugin(app, backend=\"redis\", backend_params={\n \"url\": \"redis://localhost:6379/0\"\n }, start_worker=True, start_scheduler=True)\n\nRegister a task:\n\n.. code-block:: python\n\n @tasks.task()\n async def my_task(x, y):\n return x + y\n\nSubmit task for background execution:\n\n.. code-block:: python\n\n my_task.submit(1, 2)\n\nSubmit and wait for result (RPC style):\n\n.. code-block:: python\n\n result = await my_task.submit_and_wait(1, 2)\n print(\"Result:\", result) # Result: 3\n\nSchedule a periodic task:\n\n.. code-block:: python\n\n @tasks.task()\n async def periodic_task():\n print(\"Periodic task executed\")\n\n periodic_task.schedule(\"*/5 * * * *\") # every 5 minutes\n\nHandle task errors with on_error:\n\n.. code-block:: python\n\n @tasks.on_error\n async def handle_error(exc):\n print(\"Task error:\", exc)\n\nLifecycle hooks:\n\n.. code-block:: python\n\n @tasks.on_start\n async def startup():\n print(\"Tasks manager started\")\n\n @tasks.on_stop\n async def shutdown():\n print(\"Tasks manager stopped\")\n\nHealthcheck command:\n\nMuffin-Donald provides a CLI command for health checks::\n\n muffin <app> tasks-healthcheck\n\n- Returns exit code 0 if healthy\n- Returns exit code 1 if unhealthy\n\nCommands\n========\n\n+-------------------+-----------------------------+\n| Command | Description |\n+===================+=============================+\n| tasks-worker | Run the worker process |\n+-------------------+-----------------------------+\n| tasks-scheduler | Run the scheduler |\n+-------------------+-----------------------------+\n| tasks-healthcheck | Check manager health |\n+-------------------+-----------------------------+\n\nConfiguration Options\n=====================\n\nYou can configure the plugin via parameters or Muffin settings (with ``TASKS_`` prefix):\n\n+------------------+-----------+-------------------------------------+\n| Name | Default | Description |\n+==================+===========+=====================================+\n| log_level | INFO | Logger level |\n+------------------+-----------+-------------------------------------+\n| log_config | None | Logger config |\n+------------------+-----------+-------------------------------------+\n| backend | memory | Backend: memory, redis, amqp |\n+------------------+-----------+-------------------------------------+\n| backend_params | {} | Backend connection params |\n+------------------+-----------+-------------------------------------+\n| worker_params | {} | Worker params |\n+------------------+-----------+-------------------------------------+\n| start_worker | False | Auto start a worker on startup |\n+------------------+-----------+-------------------------------------+\n| start_scheduler | False | Auto start a scheduler on startup |\n+------------------+-----------+-------------------------------------+\n\nExample in Muffin settings:\n\n.. code-block:: python\n\n TASKS_BACKEND = \"redis\"\n TASKS_BACKEND_PARAMS = {\"url\": \"redis://localhost:6379/0\"}\n TASKS_START_WORKER = True\n TASKS_START_SCHEDULER = True\n\nTesting\n=======\n\nExample using ``manage_lifespan``:\n\n.. code-block:: python\n\n import pytest\n from asgi_tools.tests import manage_lifespan\n\n async def test_tasks(app, tasks):\n async with manage_lifespan(app):\n result = await my_task.submit_and_wait(1, 2)\n assert result == 3\n\nBug Tracker\n===========\n\nPlease report issues or suggestions at https://github.com/klen/muffin-donald/issues\n\nContributing\n============\n\nDevelopment happens at: https://github.com/klen/muffin-donald\n\nContributors\n============\n\n- klen_ (Kirill Klenov)\n\nLicense\n=======\n\nLicensed under the MIT license.\n\n.. _klen: https://github.com/klen\n.. _Muffin: https://github.com/klen/muffin\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "It's a plugin for Muffin framework which provides support for external APIs",
"version": "1.0.1",
"project_urls": {
"Homepage": "https://github.com/klen/muffin-donald",
"Repository": "https://github.com/klen/muffin-donald"
},
"split_keywords": [
"muffin",
" asyncio",
" trio",
" curio"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "932b538b1cb2eaf2e5a53dcfb935796672710ebac1bb1f93022297ab3e62dc97",
"md5": "ca55db4d05eabf093be6b293a0d970bc",
"sha256": "614af44b59261f78cec8403e19914473413c1b18852a93d7e0e7e18da036e962"
},
"downloads": -1,
"filename": "muffin_donald-1.0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "ca55db4d05eabf093be6b293a0d970bc",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.9",
"size": 5081,
"upload_time": "2025-07-11T18:37:43",
"upload_time_iso_8601": "2025-07-11T18:37:43.410040Z",
"url": "https://files.pythonhosted.org/packages/93/2b/538b1cb2eaf2e5a53dcfb935796672710ebac1bb1f93022297ab3e62dc97/muffin_donald-1.0.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "2cc6cf5fc6c31c370b106923bc79f47f1e18c1a276e604e97967a6999a009f37",
"md5": "d86cee3faa43bb411d91c5f5315f8279",
"sha256": "5dd2159a754a5f679ff03d2c5044c9ec373025304196bcf1db8dda6023356747"
},
"downloads": -1,
"filename": "muffin_donald-1.0.1.tar.gz",
"has_sig": false,
"md5_digest": "d86cee3faa43bb411d91c5f5315f8279",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.9",
"size": 4712,
"upload_time": "2025-07-11T18:37:44",
"upload_time_iso_8601": "2025-07-11T18:37:44.528450Z",
"url": "https://files.pythonhosted.org/packages/2c/c6/cf5fc6c31c370b106923bc79f47f1e18c1a276e604e97967a6999a009f37/muffin_donald-1.0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-11 18:37:44",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "klen",
"github_project": "muffin-donald",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "muffin-donald"
}