buz 2.16.0__py3-none-any.whl → 2.17.0rc1__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.
@@ -10,9 +10,11 @@ class EventToOutboxRecordTranslator:
10
10
  payload = dataclasses.asdict(event)
11
11
  payload.pop("id")
12
12
  payload.pop("created_at")
13
+ payload.pop("metadata")
13
14
  return OutboxRecord(
14
15
  event_id=UUID(event.id),
15
16
  event_fqn=event.fqn(),
16
17
  created_at=event.parsed_created_at(),
17
18
  event_payload=payload,
19
+ event_metadata=event.metadata,
18
20
  )
@@ -2,6 +2,7 @@ from datetime import datetime
2
2
  from typing import Optional, Any, ClassVar
3
3
  from uuid import UUID
4
4
  from dataclasses import dataclass, fields
5
+ from dataclasses import field as dataclass_field
5
6
 
6
7
 
7
8
  @dataclass
@@ -12,6 +13,7 @@ class OutboxRecord: # type: ignore[misc]
12
13
  event_fqn: str
13
14
  event_payload: dict[str, Any] # type: ignore[misc]
14
15
  created_at: datetime
16
+ event_metadata: Optional[dict[str, Any]] = dataclass_field(default_factory=dict) # type: ignore[misc]
15
17
  delivered_at: Optional[datetime] = None
16
18
  delivery_errors: int = 0
17
19
  delivery_paused_at: Optional[datetime] = None
@@ -16,6 +16,7 @@ class OutboxRecordToEventTranslator:
16
16
  event_klass.restore(
17
17
  id=str(outbox_record.event_id),
18
18
  created_at=outbox_record.parsed_created_at(),
19
+ metadata=outbox_record.event_metadata,
19
20
  **outbox_record.event_payload,
20
21
  ),
21
22
  )
@@ -1,4 +1,5 @@
1
1
  from dataclasses import dataclass
2
+ from typing import Optional
2
3
 
3
4
 
4
5
  @dataclass(frozen=True)
@@ -9,6 +10,7 @@ class CDCPayload:
9
10
  event_id: str # uuid
10
11
  created_at: str
11
12
  event_fqn: str
13
+ event_metadata: Optional[str] = None # json encoded
12
14
 
13
15
  def validate(self) -> None:
14
16
  if not isinstance(self.payload, str):
@@ -19,6 +21,8 @@ class CDCPayload:
19
21
  raise ValueError("The created_at value is not a value")
20
22
  if not isinstance(self.event_fqn, str):
21
23
  raise ValueError("The event_fqn value is not a valid value")
24
+ if self.event_metadata is not None and not isinstance(self.event_metadata, str):
25
+ raise ValueError("The event_metadata value is not a valid value")
22
26
 
23
27
  def __post_init__(self) -> None:
24
28
  self.validate()
@@ -22,6 +22,13 @@ def generate_cdc_schema(message: Message) -> dict:
22
22
  "optional": False,
23
23
  "field": "event_fqn",
24
24
  },
