taskqueue-toolkit 0.1.0__py3-none-any.whl → 0.1.1__py3-none-any.whl

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.
@@ -6,10 +6,13 @@ import logging
6
6
  from collections.abc import AsyncIterator, Callable
7
7
  from contextlib import AbstractAsyncContextManager, asynccontextmanager
8
8
  from dataclasses import dataclass, field
9
+ from typing import TYPE_CHECKING
9
10
 
10
11
  import aioboto3
11
- from types_aiobotocore_sns.client import SNSClient
12
- from types_aiobotocore_sqs.client import SQSClient
12
+
13
+ if TYPE_CHECKING:
14
+ from types_aiobotocore_sns.client import SNSClient
15
+ from types_aiobotocore_sqs.client import SQSClient
13
16
 
14
17
  from taskqueue_toolkit.queue.aws_session import aws_session_kwargs
15
18
  from taskqueue_toolkit.queue.dsn import SnsDsn
@@ -20,7 +23,7 @@ logger = logging.getLogger(__name__)
20
23
  _LONG_POLL_WAIT_SECONDS = 10
21
24
  _SUBSCRIBER_QUEUE_SUFFIX = "-subscriber"
22
25
 
23
- ClientFactory = Callable[[SnsDsn], AbstractAsyncContextManager[tuple[SNSClient, SQSClient]]]
26
+ ClientFactory = Callable[[SnsDsn], AbstractAsyncContextManager["tuple[SNSClient, SQSClient]"]]
24
27
 
25
28
 
26
29
  @asynccontextmanager
@@ -5,10 +5,12 @@ import logging
5
5
  from collections.abc import AsyncIterator, Callable
6
6
  from contextlib import AbstractAsyncContextManager
7
7
  from dataclasses import dataclass, field
8
- from typing import cast
8
+ from typing import TYPE_CHECKING, cast
9
9
 
10
10
  import aioboto3
11
- from types_aiobotocore_sqs.client import SQSClient
11
+
12
+ if TYPE_CHECKING:
13
+ from types_aiobotocore_sqs.client import SQSClient
12
14
 
13
15
  from taskqueue_toolkit.queue.aws_session import aws_session_kwargs
14
16
  from taskqueue_toolkit.queue.dsn import SqsDsn
@@ -18,7 +20,7 @@ logger = logging.getLogger(__name__)
18
20
 
19
21
  _LONG_POLL_WAIT_SECONDS = 10
20
22
 
21
- ClientFactory = Callable[[SqsDsn], AbstractAsyncContextManager[SQSClient]]
23
+ ClientFactory = Callable[[SqsDsn], AbstractAsyncContextManager["SQSClient"]]
22
24
 
23
25
 
24
26
  def _default_client_factory(dsn: SqsDsn) -> AbstractAsyncContextManager[SQSClient]:
@@ -7,6 +7,12 @@ T = TypeVar("T")
7
7
  T_co = TypeVar("T_co", covariant=True)
8
8
 
9
9
  Encoder = Callable[[T], bytes]
10
+ # SECURITY: Decoder runs on bytes received from a broker — a source outside
11
+ # this process's control in most deployments. Using an unsafe deserializer
12
+ # here (pickle.loads, yaml.load without SafeLoader, eval, ...) turns
13
+ # whoever can publish to your queue/topic into someone who can run
14
+ # arbitrary code in your consumer. Prefer a safe format (json, msgpack,
15
+ # protobuf) unless every publisher is fully trusted.
10
16
  Decoder = Callable[[bytes], T]
11
17
 
12
18
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: taskqueue-toolkit
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: Broker-agnostic async task queue (RabbitMQ, SQS, SNS, Redis Streams, Pub/Sub) with a Postgres outbox pattern
5
5
  Author: Walid Boughdiri
6
6
  Author-email: Walid Boughdiri <walid.boughdiri@gmail.com>
@@ -152,6 +152,12 @@ Each adapter constructor takes an injectable client/connection factory for exact
152
152
 
153
153
  Create one broker instance per test — each owns its own isolated in-memory state, so there's nothing to reset between tests and no risk of one test's queue leaking into another's.
154
154
 
155
+ ## Security
156
+
157
+ `Decoder[T]` runs on bytes received from a broker — in most deployments, a source outside this process's control. Using an unsafe deserializer (`pickle.loads`, `yaml.load` without `SafeLoader`, `eval`, ...) as your `decode` callback means whoever can publish to your queue/topic can run arbitrary code in your consumer. Use a safe format (JSON, msgpack, protobuf, ...) unless every publisher is fully trusted.
158
+
159
+ This package's own code is checked on every push/PR and before every release via [bandit](https://bandit.readthedocs.io/) (unsafe code patterns) and [pip-audit](https://github.com/pypa/pip-audit) (known CVEs in resolved dependencies), alongside ruff, mypy, and the test suite. Found a vulnerability? Please open an issue.
160
+
155
161
  ## Development
