ltq 0.2.0__tar.gz → 0.3.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.
- {ltq-0.2.0 → ltq-0.3.0}/PKG-INFO +32 -4
- {ltq-0.2.0 → ltq-0.3.0}/README.md +31 -3
- {ltq-0.2.0 → ltq-0.3.0}/pyproject.toml +2 -2
- {ltq-0.2.0 → ltq-0.3.0}/src/ltq/scheduler.py +13 -12
- {ltq-0.2.0 → ltq-0.3.0}/src/ltq/__init__.py +0 -0
- {ltq-0.2.0 → ltq-0.3.0}/src/ltq/app.py +0 -0
- {ltq-0.2.0 → ltq-0.3.0}/src/ltq/cli.py +0 -0
- {ltq-0.2.0 → ltq-0.3.0}/src/ltq/errors.py +0 -0
- {ltq-0.2.0 → ltq-0.3.0}/src/ltq/logger.py +0 -0
- {ltq-0.2.0 → ltq-0.3.0}/src/ltq/message.py +0 -0
- {ltq-0.2.0 → ltq-0.3.0}/src/ltq/middleware.py +0 -0
- {ltq-0.2.0 → ltq-0.3.0}/src/ltq/q.py +0 -0
- {ltq-0.2.0 → ltq-0.3.0}/src/ltq/task.py +0 -0
- {ltq-0.2.0 → ltq-0.3.0}/src/ltq/utils.py +0 -0
- {ltq-0.2.0 → ltq-0.3.0}/src/ltq/worker.py +0 -0
{ltq-0.2.0 → ltq-0.3.0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: ltq
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Add your description here
|
|
5
5
|
Author: Tom Clesius
|
|
6
6
|
Author-email: Tom Clesius <tomclesius@gmail.com>
|
|
@@ -45,12 +45,12 @@ async def main():
|
|
|
45
45
|
# Enqueue a task
|
|
46
46
|
await send_email.send("user@example.com", "Hello", "World")
|
|
47
47
|
|
|
48
|
-
# Or
|
|
48
|
+
# Or dispatch in bulk
|
|
49
49
|
messages = [
|
|
50
50
|
send_email.message("a@example.com", "Hi", "A"),
|
|
51
51
|
send_email.message("b@example.com", "Hi", "B"),
|
|
52
52
|
]
|
|
53
|
-
await
|
|
53
|
+
await ltq.dispatch(messages)
|
|
54
54
|
|
|
55
55
|
asyncio.run(main())
|
|
56
56
|
```
|
|
@@ -68,13 +68,41 @@ async def send_newsletter(...): ...
|
|
|
68
68
|
## Running Workers
|
|
69
69
|
|
|
70
70
|
```bash
|
|
71
|
-
# Run a worker
|
|
71
|
+
# Run a single worker
|
|
72
72
|
ltq myapp:worker
|
|
73
73
|
|
|
74
74
|
# With options
|
|
75
75
|
ltq myapp:worker --concurrency 100 --log-level DEBUG
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
+
## Running an App
|
|
79
|
+
|
|
80
|
+
Register multiple workers into an `App` to run them together:
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
import ltq
|
|
84
|
+
|
|
85
|
+
app = ltq.App()
|
|
86
|
+
app.register_worker(emails_worker)
|
|
87
|
+
app.register_worker(notifications_worker)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
ltq --app myapp:app
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Scheduler
|
|
95
|
+
|
|
96
|
+
Run tasks on a cron schedule (requires `ltq[scheduler]`):
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
import ltq
|
|
100
|
+
|
|
101
|
+
scheduler = ltq.Scheduler()
|
|
102
|
+
scheduler.cron("*/5 * * * *", send_email.message("admin@example.com", "Report", "..."))
|
|
103
|
+
scheduler.run()
|
|
104
|
+
```
|
|
105
|
+
|
|
78
106
|
## Middleware
|
|
79
107
|
|
|
80
108
|
Add middleware to handle cross-cutting concerns:
|
|
@@ -31,12 +31,12 @@ async def main():
|
|
|
31
31
|
# Enqueue a task
|
|
32
32
|
await send_email.send("user@example.com", "Hello", "World")
|
|
33
33
|
|
|
34
|
-
# Or
|
|
34
|
+
# Or dispatch in bulk
|
|
35
35
|
messages = [
|
|
36
36
|
send_email.message("a@example.com", "Hi", "A"),
|
|
37
37
|
send_email.message("b@example.com", "Hi", "B"),
|
|
38
38
|
]
|
|
39
|
-
await
|
|
39
|
+
await ltq.dispatch(messages)
|
|
40
40
|
|
|
41
41
|
asyncio.run(main())
|
|
42
42
|
```
|
|
@@ -54,13 +54,41 @@ async def send_newsletter(...): ...
|
|
|
54
54
|
## Running Workers
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
|
-
# Run a worker
|
|
57
|
+
# Run a single worker
|
|
58
58
|
ltq myapp:worker
|
|
59
59
|
|
|
60
60
|
# With options
|
|
61
61
|
ltq myapp:worker --concurrency 100 --log-level DEBUG
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
+
## Running an App
|
|
65
|
+
|
|
66
|
+
Register multiple workers into an `App` to run them together:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
import ltq
|
|
70
|
+
|
|
71
|
+
app = ltq.App()
|
|
72
|
+
app.register_worker(emails_worker)
|
|
73
|
+
app.register_worker(notifications_worker)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
ltq --app myapp:app
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Scheduler
|
|
81
|
+
|
|
82
|
+
Run tasks on a cron schedule (requires `ltq[scheduler]`):
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
import ltq
|
|
86
|
+
|
|
87
|
+
scheduler = ltq.Scheduler()
|
|
88
|
+
scheduler.cron("*/5 * * * *", send_email.message("admin@example.com", "Report", "..."))
|
|
89
|
+
scheduler.run()
|
|
90
|
+
```
|
|
91
|
+
|
|
64
92
|
## Middleware
|
|
65
93
|
|
|
66
94
|
Add middleware to handle cross-cutting concerns:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "ltq"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.0"
|
|
4
4
|
description = "Add your description here"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [{ name = "Tom Clesius", email = "tomclesius@gmail.com" }]
|
|
@@ -19,7 +19,7 @@ requires = ["uv_build>=0.9.26,<0.10.0"]
|
|
|
19
19
|
build-backend = "uv_build"
|
|
20
20
|
|
|
21
21
|
[tool.bumpversion]
|
|
22
|
-
current_version = "0.
|
|
22
|
+
current_version = "0.3.0"
|
|
23
23
|
commit = true
|
|
24
24
|
tag = true
|
|
25
25
|
message = "v{new_version}"
|
|
@@ -4,21 +4,17 @@ import asyncio
|
|
|
4
4
|
import time
|
|
5
5
|
from dataclasses import dataclass, field
|
|
6
6
|
from datetime import datetime
|
|
7
|
-
from typing import TYPE_CHECKING
|
|
7
|
+
from typing import TYPE_CHECKING, Any
|
|
8
8
|
|
|
9
9
|
from .message import Message
|
|
10
|
-
|
|
11
|
-
try:
|
|
12
|
-
from croniter import croniter # type: ignore[import-not-found]
|
|
13
|
-
except ModuleNotFoundError as exc:
|
|
14
|
-
raise ModuleNotFoundError(
|
|
15
|
-
"Scheduler requires optional dependency 'croniter'. "
|
|
16
|
-
"Install with 'ltq[scheduler]'."
|
|
17
|
-
) from exc
|
|
18
|
-
|
|
19
10
|
from .utils import dispatch
|
|
20
11
|
from .logger import get_logger
|
|
21
12
|
|
|
13
|
+
try:
|
|
14
|
+
from croniter import croniter
|
|
15
|
+
except ImportError:
|
|
16
|
+
croniter = None
|
|
17
|
+
|
|
22
18
|
if TYPE_CHECKING:
|
|
23
19
|
from .task import Task
|
|
24
20
|
|
|
@@ -28,11 +24,11 @@ class ScheduledJob:
|
|
|
28
24
|
task: Task
|
|
29
25
|
msg: Message
|
|
30
26
|
expr: str
|
|
31
|
-
_cron:
|
|
27
|
+
_cron: Any = field(init=False, repr=False) # croniter instance
|
|
32
28
|
next_run: datetime = field(init=False)
|
|
33
29
|
|
|
34
30
|
def __post_init__(self):
|
|
35
|
-
self._cron = croniter(self.expr, datetime.now())
|
|
31
|
+
self._cron = croniter(self.expr, datetime.now()) # type: ignore[misc]
|
|
36
32
|
self.advance()
|
|
37
33
|
|
|
38
34
|
def advance(self) -> None:
|
|
@@ -47,6 +43,11 @@ class Scheduler:
|
|
|
47
43
|
self._running = False
|
|
48
44
|
|
|
49
45
|
def cron(self, expr: str, msg: Message) -> None:
|
|
46
|
+
if croniter is None:
|
|
47
|
+
raise ModuleNotFoundError(
|
|
48
|
+
"Scheduler requires optional dependency 'croniter'. "
|
|
49
|
+
"Install with 'ltq[scheduler]'."
|
|
50
|
+
)
|
|
50
51
|
if msg.task is None:
|
|
51
52
|
raise ValueError("Message must have a task assigned to use with scheduler")
|
|
52
53
|
self.jobs.append(ScheduledJob(msg.task, msg, expr))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|