asyncmq 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- asyncmq-0.1.0/.gitignore +31 -0
- asyncmq-0.1.0/LICENSE +20 -0
- asyncmq-0.1.0/PKG-INFO +214 -0
- asyncmq-0.1.0/README.md +155 -0
- asyncmq-0.1.0/asyncmq/__init__.py +46 -0
- asyncmq-0.1.0/asyncmq/__main__.py +4 -0
- asyncmq-0.1.0/asyncmq/backends/__init__.py +0 -0
- asyncmq-0.1.0/asyncmq/backends/base.py +550 -0
- asyncmq-0.1.0/asyncmq/backends/memory.py +805 -0
- asyncmq-0.1.0/asyncmq/backends/mongodb.py +960 -0
- asyncmq-0.1.0/asyncmq/backends/postgres.py +1097 -0
- asyncmq-0.1.0/asyncmq/backends/redis.py +1316 -0
- asyncmq-0.1.0/asyncmq/cli/__init__.py +0 -0
- asyncmq-0.1.0/asyncmq/cli/__main__.py +60 -0
- asyncmq-0.1.0/asyncmq/cli/info.py +91 -0
- asyncmq-0.1.0/asyncmq/cli/job.py +190 -0
- asyncmq-0.1.0/asyncmq/cli/queue.py +434 -0
- asyncmq-0.1.0/asyncmq/cli/utils.py +128 -0
- asyncmq-0.1.0/asyncmq/cli/worker.py +118 -0
- asyncmq-0.1.0/asyncmq/conf/__init__.py +89 -0
- asyncmq-0.1.0/asyncmq/conf/global_settings.py +291 -0
- asyncmq-0.1.0/asyncmq/core/__init__.py +0 -0
- asyncmq-0.1.0/asyncmq/core/delayed_scanner.py +56 -0
- asyncmq-0.1.0/asyncmq/core/dependencies.py +317 -0
- asyncmq-0.1.0/asyncmq/core/enums.py +56 -0
- asyncmq-0.1.0/asyncmq/core/event.py +115 -0
- asyncmq-0.1.0/asyncmq/core/stalled.py +55 -0
- asyncmq-0.1.0/asyncmq/core/utils/__init__.py +0 -0
- asyncmq-0.1.0/asyncmq/core/utils/logging.py +79 -0
- asyncmq-0.1.0/asyncmq/core/utils/postgres.py +91 -0
- asyncmq-0.1.0/asyncmq/exceptions.py +2 -0
- asyncmq-0.1.0/asyncmq/flow.py +90 -0
- asyncmq-0.1.0/asyncmq/jobs.py +237 -0
- asyncmq-0.1.0/asyncmq/logging.py +240 -0
- asyncmq-0.1.0/asyncmq/protocols/__init__.py +0 -0
- asyncmq-0.1.0/asyncmq/protocols/logging.py +72 -0
- asyncmq-0.1.0/asyncmq/py.typed +1 -0
- asyncmq-0.1.0/asyncmq/queues.py +373 -0
- asyncmq-0.1.0/asyncmq/rate_limiter.py +112 -0
- asyncmq-0.1.0/asyncmq/runners.py +145 -0
- asyncmq-0.1.0/asyncmq/sandbox.py +141 -0
- asyncmq-0.1.0/asyncmq/schedulers.py +155 -0
- asyncmq-0.1.0/asyncmq/stores/__init__.py +0 -0
- asyncmq-0.1.0/asyncmq/stores/base.py +89 -0
- asyncmq-0.1.0/asyncmq/stores/mongodb.py +147 -0
- asyncmq-0.1.0/asyncmq/stores/postgres.py +224 -0
- asyncmq-0.1.0/asyncmq/stores/redis_store.py +164 -0
- asyncmq-0.1.0/asyncmq/tasks.py +227 -0
- asyncmq-0.1.0/asyncmq/workers.py +317 -0
- asyncmq-0.1.0/pyproject.toml +215 -0
asyncmq-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# folders
|
|
2
|
+
*.egg-info/
|
|
3
|
+
.hypothesis/
|
|
4
|
+
.idea/
|
|
5
|
+
.mypy_cache/
|
|
6
|
+
.pytest_cache/
|
|
7
|
+
.scannerwork/
|
|
8
|
+
.tox/
|
|
9
|
+
.venv/
|
|
10
|
+
.vscode/
|
|
11
|
+
__pycache__/
|
|
12
|
+
virtualenv/
|
|
13
|
+
build/
|
|
14
|
+
dist/
|
|
15
|
+
node_modules/
|
|
16
|
+
results/
|
|
17
|
+
site/
|
|
18
|
+
site_lang/
|
|
19
|
+
target/
|
|
20
|
+
|
|
21
|
+
# files
|
|
22
|
+
**/*.so
|
|
23
|
+
**/*.sqlite
|
|
24
|
+
*.iml
|
|
25
|
+
**/*_test*
|
|
26
|
+
.DS_Store
|
|
27
|
+
.coverage
|
|
28
|
+
.coverage.*
|
|
29
|
+
.python-version
|
|
30
|
+
coverage.*
|
|
31
|
+
example.sqlite
|
asyncmq-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright © 2025, Dymmond Ltd. All rights reserved.
|
|
2
|
+
|
|
3
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
|
|
4
|
+
conditions are met:
|
|
5
|
+
|
|
6
|
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
7
|
+
|
|
8
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
|
|
9
|
+
disclaimer in the documentation and/or other materials provided with the distribution.
|
|
10
|
+
|
|
11
|
+
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products
|
|
12
|
+
derived from this software without specific prior written permission.
|
|
13
|
+
|
|
14
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
15
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
16
|
+
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
|
17
|
+
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
18
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
19
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|
20
|
+
THE POSSIBILITY OF SUCH DAMAGE.
|
asyncmq-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: asyncmq
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Async task queue with BullMQ-like features
|
|
5
|
+
Project-URL: Homepage, https://github.com/dymmond/asyncmq
|
|
6
|
+
Project-URL: Documentation, https://asyncmq.dymmond.com
|
|
7
|
+
Project-URL: Changelog, https://asyncmq.dymmond.com/release-notes/
|
|
8
|
+
Project-URL: Funding, https://github.com/sponsors/tarsil
|
|
9
|
+
Project-URL: Source, https://github.com/dymmond/asyncmq
|
|
10
|
+
Author-email: Tiago Silva <tiago@tarsild.io>
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: anyio,asyncio,background-jobs,celery-alternative,concurrency,cron,dead-letter-queue,esmerald,fastapi,job-scheduler,microservices,mongodb,parallelism,postgresql,rate-limiter,redis,retry-policy,task-queue
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Web Environment
|
|
15
|
+
Classifier: Framework :: AnyIO
|
|
16
|
+
Classifier: Framework :: AsyncIO
|
|
17
|
+
Classifier: Intended Audience :: Developers
|
|
18
|
+
Classifier: Intended Audience :: Information Technology
|
|
19
|
+
Classifier: Intended Audience :: System Administrators
|
|
20
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
21
|
+
Classifier: Operating System :: OS Independent
|
|
22
|
+
Classifier: Programming Language :: Python
|
|
23
|
+
Classifier: Programming Language :: Python :: 3
|
|
24
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
27
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
28
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
29
|
+
Classifier: Topic :: Internet
|
|
30
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
31
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
|
|
32
|
+
Classifier: Topic :: Software Development
|
|
33
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
34
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
35
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
36
|
+
Classifier: Typing :: Typed
|
|
37
|
+
Requires-Python: >=3.8
|
|
38
|
+
Requires-Dist: anyio<6.0.0,>=4.9.0
|
|
39
|
+
Requires-Dist: click<9.0.0,>=8.1.8
|
|
40
|
+
Requires-Dist: croniter<7.0.0,>=6.0.0
|
|
41
|
+
Requires-Dist: monkay>=0.4.1
|
|
42
|
+
Requires-Dist: redis>=5.2.1
|
|
43
|
+
Requires-Dist: rich<15.0.0,>=14.0.0
|
|
44
|
+
Provides-Extra: mongo
|
|
45
|
+
Requires-Dist: motor>=3.7.0; extra == 'mongo'
|
|
46
|
+
Provides-Extra: postgres
|
|
47
|
+
Requires-Dist: asyncpg>=0.30.0; extra == 'postgres'
|
|
48
|
+
Provides-Extra: testing
|
|
49
|
+
Requires-Dist: anyio[trio]<6.0.0,>=4.9.0; extra == 'testing'
|
|
50
|
+
Requires-Dist: autoflake<3.0.0,>=2.0.2; extra == 'testing'
|
|
51
|
+
Requires-Dist: black<25.0,==24.1.1; extra == 'testing'
|
|
52
|
+
Requires-Dist: esmerald>=3.7.7; extra == 'testing'
|
|
53
|
+
Requires-Dist: isort<6.0.0,>=5.12.0; extra == 'testing'
|
|
54
|
+
Requires-Dist: pytest-asyncio>=0.26.0; extra == 'testing'
|
|
55
|
+
Requires-Dist: pytest-cov<5.0.0,>=4.0.0; extra == 'testing'
|
|
56
|
+
Requires-Dist: pytest<9.0.0,>=7.2.2; extra == 'testing'
|
|
57
|
+
Requires-Dist: structlog>=25.3.0; extra == 'testing'
|
|
58
|
+
Description-Content-Type: text/markdown
|
|
59
|
+
|
|
60
|
+
# AsyncMQ
|
|
61
|
+
|
|
62
|
+
<p align="center">
|
|
63
|
+
<a href="https://asyncmq.dymmond.com"><img src="https://res.cloudinary.com/dymmond/image/upload/v1746002620/asyncmq/oq2qhgqdlra7rudxaqhl.png" alt="AsyncMQ Logo"></a>
|
|
64
|
+
</p>
|
|
65
|
+
|
|
66
|
+
<p align="center">
|
|
67
|
+
<span>⚡ Supercharge your async applications with tasks so fast, you’ll think you’re bending time itself. ⚡</span>
|
|
68
|
+
</p>
|
|
69
|
+
|
|
70
|
+
<p align="center">
|
|
71
|
+
<a href="https://github.com/dymmond/asyncmq/actions/workflows/test-suite.yml/badge.svg?event=push&branch=main" target="_blank">
|
|
72
|
+
<img src="https://github.com/dymmond/asyncmq/actions/workflows/test-suite.yml/badge.svg?event=push&branch=main" alt="Test Suite">
|
|
73
|
+
</a>
|
|
74
|
+
<a href="https://pypi.org/project/asyncmq" target="_blank">
|
|
75
|
+
<img src="https://img.shields.io/pypi/v/asyncmq?color=%2334D058&label=pypi%20package" alt="Package version">
|
|
76
|
+
</a>
|
|
77
|
+
<a href="https://img.shields.io/pypi/pyversions/asyncmq.svg?color=%2334D058" target="_blank">
|
|
78
|
+
<img src="https://img.shields.io/pypi/pyversions/asyncmq.svg?color=%2334D058" alt="Supported Python versions">
|
|
79
|
+
</a>
|
|
80
|
+
</p>
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
Welcome to **AsyncMQ**, the modern task queue that brings **powerful**, **flexible**, and **lightning-fast** background processing to your Python stack. Whether you're building microservices, handling high-throughput data pipelines, or just want reliable delayed jobs, AsyncMQ has your back.
|
|
85
|
+
|
|
86
|
+
## 🚀 Why Choose AsyncMQ?
|
|
87
|
+
|
|
88
|
+
1. **Asyncio & AnyIO-Native**
|
|
89
|
+
No more wrestling with threads or callbacks—AsyncMQ is built on `asyncio` and `anyio`, so your tasks are non-blocking and integrate seamlessly into modern async frameworks like FastAPI and Esmerald.
|
|
90
|
+
|
|
91
|
+
2. **Multi-Backend Flexibility**
|
|
92
|
+
From the blistering speed of Redis to the ACID guarantees of Postgres, or the schema-less power of MongoDB, AsyncMQ supports multiple backends out of the box—and you can write your own by implementing `BaseBackend`.
|
|
93
|
+
|
|
94
|
+
3. **Advanced Scheduling**
|
|
95
|
+
|
|
96
|
+
* **Delayed Jobs**: Fire off tasks in the future with precise delays.
|
|
97
|
+
* **Repeatable & Cron**: Create heartbeat jobs or cron-like schedules with a single line.
|
|
98
|
+
* **Scan & Scheduler**: Smart polling intervals and cron logic keep your timings accurate without burning CPU cycles.
|
|
99
|
+
|
|
100
|
+
4. **Robust Error Handling**
|
|
101
|
+
|
|
102
|
+
* **Retries & Backoff**: Exponential or custom backoff strategies to gracefully handle failures.
|
|
103
|
+
* **Dead Letter Queue (DLQ)**: Automatically route permanently failed tasks for later inspection and reprocessing.
|
|
104
|
+
|
|
105
|
+
5. **Observability & Event Hooks**
|
|
106
|
+
Tap into lifecycle events (`job:started`, `job:completed`, `job:failed`, `job:progress`) to power real-time dashboards, metrics, or custom alerts.
|
|
107
|
+
|
|
108
|
+
6. **Rate Limiting & Concurrency Control**
|
|
109
|
+
Fine-tune throughput with token-bucket rate limiting and capacity limiters. Scale your worker concurrency without overloading downstream systems.
|
|
110
|
+
|
|
111
|
+
7. **Sandboxed Execution**
|
|
112
|
+
Run untrusted or CPU-bound tasks in isolated subprocesses with timeouts to protect your main workers from rogue code or infinite loops.
|
|
113
|
+
|
|
114
|
+
8. **Flow/DAG Orchestration**
|
|
115
|
+
Create complex task graphs with dependencies using `FlowProducer`. Enqueue entire pipelines atomically or fall back to safe sequential logic.
|
|
116
|
+
|
|
117
|
+
9. **CLI & Dev Experience**
|
|
118
|
+
A feature-rich CLI for managing queues, jobs, and workers—intuitive commands, JSON output support, and built-in help for every scenario.
|
|
119
|
+
|
|
120
|
+
10. **Seamless ASGI Integration**
|
|
121
|
+
Out-of-the-box compatibility with FastAPI, Esmerald, or any ASGI application. Manage workers within your app’s lifecycle events.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Comparison with Other Python Task Queues
|
|
126
|
+
|
|
127
|
+
| Feature | **AsyncMQ** | Celery | RQ | Dramatiq | Huey |
|
|
128
|
+
| -------------------------- | -------------------------------- | ------------- | ---------- | ------------ | ---------- |
|
|
129
|
+
| **AsyncIO Native** | ✅ | ❌ | ❌ | ✅ | ❌ |
|
|
130
|
+
| **Pluggable Backends** | ✅ Redis, Postgres, Mongo, In-Mem | RabbitMQ only | Redis only | Redis only | Redis only |
|
|
131
|
+
| **Rate Limiting** | ✅ built-in | ❌ | ❌ | ✅ via addon | ❌ |
|
|
132
|
+
| **Cron & Repeatable Jobs** | ✅ interval & cron expressions | ✅ | ✅ | ✅ | ✅ |
|
|
133
|
+
| **Progress Reporting** | ✅ event hooks | ✅ callbacks | ❌ | ✅ hooks | ❌ |
|
|
134
|
+
| **Dead Letter Queue** | ✅ | ✅ | ❌ | ✅ | ✅ |
|
|
135
|
+
| **Flow / DAG Support** | ✅ `FlowProducer` | ✅ chords | ❌ | ✅ extensions | ❌ |
|
|
136
|
+
| **ASGI-Friendly** | ✅ FastAPI/Esmerald integration | ❌ | ❌ | ❌ | ❌ |
|
|
137
|
+
| **CLI Management** | ✅ rich, JSON-friendly | ✅ | ✅ | ✅ | ✅ |
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
### Where **AsyncMQ** Shines
|
|
142
|
+
|
|
143
|
+
* **True AsyncIO & AnyIO integration**: zero thread hacks, full non-blocking background tasks.
|
|
144
|
+
* **Backend flexibility**: swap Redis, Postgres, MongoDB, or In-Memory with a single setting.
|
|
145
|
+
* **Built-in rate limiting & concurrency control**: protect downstream services out-of-the-box.
|
|
146
|
+
* **Event-driven hooks**: subscribe to `job:started`, `completed`, `failed`, `progress`, etc., for metrics and alerts.
|
|
147
|
+
* **ASGI integration**: manage workers within FastAPI or Esmerald lifecycles—no extra wrappers needed.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## ⚡ Core Features at a Glance
|
|
152
|
+
|
|
153
|
+
| Category | Highlights |
|
|
154
|
+
| ---------------------- | ----------------------------------------------------------------------------------------- |
|
|
155
|
+
| **Task Definition** | `@task` decorator, `.enqueue()`, progress callbacks, TTL, retries, dependencies, repeats |
|
|
156
|
+
| **Queue API** | `add()`, `add_bulk()`, `add_repeatable()`, `pause()`, `resume()`, `clean()`, stats |
|
|
157
|
+
| **Worker Engine** | `process_job()`, capacity & rate limiters, sandbox, event emitter, DLQ handling |
|
|
158
|
+
| **Scheduling** | `delayed_job_scanner`, `repeatable_scheduler`, cron vs interval support |
|
|
159
|
+
| **Flow Orchestration** | `FlowProducer.add_flow()`, atomic backend support, fallback mode for dependency wiring |
|
|
160
|
+
| **Configuration** | Central `Settings` dataclass, env var override, dynamic tuning of concurrency & intervals |
|
|
161
|
+
| **Observability** | LoggingConfig protocol, structured logs, event subscriptions, metrics integration |
|
|
162
|
+
| **CLI Management** | `asyncmq queue`, `asyncmq job`, `asyncmq worker`, `asyncmq info` commands |
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## 🎬 Quickstart
|
|
167
|
+
|
|
168
|
+
1. **Install**
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
pip install asyncmq
|
|
172
|
+
```
|
|
173
|
+
2. **Configure**
|
|
174
|
+
|
|
175
|
+
Override the default settings `from asyncmq.conf import Settings` and create your own, then make it global.
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
export ASYNCMQ_SETTINGS_MODULE=myapp.settings.Settings
|
|
179
|
+
```
|
|
180
|
+
3. **Define a Task**
|
|
181
|
+
|
|
182
|
+
```python
|
|
183
|
+
from asyncmq.tasks import task
|
|
184
|
+
|
|
185
|
+
@task(queue="emails", retries=2, ttl=120)
|
|
186
|
+
async def send_welcome(email: str):
|
|
187
|
+
# Imagine real email-sending logic here
|
|
188
|
+
print(f"📧 Sent welcome to {email}")
|
|
189
|
+
```
|
|
190
|
+
4. **Enqueue & Run**
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
import anyio
|
|
194
|
+
from asyncmq.queues import Queue
|
|
195
|
+
|
|
196
|
+
async def main():
|
|
197
|
+
q = Queue("emails")
|
|
198
|
+
await send_welcome.enqueue(q.backend, "alice@example.com", delay=10)
|
|
199
|
+
anyio.run(main)
|
|
200
|
+
```
|
|
201
|
+
5. **Start Workers**
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
asyncmq worker start emails --concurrency 5
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
AsyncMQ is more than just a task queue, it’s the swiss army knife of async background processing.
|
|
210
|
+
Dive into the **Learn** section to master every feature, or jump into the **Features** docs for quick reference.
|
|
211
|
+
|
|
212
|
+
Ready to bend time?
|
|
213
|
+
|
|
214
|
+
**Get started today** and experience async tasking at warp speed! 🎉
|
asyncmq-0.1.0/README.md
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# AsyncMQ
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<a href="https://asyncmq.dymmond.com"><img src="https://res.cloudinary.com/dymmond/image/upload/v1746002620/asyncmq/oq2qhgqdlra7rudxaqhl.png" alt="AsyncMQ Logo"></a>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<span>⚡ Supercharge your async applications with tasks so fast, you’ll think you’re bending time itself. ⚡</span>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://github.com/dymmond/asyncmq/actions/workflows/test-suite.yml/badge.svg?event=push&branch=main" target="_blank">
|
|
13
|
+
<img src="https://github.com/dymmond/asyncmq/actions/workflows/test-suite.yml/badge.svg?event=push&branch=main" alt="Test Suite">
|
|
14
|
+
</a>
|
|
15
|
+
<a href="https://pypi.org/project/asyncmq" target="_blank">
|
|
16
|
+
<img src="https://img.shields.io/pypi/v/asyncmq?color=%2334D058&label=pypi%20package" alt="Package version">
|
|
17
|
+
</a>
|
|
18
|
+
<a href="https://img.shields.io/pypi/pyversions/asyncmq.svg?color=%2334D058" target="_blank">
|
|
19
|
+
<img src="https://img.shields.io/pypi/pyversions/asyncmq.svg?color=%2334D058" alt="Supported Python versions">
|
|
20
|
+
</a>
|
|
21
|
+
</p>
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
Welcome to **AsyncMQ**, the modern task queue that brings **powerful**, **flexible**, and **lightning-fast** background processing to your Python stack. Whether you're building microservices, handling high-throughput data pipelines, or just want reliable delayed jobs, AsyncMQ has your back.
|
|
26
|
+
|
|
27
|
+
## 🚀 Why Choose AsyncMQ?
|
|
28
|
+
|
|
29
|
+
1. **Asyncio & AnyIO-Native**
|
|
30
|
+
No more wrestling with threads or callbacks—AsyncMQ is built on `asyncio` and `anyio`, so your tasks are non-blocking and integrate seamlessly into modern async frameworks like FastAPI and Esmerald.
|
|
31
|
+
|
|
32
|
+
2. **Multi-Backend Flexibility**
|
|
33
|
+
From the blistering speed of Redis to the ACID guarantees of Postgres, or the schema-less power of MongoDB, AsyncMQ supports multiple backends out of the box—and you can write your own by implementing `BaseBackend`.
|
|
34
|
+
|
|
35
|
+
3. **Advanced Scheduling**
|
|
36
|
+
|
|
37
|
+
* **Delayed Jobs**: Fire off tasks in the future with precise delays.
|
|
38
|
+
* **Repeatable & Cron**: Create heartbeat jobs or cron-like schedules with a single line.
|
|
39
|
+
* **Scan & Scheduler**: Smart polling intervals and cron logic keep your timings accurate without burning CPU cycles.
|
|
40
|
+
|
|
41
|
+
4. **Robust Error Handling**
|
|
42
|
+
|
|
43
|
+
* **Retries & Backoff**: Exponential or custom backoff strategies to gracefully handle failures.
|
|
44
|
+
* **Dead Letter Queue (DLQ)**: Automatically route permanently failed tasks for later inspection and reprocessing.
|
|
45
|
+
|
|
46
|
+
5. **Observability & Event Hooks**
|
|
47
|
+
Tap into lifecycle events (`job:started`, `job:completed`, `job:failed`, `job:progress`) to power real-time dashboards, metrics, or custom alerts.
|
|
48
|
+
|
|
49
|
+
6. **Rate Limiting & Concurrency Control**
|
|
50
|
+
Fine-tune throughput with token-bucket rate limiting and capacity limiters. Scale your worker concurrency without overloading downstream systems.
|
|
51
|
+
|
|
52
|
+
7. **Sandboxed Execution**
|
|
53
|
+
Run untrusted or CPU-bound tasks in isolated subprocesses with timeouts to protect your main workers from rogue code or infinite loops.
|
|
54
|
+
|
|
55
|
+
8. **Flow/DAG Orchestration**
|
|
56
|
+
Create complex task graphs with dependencies using `FlowProducer`. Enqueue entire pipelines atomically or fall back to safe sequential logic.
|
|
57
|
+
|
|
58
|
+
9. **CLI & Dev Experience**
|
|
59
|
+
A feature-rich CLI for managing queues, jobs, and workers—intuitive commands, JSON output support, and built-in help for every scenario.
|
|
60
|
+
|
|
61
|
+
10. **Seamless ASGI Integration**
|
|
62
|
+
Out-of-the-box compatibility with FastAPI, Esmerald, or any ASGI application. Manage workers within your app’s lifecycle events.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Comparison with Other Python Task Queues
|
|
67
|
+
|
|
68
|
+
| Feature | **AsyncMQ** | Celery | RQ | Dramatiq | Huey |
|
|
69
|
+
| -------------------------- | -------------------------------- | ------------- | ---------- | ------------ | ---------- |
|
|
70
|
+
| **AsyncIO Native** | ✅ | ❌ | ❌ | ✅ | ❌ |
|
|
71
|
+
| **Pluggable Backends** | ✅ Redis, Postgres, Mongo, In-Mem | RabbitMQ only | Redis only | Redis only | Redis only |
|
|
72
|
+
| **Rate Limiting** | ✅ built-in | ❌ | ❌ | ✅ via addon | ❌ |
|
|
73
|
+
| **Cron & Repeatable Jobs** | ✅ interval & cron expressions | ✅ | ✅ | ✅ | ✅ |
|
|
74
|
+
| **Progress Reporting** | ✅ event hooks | ✅ callbacks | ❌ | ✅ hooks | ❌ |
|
|
75
|
+
| **Dead Letter Queue** | ✅ | ✅ | ❌ | ✅ | ✅ |
|
|
76
|
+
| **Flow / DAG Support** | ✅ `FlowProducer` | ✅ chords | ❌ | ✅ extensions | ❌ |
|
|
77
|
+
| **ASGI-Friendly** | ✅ FastAPI/Esmerald integration | ❌ | ❌ | ❌ | ❌ |
|
|
78
|
+
| **CLI Management** | ✅ rich, JSON-friendly | ✅ | ✅ | ✅ | ✅ |
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
### Where **AsyncMQ** Shines
|
|
83
|
+
|
|
84
|
+
* **True AsyncIO & AnyIO integration**: zero thread hacks, full non-blocking background tasks.
|
|
85
|
+
* **Backend flexibility**: swap Redis, Postgres, MongoDB, or In-Memory with a single setting.
|
|
86
|
+
* **Built-in rate limiting & concurrency control**: protect downstream services out-of-the-box.
|
|
87
|
+
* **Event-driven hooks**: subscribe to `job:started`, `completed`, `failed`, `progress`, etc., for metrics and alerts.
|
|
88
|
+
* **ASGI integration**: manage workers within FastAPI or Esmerald lifecycles—no extra wrappers needed.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## ⚡ Core Features at a Glance
|
|
93
|
+
|
|
94
|
+
| Category | Highlights |
|
|
95
|
+
| ---------------------- | ----------------------------------------------------------------------------------------- |
|
|
96
|
+
| **Task Definition** | `@task` decorator, `.enqueue()`, progress callbacks, TTL, retries, dependencies, repeats |
|
|
97
|
+
| **Queue API** | `add()`, `add_bulk()`, `add_repeatable()`, `pause()`, `resume()`, `clean()`, stats |
|
|
98
|
+
| **Worker Engine** | `process_job()`, capacity & rate limiters, sandbox, event emitter, DLQ handling |
|
|
99
|
+
| **Scheduling** | `delayed_job_scanner`, `repeatable_scheduler`, cron vs interval support |
|
|
100
|
+
| **Flow Orchestration** | `FlowProducer.add_flow()`, atomic backend support, fallback mode for dependency wiring |
|
|
101
|
+
| **Configuration** | Central `Settings` dataclass, env var override, dynamic tuning of concurrency & intervals |
|
|
102
|
+
| **Observability** | LoggingConfig protocol, structured logs, event subscriptions, metrics integration |
|
|
103
|
+
| **CLI Management** | `asyncmq queue`, `asyncmq job`, `asyncmq worker`, `asyncmq info` commands |
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 🎬 Quickstart
|
|
108
|
+
|
|
109
|
+
1. **Install**
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
pip install asyncmq
|
|
113
|
+
```
|
|
114
|
+
2. **Configure**
|
|
115
|
+
|
|
116
|
+
Override the default settings `from asyncmq.conf import Settings` and create your own, then make it global.
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
export ASYNCMQ_SETTINGS_MODULE=myapp.settings.Settings
|
|
120
|
+
```
|
|
121
|
+
3. **Define a Task**
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
from asyncmq.tasks import task
|
|
125
|
+
|
|
126
|
+
@task(queue="emails", retries=2, ttl=120)
|
|
127
|
+
async def send_welcome(email: str):
|
|
128
|
+
# Imagine real email-sending logic here
|
|
129
|
+
print(f"📧 Sent welcome to {email}")
|
|
130
|
+
```
|
|
131
|
+
4. **Enqueue & Run**
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
import anyio
|
|
135
|
+
from asyncmq.queues import Queue
|
|
136
|
+
|
|
137
|
+
async def main():
|
|
138
|
+
q = Queue("emails")
|
|
139
|
+
await send_welcome.enqueue(q.backend, "alice@example.com", delay=10)
|
|
140
|
+
anyio.run(main)
|
|
141
|
+
```
|
|
142
|
+
5. **Start Workers**
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
asyncmq worker start emails --concurrency 5
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
AsyncMQ is more than just a task queue, it’s the swiss army knife of async background processing.
|
|
151
|
+
Dive into the **Learn** section to master every feature, or jump into the **Features** docs for quick reference.
|
|
152
|
+
|
|
153
|
+
Ready to bend time?
|
|
154
|
+
|
|
155
|
+
**Get started today** and experience async tasking at warp speed! 🎉
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
|
|
3
|
+
from monkay import Monkay
|
|
4
|
+
|
|
5
|
+
__version__ = "0.1.0"
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from .backends.memory import InMemoryBackend
|
|
9
|
+
from .backends.redis import RedisBackend
|
|
10
|
+
from .conf import settings
|
|
11
|
+
from .conf.global_settings import Settings
|
|
12
|
+
from .jobs import Job
|
|
13
|
+
from .queues import Queue
|
|
14
|
+
from .stores.base import BaseJobStore
|
|
15
|
+
from .tasks import task
|
|
16
|
+
from .workers import Worker
|
|
17
|
+
|
|
18
|
+
_monkay: Monkay = Monkay(
|
|
19
|
+
globals(),
|
|
20
|
+
lazy_imports={
|
|
21
|
+
"BaseJobStore": ".stores.base.BaseJobStore",
|
|
22
|
+
"InMemoryBackend": ".backends.memory.InMemoryBackend",
|
|
23
|
+
"Job": ".jobs.Job",
|
|
24
|
+
"Queue": ".queues.Queue",
|
|
25
|
+
"RedisBackend": ".backends.redis.RedisBackend",
|
|
26
|
+
"Worker": ".workers.Worker",
|
|
27
|
+
"settings": ".conf.settings",
|
|
28
|
+
"Settings": ".conf.global_settings.Settings",
|
|
29
|
+
},
|
|
30
|
+
skip_all_update=True,
|
|
31
|
+
package="asyncmq",
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
__all__ = [
|
|
35
|
+
"BaseJobStore",
|
|
36
|
+
"InMemoryBackend",
|
|
37
|
+
"Job",
|
|
38
|
+
"Queue",
|
|
39
|
+
"RedisBackend",
|
|
40
|
+
"Settings",
|
|
41
|
+
"settings",
|
|
42
|
+
"task",
|
|
43
|
+
"Worker",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
_monkay.add_lazy_import("task", ".tasks.task")
|
|
File without changes
|