156
162
 
157
163
  ```bash
@@ -160,4 +166,6 @@ uv run pytest
160
166
  uv run ruff check .
161
167
  uv run ruff format .
162
168
  uv run mypy .
169
+ uvx bandit -r src/
170
+ uvx pip-audit --path .venv
163
171
  ```
@@ -12,16 +12,16 @@ taskqueue_toolkit/queue/pubsub.py,sha256=btCmGr0s6TG6pgkEvV_vgKJMYyhqD8YoQ_ez_da
12
12
  taskqueue_toolkit/queue/rabbitmq.py,sha256=EKfbYsOhbrpsQ25qNO6_B2Ljw3x37qYTzIw7KZcb8ts,2841
13
13
  taskqueue_toolkit/queue/redis_streams.py,sha256=0M5JJ9ong9AN4OklsddhoxZwco7vHJYKHr2gehoLfaU,4566
14
14
  taskqueue_toolkit/queue/registry.py,sha256=ylXRKCoLvgPe6zWNs9S8HqJ9ta6-Ggb2p8crFqLAZks,2063
15
- taskqueue_toolkit/queue/sns.py,sha256=s-xUDNegjON_dVt9nH4BzE4iJnHVnbHg5LhxB67p9t4,6394
16
- taskqueue_toolkit/queue/sqs.py,sha256=xIqNeCWjw79zgxTO-tJr5z5FLQ5k0jUPs0W4KiOwpI0,3955
17
- taskqueue_toolkit/queue/task_queue.py,sha256=T7CTpvOUHhU5A0T5qc806cJTg9QI8SxjAnh0HJaTxAk,2414
15
+ taskqueue_toolkit/queue/sns.py,sha256=S1PC0cFMY2rosxW-vrfVbA6qe5pmgKrZQStc83iBuzA,6456
16
+ taskqueue_toolkit/queue/sqs.py,sha256=gIO4CNAScRo1p7rxRkxZjnjyk6IcL1bo1SN-UH_1T4Q,3995
17
+ taskqueue_toolkit/queue/task_queue.py,sha256=xhqeLr4GxiQj_iAwxCLfT3FAhtcJZXoFA1jxcyCTrgY,2828
18
18
  taskqueue_toolkit/testing/__init__.py,sha256=7pg6csGeC-X-RN4q9bTcNQGzfmwk2leK7rTmD-aQmmI,2292
19
19
  taskqueue_toolkit/testing/pubsub.py,sha256=BFZs1MIYvJqznZ3FUSjwtJbLuzWTMUCGd2C5T2ZfvQc,4936
20
20
  taskqueue_toolkit/testing/rabbitmq.py,sha256=pV20m7mHLXfaEP6nm5QR00VdYsm4wzZYQArzcSX0u6Y,4125
21
21
  taskqueue_toolkit/testing/redis_streams.py,sha256=jBYBwVay0MVHEbcSGcBL_F4PB4X4JemDHpHQkM05eCs,5284
22
22
  taskqueue_toolkit/testing/sns.py,sha256=4YviIp20jMLyJFYPcsfCXe6aDzCbhtHbtnShhFEf-BA,5756
23
23
  taskqueue_toolkit/testing/sqs.py,sha256=a7vR9tYJlu08OpEroIAyQVWubD8UBHs8buKIyDSDSiE,4046
24
- taskqueue_toolkit-0.1.0.dist-info/licenses/LICENSE,sha256=XDbMvYj2p3w41uQF87jluQnQa74jSKmlpLhIsDdatQw,11346
25
- taskqueue_toolkit-0.1.0.dist-info/WHEEL,sha256=4OL6Foqnnp3xRY5wMkjgc25_i5YJC6dKsC6LPcjqEoU,80
26
- taskqueue_toolkit-0.1.0.dist-info/METADATA,sha256=4QlxVvKliEbrHDZr_Jn81j2L8OFzdpkaMxfOginEL6s,8888
27
- taskqueue_toolkit-0.1.0.dist-info/RECORD,,
24
+ taskqueue_toolkit-0.1.1.dist-info/licenses/LICENSE,sha256=XDbMvYj2p3w41uQF87jluQnQa74jSKmlpLhIsDdatQw,11346
25
+ taskqueue_toolkit-0.1.1.dist-info/WHEEL,sha256=4OL6Foqnnp3xRY5wMkjgc25_i5YJC6dKsC6LPcjqEoU,80
26
+ taskqueue_toolkit-0.1.1.dist-info/METADATA,sha256=GqcucH9lD2rfItGKBp7PKQOXGuKxOaz5yWVyu_-hhuA,9683
27
+ taskqueue_toolkit-0.1.1.dist-info/RECORD,,