25
+ {
26
+ "type": "string",
27
+ "optional": True,
28
+ "name": "io.debezium.data.Json",
29
+ "version": 1,
30
+ "field": "event_metadata",
31
+ },
25
32
  {
26
33
  "type": "string",
27
34
  "optional": False,
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from datetime import datetime
4
- from typing import TypeVar, Type, Generic
4
+ from typing import Optional, TypeVar, Type, Generic
5
5
 
6
6
  import orjson
7
7
  from dacite import from_dict
@@ -29,6 +29,7 @@ class CDCRecordBytesToEventDeserializer(BytesToMessageDeserializer[Event], Gener
29
29
  return self.__event_class.restore(
30
30
  id=cdc_payload.event_id,
31
31
  created_at=self.__get_created_at_in_event_format(cdc_payload.created_at),
32
+ metadata=self.__deserialize_event_metadata(cdc_payload.event_metadata),
32
33
  **orjson.loads(cdc_payload.payload),
33
34
  )
34
35
  except Exception as exception:
@@ -47,3 +48,9 @@ class CDCRecordBytesToEventDeserializer(BytesToMessageDeserializer[Event], Gener
47
48
  raise ValueError("The provided payload value is not valid")
48
49
 
49
50
  return from_dict(CDCPayload, payload)
51
+
52
+ def __deserialize_event_metadata(self, event_metadata: Optional[str]) -> dict:
53
+ if event_metadata is None:
54
+ return {}
55
+
56
+ return orjson.loads(event_metadata)
@@ -21,6 +21,7 @@ class CDCRecordBytesToEventSerializer(ByteSerializer):
21
21
  created_at=self.__adapt_created_to_cdc_format(data.created_at),
22
22
  event_fqn=data.fqn(),
23
23
  payload=self.__serialize_payload(data),
24
+ event_metadata=self.__serialize_event_metadata(data),
24
25
  ),
25
26
  schema=generate_cdc_schema(data),
26
27
  )
@@ -31,8 +32,14 @@ class CDCRecordBytesToEventSerializer(ByteSerializer):
31
32
  return created_at_datetime.strftime(CDCPayload.DATE_TIME_FORMAT)
32
33
 
33
34
  def __serialize_payload(self, event: Event) -> str:
34
- # Remove id and created at, because Transactional outbox is not adding them
35
35
  payload = asdict(event)
36
36
  del payload["id"]
37
37
  del payload["created_at"]
38
+ del payload["metadata"]
38
39
  return self.__json_serializer.serialize_as_json(payload)
40
+
41
+ def __serialize_event_metadata(self, event: Event) -> str:
42
+ if event.metadata is None:
43
+ return str({})
44
+
45
+ return self.__json_serializer.serialize_as_json(event.metadata)
buz/message.py CHANGED
@@ -3,7 +3,7 @@ from dataclasses import field, dataclass
3
3
  from datetime import datetime
4
4
  from inspect import signature, Parameter
5
5
  from types import MappingProxyType
6
- from typing import Any, ClassVar, get_origin, get_args, Union
6
+ from typing import Any, ClassVar, Optional, get_origin, get_args, Union
7
7
  from typing_extensions import Self
8
8
 
9
9
  from uuid_utils.compat import uuid7
@@ -17,6 +17,7 @@ class Message(ABC):
17
17
  created_at: str = field(
18
18
  init=False, default_factory=lambda: datetime.strftime(datetime.now(), Message.DATE_TIME_FORMAT)
19
19
  )
20
+ metadata: Optional[dict[str, Any]] = field(init=False, default_factory=dict)
20
21
 
21
22
  @classmethod
22
23
  def fqn(cls) -> str:
@@ -26,11 +27,13 @@ class Message(ABC):
26
27
  def restore(cls, **kwargs: Any) -> Self:
27
28
  message_id = kwargs.pop("id")
28
29
  created_at = kwargs.pop("created_at")
30
+ metadata = kwargs.pop("metadata", dict())
29
31
 
30
32
  instance = cls.__from_dict(kwargs) # type: ignore
31
33
 
32
34
  object.__setattr__(instance, "id", message_id)
33
35
  object.__setattr__(instance, "created_at", created_at)
36
+ object.__setattr__(instance, "metadata", metadata)
34
37
  return instance
35
38
 
36
39
  @classmethod
@@ -61,3 +64,12 @@ class Message(ABC):
61
64
 
62
65
  def parsed_created_at(self) -> datetime:
63
66
  return datetime.strptime(self.created_at, self.DATE_TIME_FORMAT)
67
+
68
+ def add_metadata(self, metadata: Optional[dict[str, Any]]) -> None:
69
+ if metadata is None:
70
+ return None
71
+
72
+ if self.metadata is None:
73
+ object.__setattr__(self, "metadata", metadata)
74
+ else:
75
+ self.metadata.update(metadata)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: buz
3
- Version: 2.16.0
3
+ Version: 2.17.0rc1
4
4
  Summary: Buz is a set of light, simple and extensible implementations of event, command and query buses.
5
5
  License: MIT
6
6
  Author: Luis Pintado Lozano
@@ -121,18 +121,18 @@ buz/event/sync/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
121
121
  buz/event/sync/models/sync_delivery_context.py,sha256=LHjrS6gV-19NEKwtAXVmefjPd-Dsp_Ym8RZb84T3lm8,190
122
122
  buz/event/sync/sync_event_bus.py,sha256=LTJHNKy8LrbygO343AA4Zt_hmgTP9uY6TLdjKs8LuHM,1821
123
123
  buz/event/transactional_outbox/__init__.py,sha256=k8ZBWCi12pWKXchHfgW_Raw4sVR8XkBLuPNW9jB9X2k,1381
124
- buz/event/transactional_outbox/event_to_outbox_record_translator.py,sha256=oSn1iQuW-cZLvlXYIJPnSwm3JYUwGMm9f1pqnlF0cJI,534
124
+ buz/event/transactional_outbox/event_to_outbox_record_translator.py,sha256=HB6tBGzO2WMvl5g-wyWUZIOOgcyiFyEH8Iruv_mVOuM,609
125
125
  buz/event/transactional_outbox/fqn_to_event_mapper.py,sha256=ujcq6CfYqRJtM8f3SEEltbWN0Ru7NM5JfrbNdh4nvhQ,773
126
126
  buz/event/transactional_outbox/outbox_criteria/__init__.py,sha256=_9YjtbyYdqvDKEAwSQUyOn46Fc2pSNzTl2I7AqisEoc,594
127
127
  buz/event/transactional_outbox/outbox_criteria/deliverable_records_outbox_criteria_factory.py,sha256=vnaf6OPBAiw78RJZ8iOtaISbvuDIj4gN31aR-5k3BL8,347
128
128
  buz/event/transactional_outbox/outbox_criteria/outbox_criteria.py,sha256=HlD7tt3V-qVdPrq4H0idvyDnP7ncD0ZYQJ_XkwLNg-o,695
129
129
  buz/event/transactional_outbox/outbox_criteria/outbox_criteria_factory.py,sha256=XvqOfd7coi2veXyAvAthIBYRxS0Gpfb70nnkq9igvVM,220
130
130
  buz/event/transactional_outbox/outbox_criteria/outbox_sorting_criteria.py,sha256=-ckCLHvHlkuabI0TZ4Tw-qAQhU1hFLAgCOwuvIs_vpI,89
131
- buz/event/transactional_outbox/outbox_record.py,sha256=r8V8eQpuyS5UMS8r7viR2Z-mmEq-ZiakhO7f8TApd5E,1151
131
+ buz/event/transactional_outbox/outbox_record.py,sha256=8UxPydEFt5qHwfxR20kjte-xO0x9JDjAL6DJvqQtKdQ,1307
132
132
  buz/event/transactional_outbox/outbox_record_finder/__init__.py,sha256=HdW8GTIaxYExlUWeXugFmkRDyHcBiOlAVwh17dpPOfQ,344
133
133
  buz/event/transactional_outbox/outbox_record_finder/outbox_record_stream_finder.py,sha256=RjCetETAggQ5arXI4Terpyvh7xfz0eXXZon2-C1gXgw,239
134
134
  buz/event/transactional_outbox/outbox_record_finder/polling_outbox_record_stream_finder.py,sha256=qdCsqPQaS6cJ7li0veA2bY17iUG7fd84MzIywG7cPHw,1078
135
- buz/event/transactional_outbox/outbox_record_to_event_translator.py,sha256=StGyBfJsvRP9nJGckxufO2zVAd8xNIjdLVlfCZ2WAd4,746
135
+ buz/event/transactional_outbox/outbox_record_to_event_translator.py,sha256=NIu4HpuRwA8-qW_qjTEIxNd681uRMtW-cueWNZL9oyI,801
136
136
  buz/event/transactional_outbox/outbox_record_validation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
137
137
  buz/event/transactional_outbox/outbox_record_validation/abstract_outbox_record_validator.py,sha256=brOrVum-1bOTU-mTXqQ1WdaPzoVJdQa58sSPQ3U0XcY,610
138
138
  buz/event/transactional_outbox/outbox_record_validation/outbox_record_size_not_allowed_exception.py,sha256=kHvQXgYwJbvF3ZW558NzbdydqsuggnDCcjgesi0G9W8,749
@@ -179,13 +179,13 @@ buz/kafka/infrastructure/aiokafka/translators/__init__.py,sha256=47DEQpj8HBSa-_T
179
179
  buz/kafka/infrastructure/aiokafka/translators/consumer_initial_offset_position_translator.py,sha256=WmxkQfoXeTy9mIJtGGhM0eDKeQxhcJczeVAGCbtonVI,617
180
180
  buz/kafka/infrastructure/cdc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
181
181
  buz/kafka/infrastructure/cdc/cdc_message.py,sha256=Cpv2nA19SG3HZGBLH-wIJbuokzTTZKT_HNFm1VwGSk4,585
182
- buz/kafka/infrastructure/cdc/cdc_payload.py,sha256=tQ_HdiREkORHlDoQQraj-KQj0x5MRuV8vP-C4x3cgHY,793
183
- buz/kafka/infrastructure/cdc/cdc_schema.py,sha256=JVSj6MSWNh2aaoWp1LL8UNJtjBvKggoBgMtOOT0vkQQ,940
182
+ buz/kafka/infrastructure/cdc/cdc_payload.py,sha256=0dIsni7Z_Cy625op5SCAW3PLSJ1mBA9ty7LYP-aLUa4,1045
183
+ buz/kafka/infrastructure/cdc/cdc_schema.py,sha256=s6Ab0Ccztnl63_jjZC1xXxsmE4ajr6KtkDDyEm_ssAU,1159
184
184
  buz/kafka/infrastructure/deserializers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
185
185
  buz/kafka/infrastructure/deserializers/byte_deserializer.py,sha256=4fc6t-zvcFx6F5eoyEixH2uN0cM6aB0YRGwowIzz1RA,211
186
186
  buz/kafka/infrastructure/deserializers/bytes_to_message_deserializer.py,sha256=r40yq67DIElPi6ClmElbtR3VGrG2grNwgwuflXWOh20,345
187
187
  buz/kafka/infrastructure/deserializers/implementations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
188
- buz/kafka/infrastructure/deserializers/implementations/cdc/cdc_record_bytes_to_event_deserializer.py,sha256=iMTx9zI_QzHcHvCbpfUkq6Hp67O_LXK5iYE1nzt_mqA,1913
188
+ buz/kafka/infrastructure/deserializers/implementations/cdc/cdc_record_bytes_to_event_deserializer.py,sha256=5ptC3yZHAXaoySpAeLPRDtZkXE0IFDdeEOH4GHJ7eIk,2197
189
189
  buz/kafka/infrastructure/deserializers/implementations/cdc/not_valid_cdc_message_exception.py,sha256=hgLLwTcC-C2DuJSOWUhmQsrd1bO9I1469869IqfAPOk,414
190
190
  buz/kafka/infrastructure/deserializers/implementations/json_byte_deserializer.py,sha256=L4b164-KweiQUwyRONhTMIGnAz48UPk0btLqjGOTNdk,373
191
191
  buz/kafka/infrastructure/deserializers/implementations/json_bytes_to_message_deserializer.py,sha256=YwugXkmOudMNtkVfCC4BFe3pFVpbM8rAL9bT88bZMRk,756
@@ -200,7 +200,7 @@ buz/kafka/infrastructure/kafka_python/kafka_python_producer.py,sha256=DkqqLSSXHB
200
200
  buz/kafka/infrastructure/kafka_python/translators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
201
201
  buz/kafka/infrastructure/kafka_python/translators/consumer_initial_offset_position_translator.py,sha256=hJ48_eyMcnbFL_Y5TOiMbGXrQSryuKk9CvP59MdqNOY,620
202
202
  buz/kafka/infrastructure/serializers/byte_serializer.py,sha256=T83sLdX9V5Oh1mzjRwHi_1DsTFI7KefFj7kmnz7JVy4,207
203
- buz/kafka/infrastructure/serializers/implementations/cdc_record_bytes_to_event_serializer.py,sha256=Cw6kbzCMHC2PwHf6DNCIKZB2H-WCEZ-HeIDNxQbkTow,1601
203
+ buz/kafka/infrastructure/serializers/implementations/cdc_record_bytes_to_event_serializer.py,sha256=_14_HzyC7N_FdTmT8h5HsDuY1QB6ozhqnfdxdsp9xdI,1818
204
204
  buz/kafka/infrastructure/serializers/implementations/json_byte_serializer.py,sha256=KGkTQE7lq8VB048zCew_IlYgoWPozkmERYKg0t4DjOA,1510
205
205
  buz/kafka/infrastructure/serializers/kafka_header_serializer.py,sha256=ws9xr5lsJF6J-uVIplPym7vboo00KtXHfLJf8JjG0lo,649
206
206
  buz/locator/__init__.py,sha256=my8qfHL5htIT9RFFjzV4zGIPVW72tu4SMQbKKqBeSKo,293
@@ -216,7 +216,7 @@ buz/locator/sync/__init__.py,sha256=OljGqPXBPuxHzWcn-tQ0P-ObLRHbhoCmmXhsSIgVxJM,
216
216
  buz/locator/sync/handler_already_registered_exception.py,sha256=7DAnkGD97OIC9gc7604dTMBtVUl8KereUvTMicK7FD0,245
217
217
  buz/locator/sync/handler_not_registered_exception.py,sha256=cYKtKET1fHXaMvbBFJNLtvNF6-yp8pixUV62_CdTS54,234
218
218
  buz/locator/sync/instance_locator.py,sha256=HGQ6uRIwrTruhax2i8L6clfJUywgHCHC3k2rwYqjApo,2076
219
- buz/message.py,sha256=HpcFeAcYPfhyXNS8T0VokAp6XW8nHYCAHm8d0dOk0_o,2402
219
+ buz/message.py,sha256=cXJoF0w1Cy6j1Au5PCIagvn86D1VzOsK9MjJyIoE7Hk,2879
220
220
  buz/middleware/__init__.py,sha256=ndg9oGa4p8zOYC3i0nikfmSe3Ny5ug9RBwb9vZ7YhKM,176
221
221
  buz/middleware/middleware.py,sha256=XNSlfSTyBAfHzvuFrjM0IOVtz35lP_f-xWbkfdMYltA,54
222
222
  buz/middleware/middleware_chain_builder.py,sha256=D9zl5XSF5P65QpnPcbtyFaaVHqBTb6hX75aKI7CtiPU,1010
@@ -257,7 +257,7 @@ buz/serializer/message_to_json_bytes_serializer.py,sha256=RGZJ64t4t4Pz2FCASZZCv-
257
257
  buz/wrapper/__init__.py,sha256=GnRdJFcncn-qp0hzDG9dBHLmTJSbHFVjE_yr-MdW_n4,77
258
258
  buz/wrapper/async_to_sync.py,sha256=OfK-vrVUhuN-LLLvekLdMbQYtH0ue5lfbvuasj6ovMI,698
259
259
  buz/wrapper/event_loop.py,sha256=pfBJ1g-8A2a3YgW8Gf9Fg0kkewoh3-wgTy2KIFDyfHk,266
260
- buz-2.16.0.dist-info/LICENSE,sha256=jcLgcIIVaBqaZNwe0kzGWSU99YgwMcI0IGv142wkYSM,1062
261
- buz-2.16.0.dist-info/METADATA,sha256=NUJDqpVmTFd9vDNXIhjiaN1N9jKAiUOisQfBFUB6q_Y,12679
262
- buz-2.16.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
263
- buz-2.16.0.dist-info/RECORD,,
260
+ buz-2.17.0rc1.dist-info/LICENSE,sha256=jcLgcIIVaBqaZNwe0kzGWSU99YgwMcI0IGv142wkYSM,1062
261
+ buz-2.17.0rc1.dist-info/METADATA,sha256=l0G8yhZ42hHCWCVgIY5X6Yf6wb5HABbIsVsnyPquGOw,12682
262
+ buz-2.17.0rc1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
263
+ buz-2.17.0rc1.dist-info/RECORD,,
File without changes