Skip to content

Commit a3d11ec

Browse files
committed
Merge branch 'release/0.8.0'
2 parents 00ee6cf + a816c6c commit a3d11ec

31 files changed

+2690
-1967
lines changed

.python-version

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
3.11.4
2+
3.10.12
3+
3.9.17
4+
3.8.17

docs/.vuepress/styles/index.scss

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
1-
.toggle-navbar-button {
1+
.vp-site-name {
22
visibility: hidden;
33
}
44

5-
.hero-info-wrapper {
5+
.vp-hero-info {
66
img {
77
max-width: 60% !important;
88
padding: 1rem;
99
}
1010
}
1111

12-
.actions {
12+
.vp-actions {
1313
align-items: flex-end;
1414
}
15-
16-
span.site-name {
17-
visibility: hidden;
18-
}

docs/contrib.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
---
2+
order: 5
3+
---
4+
5+
# Contribution guide
6+
7+
We love contributions. This guide is for all folks who want to make taskiq
8+
better together.
9+
10+
We have several rules for contributors:
11+
* Please do not add malware.
12+
* Please make sure that your request solves problem.
13+
14+
If you struggle with something or feel frustrating, you either create an issue, create a discussion on page or publish draft PR and ask your question in description.
15+
16+
We have lots of tests in CI. But since runs from first-time contributors should be approved you better test locally, it just takes less time.
17+
18+
We love contributions. This guide is for all folks who want to make taskiq better together.
19+
We have several rules for contributors:
20+
* Please do not add malware.
21+
* Please make sure that your request solves the problem.
22+
23+
If you struggle with something or feel frustrated, you either create an issue, create a [discussions](https://github.com/orgs/taskiq-python/discussions).
24+
page or publish a draft PR and ask your question in the description.
25+
26+
We have lots of tests in CI. But since CI runs from first-time contributors should be approved, you better test locally. It just takes less time to prepare PR for merging.
27+
28+
## Setting up environment
29+
30+
We use poetry for managing dependencies. To install it, please follow the official guide in [documentation](https://python-poetry.org/docs/).
31+
32+
After you have cloned the taskiq repo, install dependencies using this command:
33+
34+
```bash
35+
poetry install
36+
```
37+
38+
It will install all required dependencies.
39+
If you want to run pytest against different python environments, please install `pyenv` using instructions from its [readme](https://github.com/pyenv/pyenv).
40+
41+
After pyenv is ready, you can install all python versions using this command:
42+
43+
```bash
44+
pyenv install
45+
```
46+
47+
## Linting
48+
49+
We have `pre-commit` configured with all our settings. We highly recommend you to install it as a git hook using `pre-commit install` command.
50+
51+
But even without installation, you can run all lints manually:
52+
53+
```bash
54+
pre-commit run -a
55+
```
56+
57+
58+
## Testing
59+
60+
You can run `pytest` without any parameters and it will do the thing.
61+
62+
```bash
63+
pytest
64+
```
65+
66+
If you want to speedup testings, you can run it with `-n` option from [pytest-xdist](https://pypi.org/project/pytest-xdist/) to run tests in parallel.
67+
68+
```bash
69+
pytest -n 2
70+
```
71+
72+
Also we use `tox` to test against different environments. You can publish a PR to run pytest with different
73+
python versions, but if you want to do it locally, just run `tox` command.
74+
75+
76+
```bash
77+
tox
78+
```
79+
80+
Tox assumes that you've installed python versions using pyenv with command above.

docs/examples/extending/middleware_async.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@
55

66

77
class MyMiddleware(TaskiqMiddleware):
8+
async def startup(self) -> None:
9+
print("RUN STARTUP")
10+
await sleep(1)
11+
12+
async def shutdown(self) -> None:
13+
print("RUN SHUTDOWN")
14+
await sleep(1)
15+
816
async def pre_execute(self, message: "TaskiqMessage") -> TaskiqMessage:
917
await sleep(1)
1018
return message

docs/examples/extending/middleware_sync.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@
55

66

77
class MyMiddleware(TaskiqMiddleware):
8+
def startup(self) -> None:
9+
print("RUN STARTUP")
10+
sleep(1)
11+
12+
def shutdown(self) -> None:
13+
print("RUN SHUTDOWN")
14+
sleep(1)
15+
816
def pre_execute(self, message: "TaskiqMessage") -> TaskiqMessage:
917
sleep(1)
1018
return message

docs/guide/architecture-overview.md

Lines changed: 75 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,60 @@ asyncio.run(main())
8282

8383
```
8484

85+
## Messages
86+
87+
Every message has labels. You can define labels
88+
using `task` decorator, or you can add them using kicker.
89+
90+
For example:
91+
92+
```python
93+
94+
@broker.task(my_label=1, label2="something")
95+
async def my_async_task() -> None:
96+
"""My lovely task."""
97+
await asyncio.sleep(1)
98+
print("Hello")
99+
100+
async def main():
101+
await my_async_task.kiq()
102+
```
103+
104+
It's equivalent to this
105+
106+
```python
107+
108+
@broker.task
109+
async def my_async_task() -> None:
110+
"""My lovely task."""
111+
await asyncio.sleep(1)
112+
print("Hello")
113+
114+
async def main():
115+
await my_async_task.kicker().with_labels(
116+
my_label=1,
117+
label2="something",
118+
).kiq()
119+
```
120+
121+
Also you can assign custom task names using decorator.
122+
This is useful to be sure that task names are unique and resolved correctly.
123+
Also it may be useful to balance message routing in some brokers.
124+
125+
for example:
126+
127+
```python
128+
@broker.task(task_name="my_tasks.add_one", label1=1)
129+
async def my_async_task() -> None:
130+
"""My lovely task."""
131+
await asyncio.sleep(1)
132+
print("Hello")
133+
134+
```
135+
85136
## Result backend
86137

87-
This part is used to store and get results of the execution.
138+
Result backend is used to store and get results of the execution.
88139
Results have type `TaskiqResult` from [taskiq.result](https://github.com/taskiq-python/taskiq/blob/master/taskiq/result.py).
89140

90141
Every ResultBackend must implement `AsyncResultBackend` from [taskiq.abc.result_backend](https://github.com/taskiq-python/taskiq/blob/master/taskiq/abc/result_backend.py). By default, brokers use `DummyResultBackend`. It doesn't do anything and cannot be used
@@ -131,6 +182,12 @@ taskiq worker test_project.broker:broker -fsd
131182
If you have uvloop installed, taskiq will automatically install new policies to event loop.
132183
You can get more info about the CLI in the [CLI](./cli.md) section.
133184

185+
::: info Cool info
186+
187+
By default we start two processes, if you want to change this value, please take a look at `--help`.
188+
189+
:::
190+
134191
## Middlewares
135192

136193
Middlewares are used to modify message, or take
@@ -182,88 +239,35 @@ Middlewares can store information in `message.labels` for
182239
later use. For example `SimpleRetryMiddleware` uses labels
183240
to remember number of failed attempts.
184241

185-
## Messages
242+
## Context
186243

187-
Every message has labels. You can define labels
188-
using `task` decorator, or you can add them using kicker.
244+
Context is a useful class with some additional functions.
245+
You can use context to get broker that runs this task, from inside of the task.
189246

190-
For example:
247+
Or it has ability to control the flow of execution. Here's example of how to get
248+
the context.
191249

192250
```python
251+
from taskiq import Context, TaskiqDepends, ZeroMQBroker
193252

194-
@broker.task(my_label=1, label2="something")
195-
async def my_async_task() -> None:
196-
"""My lovely task."""
197-
await asyncio.sleep(1)
198-
print("Hello")
253+
broker = ZeroMQBroker()
199254

200-
async def main():
201-
await my_async_task.kiq()
202-
```
203-
204-
It's equivalent to this
205-
206-
```python
207255

208256
@broker.task
209-
async def my_async_task() -> None:
210-
"""My lovely task."""
211-
await asyncio.sleep(1)
212-
print("Hello")
213-
214-
async def main():
215-
await my_async_task.kicker().with_labels(
216-
my_label=1,
217-
label2="something",
218-
).kiq()
257+
async def my_task(context: Context = TaskiqDepends()):
258+
...
219259
```
220260

221-
Also you can assign custom task names using decorator.
222-
This is useful to be sure that task names are unique and resolved correctly.
223-
Also it may be useful to balance message routing in some brokers.
224-
225-
for example:
261+
Also through contexts you can reject or requeue a task. It's easy as this:
226262

227263
```python
228-
@broker.task(task_name="my_tasks.add_one", label1=1)
229-
async def my_async_task() -> None:
230-
"""My lovely task."""
231-
await asyncio.sleep(1)
232-
print("Hello")
233-
264+
@broker.task
265+
async def my_task(context: Context = TaskiqDepends()):
266+
await context.requeue()
234267
```
235268

236-
## Context
237-
238-
This section is useful for library developers. Who want to get current broker during shared task execution.
239-
240-
For example, you've created shared_task and you want to send message in that task.
241-
This can be done with context.
242-
243-
Context holds information about the current broker and current incoming message.
244-
To get it, simply add the context parameter with `type-hint`.
245-
246-
::: danger Cool warning!
247-
Context injected only if you have a type hint.
248-
:::
249-
250-
Example:
251-
252-
```python
253-
from taskiq import async_shared_broker, BrokerMessage, Context
254-
255-
256-
@async_shared_broker.task
257-
async def my_shr_task(context: Context):
258-
message = BrokerMessage(
259-
task_id="123",
260-
task_name="dummy_name",
261-
message='{"one": "two"}',
262-
labels={},
263-
)
264-
await context.broker.kick(message)
265-
266-
```
269+
Calling `requeue` or `reject` stops task execution and either drops the message,
270+
or puts it back to the queue.
267271

268-
This is useless example, but it's good as a demonstration.
269-
Pipelines are built using this magic.
272+
Also, with context you'll be able to get current message that was received by the broker
273+
or even instance of a broker who received a message. This may be useful for lib developers.

docs/guide/cli.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@ To enable this option simply pass the `--reload` or `-r` option to worker taskiq
7171
Also this option supports `.gitignore` files. If you have such file in your directory, it won't reload worker
7272
when you modify ignored files. To disable this functionality pass `--do-not-use-gitignore` option.
7373

74+
### Other parameters
75+
76+
* `--no-configure-logging` - disables default logging configuration for workers.
77+
* `--max-async-tasks` - maximum number of simultaneously running async tasks.
78+
* `--max-prefetch` - number of tasks to be prefetched before execution. (Useful for systems with high message rates, but brokers should support acknowledgements).
79+
* `--max-threadpool-threads` - number of threads for sync function exection.
80+
* `--no-propagate-errors` - if this parameter is enabled, exceptions won't be thrown in generator dependencies.
81+
* `--receiver` - python path to custom receiver class.
82+
* `--receiver_arg` - custom args for receiver.
83+
7484
## Scheduler
7585

7686
Scheduler is used to schedule tasks as described in [Scheduling tasks](./scheduling-tasks.md) section.

docs/guide/state-and-deps.md

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -165,29 +165,12 @@ If you want to do something asynchronously, convert this function to an asynchro
165165

166166
@[code python](../examples/state/async_generator_deps.py)
167167

168-
### Default dependencies
169-
170-
By default taskiq has only two dependencies:
171-
172-
- Context from `taskiq.context.Context`
173-
- TaskiqState from `taskiq.state.TaskiqState`
174-
175-
176-
### Adding first-level dependencies
177-
178-
You can expand default list of available dependencies for you application.
179-
Taskiq have an ability to add new first-level dependencies using brokers.
180-
181-
The AsyncBroker interface has a function called `add_dependency_context` and you can add
182-
more default dependencies to the taskiq. This may be useful for libraries if you want to
183-
add new dependencies to users.
184-
185168

186-
### Exception handling
169+
#### Exception handling
187170

188-
Dependencies can handle exceptions that happen in tasks. This feature is handy if you want your system to be more atomic.
171+
Generator dependencies can handle exceptions that happen in tasks. This feature is handy if you want your system to be more atomic.
189172

190-
For example, if you open a database transaction in your dependency and want to commit it only if the function is completed successfully.
173+
For example, if you open a database transaction in your dependency and want to commit it only if the function you execute is completed successfully.
191174

192175
```python
193176
async def get_transaction(db_driver: DBDriver = TaskiqDepends(get_driver)) -> AsyncGenerator[Transaction, None]:
@@ -211,3 +194,20 @@ taskiq worker my_file:broker --no-propagate-errors
211194
```
212195

213196
In this case, no exception will ever going to be propagated to any dependency.
197+
198+
### Default dependencies
199+
200+
By default taskiq has only two dependencies:
201+
202+
- Context from `taskiq.context.Context`
203+
- TaskiqState from `taskiq.state.TaskiqState`
204+
205+
206+
### Adding first-level dependencies
207+
208+
You can expand default list of available dependencies for you application.
209+
Taskiq have an ability to add new first-level dependencies using brokers.
210+
211+
The AsyncBroker interface has a function called `add_dependency_context` and you can add
212+
more default dependencies to the taskiq. This may be useful for libraries if you want to
213+
add new dependencies to users.

0 commit comments

Comments
 (0)