csrd-message 0.3.0__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.
@@ -0,0 +1,10 @@
1
+ """Messaging abstractions for publisher/consumer workflows.
2
+
3
+ This package intentionally provides broker-agnostic interfaces first.
4
+ Concrete adapters (for example RabbitMQ/Kafka) are expected to implement
5
+ these protocols in follow-up iterations.
6
+ """
7
+
8
+ from ._types import Acknowledgement, Message, MessageConsumer, MessagePublisher
9
+
10
+ __all__ = ("Acknowledgement", "Message", "MessageConsumer", "MessagePublisher")
csrd/message/_types.py ADDED
@@ -0,0 +1,38 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+ from datetime import UTC, datetime
5
+ from enum import StrEnum
6
+ from typing import Any, Protocol
7
+
8
+
9
+ class Acknowledgement(StrEnum):
10
+ """Consumer acknowledgement decision for a processed message."""
11
+
12
+ ACK = "ack"
13
+ RETRY = "retry"
14
+ REJECT = "reject"
15
+
16
+
17
+ @dataclass(frozen=True, slots=True)
18
+ class Message:
19
+ """Immutable transport-agnostic message envelope."""
20
+
21
+ topic: str
22
+ payload: dict[str, Any]
23
+ key: str | None = None
24
+ headers: dict[str, str] = field(default_factory=dict)
25
+ message_id: str | None = None
26
+ timestamp: datetime = field(default_factory=lambda: datetime.now(UTC))
27
+
28
+
29
+ class MessagePublisher(Protocol):
30
+ """Protocol contract for outbound message publishing."""
31
+
32
+ async def publish(self, message: Message) -> None: ...
33
+
34
+
35
+ class MessageConsumer(Protocol):
36
+ """Protocol contract for inbound message consumption."""
37
+
38
+ async def consume(self, message: Message) -> Acknowledgement: ...
csrd/message/py.typed ADDED
File without changes
@@ -0,0 +1,78 @@
1
+ Metadata-Version: 2.4
2
+ Name: csrd-message
3
+ Version: 0.3.0
4
+ Summary: Messaging abstractions for publisher/consumer workflows with optional RabbitMQ and Kafka extras
5
+ Project-URL: Repository, https://github.com/csrd-api/fastapi-common
6
+ Project-URL: Documentation, https://github.com/csrd-api/fastapi-common/tree/main/packages/message
7
+ Project-URL: Changelog, https://github.com/csrd-api/fastapi-common/blob/main/CHANGELOG.md
8
+ License: MIT
9
+ Requires-Python: >=3.12
10
+ Provides-Extra: all
11
+ Requires-Dist: aio-pika<10,>=9; extra == 'all'
12
+ Requires-Dist: aiokafka<1,>=0.11; extra == 'all'
13
+ Provides-Extra: kafka
14
+ Requires-Dist: aiokafka<1,>=0.11; extra == 'kafka'
15
+ Provides-Extra: rabbit
16
+ Requires-Dist: aio-pika<10,>=9; extra == 'rabbit'
17
+ Description-Content-Type: text/markdown
18
+
19
+ # csrd.message
20
+
21
+ Transport-agnostic message abstractions for publish/consume workflows.
22
+
23
+ ## Why this package exists
24
+
25
+ - Provide a stable API for messaging behavior independent of broker choice
26
+ - Enable optional broker installs with extras (`rabbit`, `kafka`)
27
+ - Keep service code portable across RabbitMQ and Kafka backends
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ # Core abstractions only
33
+ uv add csrd-message
34
+
35
+ # RabbitMQ support
36
+ uv add 'csrd-message[rabbit]'
37
+
38
+ # Kafka support
39
+ uv add 'csrd-message[kafka]'
40
+
41
+ # Both brokers
42
+ uv add 'csrd-message[all]'
43
+ ```
44
+
45
+ ## Important extras note
46
+
47
+ Python extras are part of the same PyPI project, not a separate project.
48
+
49
+ - `csrd-message` and `csrd-message[rabbit]` resolve to the same package name (`csrd-message`)
50
+ - The extra only adds optional dependencies declared by this package
51
+ - Extras do not create new package names on PyPI
52
+
53
+ ## Initial API surface
54
+
55
+ - `Message` - immutable message envelope
56
+ - `MessagePublisher` - protocol for publishing messages
57
+ - `MessageConsumer` - protocol for consuming messages
58
+ - `Acknowledgement` - ack/retry/reject semantics
59
+
60
+ ## Quick example
61
+
62
+ ```python
63
+ from csrd.message import Acknowledgement, Message, MessagePublisher
64
+
65
+
66
+ class InMemoryPublisher:
67
+ async def publish(self, message: Message) -> None:
68
+ print(message.topic, message.payload)
69
+
70
+
71
+ async def send(publisher: MessagePublisher) -> None:
72
+ await publisher.publish(Message(topic="orders.created", payload={"order_id": "o-1"}))
73
+ ```
74
+
75
+ ## Status
76
+
77
+ This is a v0 skeleton package to reserve naming and establish contracts.
78
+ Concrete RabbitMQ/Kafka adapters are planned follow-up work, while the shared envelope/protocol API is considered stable for early adopters.
@@ -0,0 +1,6 @@
1
+ csrd/message/__init__.py,sha256=qGquWw5hHJIXGYE2JAOoJz0cI1mZfYg4yxfVn9KQCVw,411
2
+ csrd/message/_types.py,sha256=W1gb-gW6u1uUfiJxx7geX9r1EQ8yDsaF7PAqyVnj5J0,1004
3
+ csrd/message/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ csrd_message-0.3.0.dist-info/METADATA,sha256=TQxYQkGnVZYDhTrEc6RpLNpMPPtmL6q8nrXmDBytc30,2430
5
+ csrd_message-0.3.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
6
+ csrd_message-0.3.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any