bazis-async-background 2.2.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.
- bazis_async_background-2.2.0/.dockerignore +3 -0
- bazis_async_background-2.2.0/.github/workflows/build-publish.yml +16 -0
- bazis_async_background-2.2.0/.github/workflows/update-licenses.yml +18 -0
- bazis_async_background-2.2.0/.gitignore +44 -0
- bazis_async_background-2.2.0/PKG-INFO +271 -0
- bazis_async_background-2.2.0/README.md +244 -0
- bazis_async_background-2.2.0/bazis/contrib/async_background/__init__.py +21 -0
- bazis_async_background-2.2.0/bazis/contrib/async_background/_version.py +34 -0
- bazis_async_background-2.2.0/bazis/contrib/async_background/apps.py +23 -0
- bazis_async_background-2.2.0/bazis/contrib/async_background/broker.py +62 -0
- bazis_async_background-2.2.0/bazis/contrib/async_background/conf.py +88 -0
- bazis_async_background-2.2.0/bazis/contrib/async_background/management/__init__.py +14 -0
- bazis_async_background-2.2.0/bazis/contrib/async_background/management/commands/__init__.py +14 -0
- bazis_async_background-2.2.0/bazis/contrib/async_background/management/commands/kafka_consumer_multiple.py +113 -0
- bazis_async_background-2.2.0/bazis/contrib/async_background/management/commands/kafka_consumer_single.py +91 -0
- bazis_async_background-2.2.0/bazis/contrib/async_background/producer.py +132 -0
- bazis_async_background-2.2.0/bazis/contrib/async_background/router.py +15 -0
- bazis_async_background-2.2.0/bazis/contrib/async_background/routes.py +57 -0
- bazis_async_background-2.2.0/bazis/contrib/async_background/schemas.py +36 -0
- bazis_async_background-2.2.0/bazis/contrib/async_background/utils.py +137 -0
- bazis_async_background-2.2.0/bazis_async_background.egg-info/PKG-INFO +271 -0
- bazis_async_background-2.2.0/bazis_async_background.egg-info/SOURCES.txt +44 -0
- bazis_async_background-2.2.0/bazis_async_background.egg-info/dependency_links.txt +1 -0
- bazis_async_background-2.2.0/bazis_async_background.egg-info/requires.txt +9 -0
- bazis_async_background-2.2.0/bazis_async_background.egg-info/top_level.txt +1 -0
- bazis_async_background-2.2.0/pyproject.toml +95 -0
- bazis_async_background-2.2.0/pytest.ini +4 -0
- bazis_async_background-2.2.0/sample/Dockerfile +26 -0
- bazis_async_background-2.2.0/sample/demo/__init__.py +14 -0
- bazis_async_background-2.2.0/sample/demo/router.py +43 -0
- bazis_async_background-2.2.0/sample/demo/schemas.py +19 -0
- bazis_async_background-2.2.0/sample/demo/tasks.py +59 -0
- bazis_async_background-2.2.0/sample/docker-compose.test.yml +148 -0
- bazis_async_background-2.2.0/sample/manage.py +28 -0
- bazis_async_background-2.2.0/sample/project.env +19 -0
- bazis_async_background-2.2.0/sample/pyproject.toml +14 -0
- bazis_async_background-2.2.0/sample/sample/__init__.py +14 -0
- bazis_async_background-2.2.0/sample/sample/main.py +23 -0
- bazis_async_background-2.2.0/sample/sample/router.py +21 -0
- bazis_async_background-2.2.0/sample/sample/settings.py +23 -0
- bazis_async_background-2.2.0/sample/sample/urls.py +29 -0
- bazis_async_background-2.2.0/sample/sample/wsgi.py +22 -0
- bazis_async_background-2.2.0/sample/test.env +29 -0
- bazis_async_background-2.2.0/setup.cfg +4 -0
- bazis_async_background-2.2.0/tests/conftest.py +49 -0
- bazis_async_background-2.2.0/tests/test_demo.py +47 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
name: Build and Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*.*.*'
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
uses: ecofuture-tech/.github/.github/workflows/reusable-build-publish.yml@main
|
|
14
|
+
secrets:
|
|
15
|
+
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
|
|
16
|
+
TEST_PYPI_TOKEN: ${{ secrets.TEST_PYPI_TOKEN }}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
name: Update Licenses
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
paths:
|
|
8
|
+
- '**.py'
|
|
9
|
+
- 'pyproject.toml'
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: write
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
update-licenses:
|
|
16
|
+
uses: ecofuture-tech/.github/.github/workflows/reusable-update-licenses.yml@main
|
|
17
|
+
secrets:
|
|
18
|
+
WORKFLOW_LICENSE_TOKEN: ${{ secrets.WORKFLOW_LICENSE_TOKEN }}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
.idea
|
|
2
|
+
.ipynb_checkpoints
|
|
3
|
+
.mypy_cache
|
|
4
|
+
.vscode
|
|
5
|
+
__pycache__
|
|
6
|
+
.pytest_cache
|
|
7
|
+
htmlcov
|
|
8
|
+
dist
|
|
9
|
+
site
|
|
10
|
+
.coverage
|
|
11
|
+
coverage.xml
|
|
12
|
+
.netlify
|
|
13
|
+
test.db
|
|
14
|
+
log.txt
|
|
15
|
+
Pipfile.lock
|
|
16
|
+
env3.*
|
|
17
|
+
env
|
|
18
|
+
docs_build
|
|
19
|
+
venv
|
|
20
|
+
.venv
|
|
21
|
+
docs.zip
|
|
22
|
+
archive.zip
|
|
23
|
+
|
|
24
|
+
.env
|
|
25
|
+
local.env
|
|
26
|
+
*/.env*
|
|
27
|
+
|
|
28
|
+
# vim temporary files
|
|
29
|
+
*~
|
|
30
|
+
.*.sw?
|
|
31
|
+
*.DS_Store
|
|
32
|
+
|
|
33
|
+
*.egg-info
|
|
34
|
+
build
|
|
35
|
+
dist
|
|
36
|
+
|
|
37
|
+
docs/_autosummary
|
|
38
|
+
docs/_build
|
|
39
|
+
*.DS_Store
|
|
40
|
+
*.log
|
|
41
|
+
my-*
|
|
42
|
+
My*
|
|
43
|
+
*/**/_version.py
|
|
44
|
+
/uv.lock
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bazis-async-background
|
|
3
|
+
Version: 2.2.0
|
|
4
|
+
Summary: Async Background core framework for Bazis.
|
|
5
|
+
Author-email: Ilya Kharyn <ilya.tt07@gmail.com>
|
|
6
|
+
Maintainer-email: Ilya Kharyn <ilya.tt07@gmail.com>
|
|
7
|
+
Project-URL: Home, https://github.com/ecofuture-tech/bazis-async-background
|
|
8
|
+
Keywords: bazis,django,fastapi,async,background,kafka,framework
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Classifier: Framework :: Django
|
|
17
|
+
Classifier: Framework :: FastAPI
|
|
18
|
+
Requires-Python: >=3.12
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
Requires-Dist: bazis
|
|
21
|
+
Requires-Dist: bazis-ws
|
|
22
|
+
Requires-Dist: faststream[kafka]
|
|
23
|
+
Provides-Extra: test
|
|
24
|
+
Requires-Dist: bazis-test-utils; extra == "test"
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: ruff; extra == "dev"
|
|
27
|
+
|
|
28
|
+
# Bazis Async Background
|
|
29
|
+
|
|
30
|
+
[](https://pypi.org/project/bazis-async-background/)
|
|
31
|
+
[](https://pypi.org/project/bazis-async-background/)
|
|
32
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
33
|
+
|
|
34
|
+
Core background task framework for Bazis. It provides Kafka broker helpers, task schemas, status storage in Redis, and a base API to retrieve task results.
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Install the package
|
|
40
|
+
uv add bazis-async-background
|
|
41
|
+
|
|
42
|
+
# Configure environment variables / settings
|
|
43
|
+
INSTALLED_APPS='["bazis.contrib.async_background", ...]'
|
|
44
|
+
BAZIS_CONFIG_APPS='["bazis.contrib.async_background", ...]'
|
|
45
|
+
|
|
46
|
+
# Kafka settings
|
|
47
|
+
KAFKA_BOOTSTRAP_SERVERS=localhost:9093
|
|
48
|
+
KAFKA_TOPIC_ASYNC_REQUEST=my_app_background_tasks
|
|
49
|
+
KAFKA_GROUP_ID=my_app_background
|
|
50
|
+
KAFKA_TASKS='["my_app.background.tasks"]'
|
|
51
|
+
|
|
52
|
+
# Run consumer in Kubernetes
|
|
53
|
+
python manage.py kafka_consumer_single
|
|
54
|
+
|
|
55
|
+
# Run multiple consumers locally
|
|
56
|
+
python manage.py kafka_consumer_multiple --consumers-count=5
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Table of Contents
|
|
60
|
+
|
|
61
|
+
- [Description](#description)
|
|
62
|
+
- [Requirements](#requirements)
|
|
63
|
+
- [Installation](#installation)
|
|
64
|
+
- [Architecture](#architecture)
|
|
65
|
+
- [Configuration](#configuration)
|
|
66
|
+
- [Environment Variables / Settings](#environment-variables--settings)
|
|
67
|
+
- [Route Registration](#route-registration)
|
|
68
|
+
- [Usage](#usage)
|
|
69
|
+
- [Running Consumers](#running-consumers)
|
|
70
|
+
- [Examples](#examples)
|
|
71
|
+
- [License](#license)
|
|
72
|
+
- [Links](#links)
|
|
73
|
+
|
|
74
|
+
## Description
|
|
75
|
+
|
|
76
|
+
**Bazis Async Background** is a core package for running background tasks in the Bazis framework. It includes:
|
|
77
|
+
|
|
78
|
+
- **Kafka Producer** — sending tasks to Kafka queue
|
|
79
|
+
- **Kafka Consumer** — processing tasks from the queue
|
|
80
|
+
- **Redis storage** — storing task execution results
|
|
81
|
+
- **API endpoint** — retrieving results by task_id
|
|
82
|
+
|
|
83
|
+
## Requirements
|
|
84
|
+
|
|
85
|
+
- **Python**: 3.12+
|
|
86
|
+
- **bazis**: latest version
|
|
87
|
+
- **PostgreSQL**: 12+
|
|
88
|
+
- **Redis**: For storing results and caching
|
|
89
|
+
- **Kafka**: For task queue
|
|
90
|
+
|
|
91
|
+
## Installation
|
|
92
|
+
|
|
93
|
+
### Using uv (recommended)
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
uv add bazis-async-background
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Using pip
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
pip install bazis-async-background
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Running Tests
|
|
106
|
+
|
|
107
|
+
Run from the project root:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
docker compose -f sample/docker-compose.test.yml up --build --exit-code-from bazis-async-background-pytest --attach bazis-async-background-pytest --attach bazis-async-background-consumer-test
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
This waits for the pytest container to finish and streams logs only from the Python containers, so test completion and output are easy to follow.
|
|
114
|
+
|
|
115
|
+
## Architecture
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
┌─────────────┐
|
|
119
|
+
│ Client │
|
|
120
|
+
└──────┬──────┘
|
|
121
|
+
│ Background task request
|
|
122
|
+
▼
|
|
123
|
+
┌─────────────────────┐
|
|
124
|
+
│ API Endpoint │
|
|
125
|
+
│ (Async Background) │
|
|
126
|
+
└──────┬──────────────┘
|
|
127
|
+
│ 1. Return task_id (202)
|
|
128
|
+
│ 2. Send to Kafka
|
|
129
|
+
▼
|
|
130
|
+
┌─────────────────────┐
|
|
131
|
+
│ Kafka Topic │
|
|
132
|
+
│ (async_background) │
|
|
133
|
+
└──────┬──────────────┘
|
|
134
|
+
│
|
|
135
|
+
│ Consumer polls
|
|
136
|
+
▼
|
|
137
|
+
┌─────────────────────┐
|
|
138
|
+
│ Kafka Consumer │
|
|
139
|
+
│ (Background Worker)│
|
|
140
|
+
└──────┬──────────────┘
|
|
141
|
+
│ 3. Process task
|
|
142
|
+
│ 4. Save result to Redis
|
|
143
|
+
▼
|
|
144
|
+
┌─────────────────────┐
|
|
145
|
+
│ Redis │
|
|
146
|
+
│ (Results Store) │
|
|
147
|
+
└──────┬──────────────┘
|
|
148
|
+
│
|
|
149
|
+
│ 5. GET /async_background_response/{task_id}/
|
|
150
|
+
▼
|
|
151
|
+
┌─────────────────────┐
|
|
152
|
+
│ API Endpoint │
|
|
153
|
+
│ (Get Result) │
|
|
154
|
+
└─────────────────────┘
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Configuration
|
|
158
|
+
|
|
159
|
+
### Environment Variables / Settings
|
|
160
|
+
|
|
161
|
+
Add to your `.env` or `settings.py`:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
# Required settings
|
|
165
|
+
INSTALLED_APPS='["bazis.contrib.async_background", ...]'
|
|
166
|
+
BAZIS_CONFIG_APPS='["bazis.contrib.async_background", ...]'
|
|
167
|
+
KAFKA_TASKS='["my_app.background.tasks"]'
|
|
168
|
+
|
|
169
|
+
# Kafka settings
|
|
170
|
+
KAFKA_BOOTSTRAP_SERVERS=localhost:9093
|
|
171
|
+
KAFKA_TOPIC_ASYNC_REQUEST=my_app_background_tasks
|
|
172
|
+
KAFKA_GROUP_ID=my_app_background
|
|
173
|
+
|
|
174
|
+
# Optional settings
|
|
175
|
+
KAFKA_CONSUMER_LIFETIME_SEC=900 # Consumer lifetime (15 minutes)
|
|
176
|
+
KAFKA_CONSUMER_LIFETIME_JITTER_SEC=180 # Random deviation (3 minutes)
|
|
177
|
+
KAFKA_AUTO_OFFSET_RESET=latest
|
|
178
|
+
KAFKA_ENABLE_AUTO_COMMIT=true
|
|
179
|
+
KAFKA_AUTO_COMMIT_INTERVAL_MS=5000
|
|
180
|
+
KAFKA_LOG_LEVEL=INFO
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**Parameters**:
|
|
184
|
+
|
|
185
|
+
- `KAFKA_TASKS` — dotted module paths imported by the consumer to register tasks
|
|
186
|
+
- `KAFKA_BOOTSTRAP_SERVERS` — Kafka broker address
|
|
187
|
+
- `KAFKA_TOPIC_ASYNC_REQUEST` — topic for async tasks
|
|
188
|
+
- `KAFKA_GROUP_ID` — consumer group
|
|
189
|
+
- `KAFKA_CONSUMER_LIFETIME_SEC` — consumer working time before restart
|
|
190
|
+
- `KAFKA_CONSUMER_LIFETIME_JITTER_SEC` — random deviation to avoid simultaneous restart
|
|
191
|
+
- `KAFKA_AUTO_OFFSET_RESET` — Kafka auto offset reset policy
|
|
192
|
+
- `KAFKA_ENABLE_AUTO_COMMIT` — Kafka auto-commit toggle
|
|
193
|
+
- `KAFKA_AUTO_COMMIT_INTERVAL_MS` — auto-commit interval in ms
|
|
194
|
+
- `KAFKA_LOG_LEVEL` — log level for consumers
|
|
195
|
+
|
|
196
|
+
### Route Registration
|
|
197
|
+
|
|
198
|
+
Add the route for getting results to your `router.py`:
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
from bazis.core.routing import BazisRouter
|
|
202
|
+
|
|
203
|
+
router = BazisRouter(prefix='/api/v1')
|
|
204
|
+
|
|
205
|
+
# Register background task results route
|
|
206
|
+
router.register('bazis.contrib.async_background.router')
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
This adds the endpoint: `GET /api/v1/async_background_response/{task_id}/`
|
|
210
|
+
|
|
211
|
+
## Usage
|
|
212
|
+
|
|
213
|
+
### Running Consumers
|
|
214
|
+
|
|
215
|
+
#### For Kubernetes (one consumer per pod)
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
python manage.py kafka_consumer_single
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Runs one consumer that processes tasks from Kafka. Suitable for horizontal scaling in Kubernetes.
|
|
222
|
+
|
|
223
|
+
#### For Local Development (multiple consumers)
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
python manage.py kafka_consumer_multiple --consumers-count=5
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Runs 5 consumers in separate processes. Suitable for local development or deployment without orchestration.
|
|
230
|
+
|
|
231
|
+
**Parameters**:
|
|
232
|
+
|
|
233
|
+
- `--consumers-count` — number of consumers to run (default: 1)
|
|
234
|
+
|
|
235
|
+
## Examples
|
|
236
|
+
|
|
237
|
+
### Minimal Task Registration
|
|
238
|
+
|
|
239
|
+
```python
|
|
240
|
+
from bazis.contrib.async_background.broker import get_broker_for_consumer
|
|
241
|
+
from bazis.contrib.async_background.schemas import KafkaTask, TaskStatus
|
|
242
|
+
from bazis.contrib.async_background.utils import set_and_publish_status_async
|
|
243
|
+
from pydantic import BaseModel
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
class DemoPayload(BaseModel):
|
|
247
|
+
message: str
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
@get_broker_for_consumer().subscriber("my_app_background_tasks")
|
|
251
|
+
async def consumer_demo(task: KafkaTask[DemoPayload]):
|
|
252
|
+
await set_and_publish_status_async(
|
|
253
|
+
task_id=task.task_id,
|
|
254
|
+
channel_name=task.channel_name,
|
|
255
|
+
status=TaskStatus.COMPLETED,
|
|
256
|
+
response={"echo": task.payload.model_dump()},
|
|
257
|
+
)
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## License
|
|
261
|
+
|
|
262
|
+
Apache License 2.0
|
|
263
|
+
|
|
264
|
+
See [LICENSE](LICENSE) file for details.
|
|
265
|
+
|
|
266
|
+
## Links
|
|
267
|
+
|
|
268
|
+
- [Bazis Documentation](https://github.com/ecofuture-tech/bazis) — main repository
|
|
269
|
+
- [Bazis Async Background Repository](https://github.com/ecofuture-tech/bazis-async-background) — package repository
|
|
270
|
+
- [Issue Tracker](https://github.com/ecofuture-tech/bazis-async-background/issues) — report bugs or request features
|
|
271
|
+
- [Apache Kafka](https://kafka.apache.org/) — Kafka documentation
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# Bazis Async Background
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/bazis-async-background/)
|
|
4
|
+
[](https://pypi.org/project/bazis-async-background/)
|
|
5
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
6
|
+
|
|
7
|
+
Core background task framework for Bazis. It provides Kafka broker helpers, task schemas, status storage in Redis, and a base API to retrieve task results.
|
|
8
|
+
|
|
9
|
+
## Quick Start
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Install the package
|
|
13
|
+
uv add bazis-async-background
|
|
14
|
+
|
|
15
|
+
# Configure environment variables / settings
|
|
16
|
+
INSTALLED_APPS='["bazis.contrib.async_background", ...]'
|
|
17
|
+
BAZIS_CONFIG_APPS='["bazis.contrib.async_background", ...]'
|
|
18
|
+
|
|
19
|
+
# Kafka settings
|
|
20
|
+
KAFKA_BOOTSTRAP_SERVERS=localhost:9093
|
|
21
|
+
KAFKA_TOPIC_ASYNC_REQUEST=my_app_background_tasks
|
|
22
|
+
KAFKA_GROUP_ID=my_app_background
|
|
23
|
+
KAFKA_TASKS='["my_app.background.tasks"]'
|
|
24
|
+
|
|
25
|
+
# Run consumer in Kubernetes
|
|
26
|
+
python manage.py kafka_consumer_single
|
|
27
|
+
|
|
28
|
+
# Run multiple consumers locally
|
|
29
|
+
python manage.py kafka_consumer_multiple --consumers-count=5
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Table of Contents
|
|
33
|
+
|
|
34
|
+
- [Description](#description)
|
|
35
|
+
- [Requirements](#requirements)
|
|
36
|
+
- [Installation](#installation)
|
|
37
|
+
- [Architecture](#architecture)
|
|
38
|
+
- [Configuration](#configuration)
|
|
39
|
+
- [Environment Variables / Settings](#environment-variables--settings)
|
|
40
|
+
- [Route Registration](#route-registration)
|
|
41
|
+
- [Usage](#usage)
|
|
42
|
+
- [Running Consumers](#running-consumers)
|
|
43
|
+
- [Examples](#examples)
|
|
44
|
+
- [License](#license)
|
|
45
|
+
- [Links](#links)
|
|
46
|
+
|
|
47
|
+
## Description
|
|
48
|
+
|
|
49
|
+
**Bazis Async Background** is a core package for running background tasks in the Bazis framework. It includes:
|
|
50
|
+
|
|
51
|
+
- **Kafka Producer** — sending tasks to Kafka queue
|
|
52
|
+
- **Kafka Consumer** — processing tasks from the queue
|
|
53
|
+
- **Redis storage** — storing task execution results
|
|
54
|
+
- **API endpoint** — retrieving results by task_id
|
|
55
|
+
|
|
56
|
+
## Requirements
|
|
57
|
+
|
|
58
|
+
- **Python**: 3.12+
|
|
59
|
+
- **bazis**: latest version
|
|
60
|
+
- **PostgreSQL**: 12+
|
|
61
|
+
- **Redis**: For storing results and caching
|
|
62
|
+
- **Kafka**: For task queue
|
|
63
|
+
|
|
64
|
+
## Installation
|
|
65
|
+
|
|
66
|
+
### Using uv (recommended)
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
uv add bazis-async-background
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Using pip
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
pip install bazis-async-background
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Running Tests
|
|
79
|
+
|
|
80
|
+
Run from the project root:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
docker compose -f sample/docker-compose.test.yml up --build --exit-code-from bazis-async-background-pytest --attach bazis-async-background-pytest --attach bazis-async-background-consumer-test
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
This waits for the pytest container to finish and streams logs only from the Python containers, so test completion and output are easy to follow.
|
|
87
|
+
|
|
88
|
+
## Architecture
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
┌─────────────┐
|
|
92
|
+
│ Client │
|
|
93
|
+
└──────┬──────┘
|
|
94
|
+
│ Background task request
|
|
95
|
+
▼
|
|
96
|
+
┌─────────────────────┐
|
|
97
|
+
│ API Endpoint │
|
|
98
|
+
│ (Async Background) │
|
|
99
|
+
└──────┬──────────────┘
|
|
100
|
+
│ 1. Return task_id (202)
|
|
101
|
+
│ 2. Send to Kafka
|
|
102
|
+
▼
|
|
103
|
+
┌─────────────────────┐
|
|
104
|
+
│ Kafka Topic │
|
|
105
|
+
│ (async_background) │
|
|
106
|
+
└──────┬──────────────┘
|
|
107
|
+
│
|
|
108
|
+
│ Consumer polls
|
|
109
|
+
▼
|
|
110
|
+
┌─────────────────────┐
|
|
111
|
+
│ Kafka Consumer │
|
|
112
|
+
│ (Background Worker)│
|
|
113
|
+
└──────┬──────────────┘
|
|
114
|
+
│ 3. Process task
|
|
115
|
+
│ 4. Save result to Redis
|
|
116
|
+
▼
|
|
117
|
+
┌─────────────────────┐
|
|
118
|
+
│ Redis │
|
|
119
|
+
│ (Results Store) │
|
|
120
|
+
└──────┬──────────────┘
|
|
121
|
+
│
|
|
122
|
+
│ 5. GET /async_background_response/{task_id}/
|
|
123
|
+
▼
|
|
124
|
+
┌─────────────────────┐
|
|
125
|
+
│ API Endpoint │
|
|
126
|
+
│ (Get Result) │
|
|
127
|
+
└─────────────────────┘
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Configuration
|
|
131
|
+
|
|
132
|
+
### Environment Variables / Settings
|
|
133
|
+
|
|
134
|
+
Add to your `.env` or `settings.py`:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
# Required settings
|
|
138
|
+
INSTALLED_APPS='["bazis.contrib.async_background", ...]'
|
|
139
|
+
BAZIS_CONFIG_APPS='["bazis.contrib.async_background", ...]'
|
|
140
|
+
KAFKA_TASKS='["my_app.background.tasks"]'
|
|
141
|
+
|
|
142
|
+
# Kafka settings
|
|
143
|
+
KAFKA_BOOTSTRAP_SERVERS=localhost:9093
|
|
144
|
+
KAFKA_TOPIC_ASYNC_REQUEST=my_app_background_tasks
|
|
145
|
+
KAFKA_GROUP_ID=my_app_background
|
|
146
|
+
|
|
147
|
+
# Optional settings
|
|
148
|
+
KAFKA_CONSUMER_LIFETIME_SEC=900 # Consumer lifetime (15 minutes)
|
|
149
|
+
KAFKA_CONSUMER_LIFETIME_JITTER_SEC=180 # Random deviation (3 minutes)
|
|
150
|
+
KAFKA_AUTO_OFFSET_RESET=latest
|
|
151
|
+
KAFKA_ENABLE_AUTO_COMMIT=true
|
|
152
|
+
KAFKA_AUTO_COMMIT_INTERVAL_MS=5000
|
|
153
|
+
KAFKA_LOG_LEVEL=INFO
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Parameters**:
|
|
157
|
+
|
|
158
|
+
- `KAFKA_TASKS` — dotted module paths imported by the consumer to register tasks
|
|
159
|
+
- `KAFKA_BOOTSTRAP_SERVERS` — Kafka broker address
|
|
160
|
+
- `KAFKA_TOPIC_ASYNC_REQUEST` — topic for async tasks
|
|
161
|
+
- `KAFKA_GROUP_ID` — consumer group
|
|
162
|
+
- `KAFKA_CONSUMER_LIFETIME_SEC` — consumer working time before restart
|
|
163
|
+
- `KAFKA_CONSUMER_LIFETIME_JITTER_SEC` — random deviation to avoid simultaneous restart
|
|
164
|
+
- `KAFKA_AUTO_OFFSET_RESET` — Kafka auto offset reset policy
|
|
165
|
+
- `KAFKA_ENABLE_AUTO_COMMIT` — Kafka auto-commit toggle
|
|
166
|
+
- `KAFKA_AUTO_COMMIT_INTERVAL_MS` — auto-commit interval in ms
|
|
167
|
+
- `KAFKA_LOG_LEVEL` — log level for consumers
|
|
168
|
+
|
|
169
|
+
### Route Registration
|
|
170
|
+
|
|
171
|
+
Add the route for getting results to your `router.py`:
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
from bazis.core.routing import BazisRouter
|
|
175
|
+
|
|
176
|
+
router = BazisRouter(prefix='/api/v1')
|
|
177
|
+
|
|
178
|
+
# Register background task results route
|
|
179
|
+
router.register('bazis.contrib.async_background.router')
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
This adds the endpoint: `GET /api/v1/async_background_response/{task_id}/`
|
|
183
|
+
|
|
184
|
+
## Usage
|
|
185
|
+
|
|
186
|
+
### Running Consumers
|
|
187
|
+
|
|
188
|
+
#### For Kubernetes (one consumer per pod)
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
python manage.py kafka_consumer_single
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Runs one consumer that processes tasks from Kafka. Suitable for horizontal scaling in Kubernetes.
|
|
195
|
+
|
|
196
|
+
#### For Local Development (multiple consumers)
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
python manage.py kafka_consumer_multiple --consumers-count=5
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Runs 5 consumers in separate processes. Suitable for local development or deployment without orchestration.
|
|
203
|
+
|
|
204
|
+
**Parameters**:
|
|
205
|
+
|
|
206
|
+
- `--consumers-count` — number of consumers to run (default: 1)
|
|
207
|
+
|
|
208
|
+
## Examples
|
|
209
|
+
|
|
210
|
+
### Minimal Task Registration
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
from bazis.contrib.async_background.broker import get_broker_for_consumer
|
|
214
|
+
from bazis.contrib.async_background.schemas import KafkaTask, TaskStatus
|
|
215
|
+
from bazis.contrib.async_background.utils import set_and_publish_status_async
|
|
216
|
+
from pydantic import BaseModel
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
class DemoPayload(BaseModel):
|
|
220
|
+
message: str
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
@get_broker_for_consumer().subscriber("my_app_background_tasks")
|
|
224
|
+
async def consumer_demo(task: KafkaTask[DemoPayload]):
|
|
225
|
+
await set_and_publish_status_async(
|
|
226
|
+
task_id=task.task_id,
|
|
227
|
+
channel_name=task.channel_name,
|
|
228
|
+
status=TaskStatus.COMPLETED,
|
|
229
|
+
response={"echo": task.payload.model_dump()},
|
|
230
|
+
)
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## License
|
|
234
|
+
|
|
235
|
+
Apache License 2.0
|
|
236
|
+
|
|
237
|
+
See [LICENSE](LICENSE) file for details.
|
|
238
|
+
|
|
239
|
+
## Links
|
|
240
|
+
|
|
241
|
+
- [Bazis Documentation](https://github.com/ecofuture-tech/bazis) — main repository
|
|
242
|
+
- [Bazis Async Background Repository](https://github.com/ecofuture-tech/bazis-async-background) — package repository
|
|
243
|
+
- [Issue Tracker](https://github.com/ecofuture-tech/bazis-async-background/issues) — report bugs or request features
|
|
244
|
+
- [Apache Kafka](https://kafka.apache.org/) — Kafka documentation
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Copyright 2026 EcoFuture Technology Services LLC and contributors
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from importlib.metadata import version
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
try:
|
|
19
|
+
__version__ = version('bazis-async-background')
|
|
20
|
+
except Exception:
|
|
21
|
+
__version__ = 'dev'
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
TYPE_CHECKING = False
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from typing import Tuple
|
|
16
|
+
from typing import Union
|
|
17
|
+
|
|
18
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
20
|
+
else:
|
|
21
|
+
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
23
|
+
|
|
24
|
+
version: str
|
|
25
|
+
__version__: str
|
|
26
|
+
__version_tuple__: VERSION_TUPLE
|
|
27
|
+
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
30
|
+
|
|
31
|
+
__version__ = version = '2.2.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (2, 2, 0)
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = 'g639234d6d'
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Copyright 2026 EcoFuture Technology Services LLC and contributors
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from django.utils.translation import gettext_lazy as _
|
|
16
|
+
|
|
17
|
+
from bazis.core.utils.apps import BaseConfig
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class AsyncBackgroundConfig(BaseConfig):
|
|
21
|
+
name = "bazis.contrib.async_background"
|
|
22
|
+
verbose_name = _("AsyncBackground")
|
|
23
|
+
default = True
|