eventsourcing 9.5.0b3__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,164 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from abc import ABC, abstractmethod
5
+ from base64 import b64decode, b64encode
6
+ from typing import TYPE_CHECKING, Generic
7
+ from uuid import UUID
8
+
9
+ from eventsourcing.application import NotificationLog, Section, TApplication
10
+ from eventsourcing.persistence import Notification
11
+
12
+ if TYPE_CHECKING:
13
+ from collections.abc import Sequence
14
+
15
+
16
+ class NotificationLogInterface(ABC):
17
+ """Abstract base class for obtaining serialised
18
+ sections of a notification log.
19
+ """
20
+
21
+ @abstractmethod
22
+ def get_log_section(self, section_id: str) -> str:
23
+ """Returns a serialised :class:`~eventsourcing.application.Section`
24
+ from a notification log.
25
+ """
26
+
27
+ @abstractmethod
28
+ def get_notifications(
29
+ self,
30
+ start: int | None,
31
+ limit: int,
32
+ topics: Sequence[str] = (),
33
+ *,
34
+ inclusive_of_start: bool = True,
35
+ ) -> str:
36
+ """Returns a serialised list of :class:`~eventsourcing.persistence.Notification`
37
+ objects from a notification log.
38
+ """
39
+
40
+
41
+ class NotificationLogJSONService(NotificationLogInterface, Generic[TApplication]):
42
+ """Presents serialised sections of a notification log."""
43
+
44
+ def __init__(self, app: TApplication):
45
+ """Initialises service with given application."""
46
+ self.app = app
47
+
48
+ def get_log_section(self, section_id: str) -> str:
49
+ """Returns JSON serialised :class:`~eventsourcing.application.Section`
50
+ from a notification log.
51
+ """
52
+ section = self.app.notification_log[section_id]
53
+ return json.dumps(
54
+ {
55
+ "id": section.id,
56
+ "next_id": section.next_id,
57
+ "items": [
58
+ {
59
+ "id": item.id,
60
+ "originator_id": (
61
+ item.originator_id.hex
62
+ if isinstance(item.originator_id, UUID)
63
+ else item.originator_id
64
+ ),
65
+ "originator_version": item.originator_version,
66
+ "topic": item.topic,
67
+ "state": b64encode(item.state).decode("utf8"),
68
+ }
69
+ for item in section.items
70
+ ],
71
+ }
72
+ )
73
+
74
+ def get_notifications(
75
+ self,
76
+ start: int | None,
77
+ limit: int,
78
+ topics: Sequence[str] = (),
79
+ *,
80
+ inclusive_of_start: bool = True,
81
+ ) -> str:
82
+ notifications = self.app.notification_log.select(
83
+ start=start,
84
+ limit=limit,
85
+ topics=topics,
86
+ inclusive_of_start=inclusive_of_start,
87
+ )
88
+ return json.dumps(
89
+ [
90
+ {
91
+ "id": notification.id,
92
+ "originator_id": (
93
+ notification.originator_id.hex
94
+ if isinstance(notification.originator_id, UUID)
95
+ else notification.originator_id
96
+ ),
97
+ "originator_version": notification.originator_version,
98
+ "topic": notification.topic,
99
+ "state": b64encode(notification.state).decode("utf8"),
100
+ }
101
+ for notification in notifications
102
+ ]
103
+ )
104
+
105
+
106
+ class NotificationLogJSONClient(NotificationLog):
107
+ """Presents deserialized sections of a notification log."""
108
+
109
+ def __init__(self, interface: NotificationLogInterface):
110
+ """Initialises log with a given interface."""
111
+ self.interface = interface
112
+
113
+ def __getitem__(self, section_id: str) -> Section:
114
+ """Returns a :class:`Section` of
115
+ :class:`~eventsourcing.persistence.Notification` objects
116
+ from the notification log.
117
+ """
118
+ body = self.interface.get_log_section(section_id)
119
+ section = json.loads(body)
120
+ return Section(
121
+ id=section["id"],
122
+ next_id=section["next_id"],
123
+ items=[
124
+ Notification(
125
+ id=item["id"],
126
+ originator_id=UUID(item["originator_id"]),
127
+ originator_version=item["originator_version"],
128
+ topic=item["topic"],
129
+ state=b64decode(item["state"].encode("utf8")),
130
+ )
131
+ for item in section["items"]
132
+ ],
133
+ )
134
+
135
+ def select(
136
+ self,
137
+ start: int | None,
138
+ limit: int,
139
+ stop: int | None = None,
140
+ topics: Sequence[str] = (),
141
+ *,
142
+ inclusive_of_start: bool = True,
143
+ ) -> list[Notification]:
144
+ """Returns a selection of
145
+ :class:`~eventsourcing.persistence.Notification` objects
146
+ from the notification log.
147
+ """
148
+ return [
149
+ Notification(
150
+ id=item["id"],
151
+ originator_id=UUID(item["originator_id"]),
152
+ originator_version=item["originator_version"],
153
+ topic=item["topic"],
154
+ state=b64decode(item["state"].encode("utf8")),
155
+ )
156
+ for item in json.loads(
157
+ self.interface.get_notifications(
158
+ start=start,
159
+ limit=limit,
160
+ topics=topics,
161
+ inclusive_of_start=inclusive_of_start,
162
+ )
163
+ )
164
+ ]