Skip to content

Commit 065ef91

Browse files
committed
refactor: expose data and attributes in class
Signed-off-by: Alexander Tkachev <[email protected]>
1 parent c0b5413 commit 065ef91

File tree

3 files changed

+25
-47
lines changed

3 files changed

+25
-47
lines changed

cloudevents/abstract/event.py

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -26,55 +26,27 @@ def create(
2626
raise NotImplementedError()
2727

2828
@property
29-
def _attributes_read_model(self) -> typing.Dict[str, typing.Any]:
29+
def attributes(self) -> typing.Dict[str, typing.Any]:
3030
"""
3131
:return: Attributes of this event.
3232
3333
You MUST NOT mutate this dict.
3434
Implementation MAY assume the dict will not be mutated.
35-
36-
The reason this is only a read model and not a write model is
37-
because you MAY not have an easy write access to the data.
38-
39-
For example - a database row or a cached value.
40-
41-
We don't wont to restrict our future selves.
42-
43-
When a write model will be needed, it will be implemented
44-
45-
The we don't have an `attributes` property is to prevent API confusion
46-
Examples of confusion:
47-
* What is the difference between `event.get("myattr")` and
48-
`event.attributes.get("myattr")`
49-
* What SHOULD I use `event["myattr"]` or `event.attributes["myattr"]` ?
5035
"""
5136
raise NotImplementedError()
5237

5338
@property
54-
def _data_read_model(self) -> typing.Optional[typing.Any]:
39+
def data(self) -> typing.Optional[typing.Any]:
5540
"""
5641
:return: Data value of the event.
5742
You MUST NOT mutate this dict.
5843
Implementation MAY assume the dict will not be mutated.
59-
60-
The reason this is only a read model and not a write model is
61-
because you MAY not have an easy write access to the data.
62-
63-
For example - a database row or a cached value.
64-
65-
We don't wont to restrict our future selves.
66-
67-
When a write model will be needed, it will be implemented
68-
6944
"""
7045
raise NotImplementedError()
7146

7247
def __eq__(self, other: typing.Any) -> bool:
7348
if isinstance(other, CloudEvent):
74-
return (
75-
self._data_read_model == other._data_read_model
76-
and self._attributes_read_model == other._attributes_read_model
77-
)
49+
return self.data == other.data and self.attributes == other.attributes
7850
return False
7951

8052
def __getitem__(self, key: str) -> typing.Any:
@@ -84,7 +56,7 @@ def __getitem__(self, key: str) -> typing.Any:
8456
:param key: The event attribute name.
8557
:return: The event attribute value.
8658
"""
87-
return self._attributes_read_model[key]
59+
return self.attributes[key]
8860

8961
def get(
9062
self, key: str, default: typing.Optional[typing.Any] = None
@@ -100,21 +72,19 @@ def get(
10072
no attribute with the given key exists.
10173
:returns: The event attribute value if exists, default value otherwise.
10274
"""
103-
return self._attributes_read_model.get(key, default)
75+
return self.attributes.get(key, default)
10476

10577
def __iter__(self) -> typing.Iterator[typing.Any]:
106-
return iter(self._attributes_read_model)
78+
return iter(self.attributes)
10779

10880
def __len__(self) -> int:
109-
return len(self._attributes_read_model)
81+
return len(self.attributes)
11082

11183
def __contains__(self, key: str) -> bool:
112-
return key in self._attributes_read_model
84+
return key in self.attributes
11385

11486
def __repr__(self) -> str:
115-
return str(
116-
{"attributes": self._attributes_read_model, "data": self._data_read_model}
117-
)
87+
return str({"attributes": self.attributes, "data": self.data})
11888

11989

12090
AnyCloudEvent = TypeVar("AnyCloudEvent", bound=CloudEvent)

cloudevents/http/event.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def __init__(self, attributes: typing.Dict[str, str], data: typing.Any = None):
5252
:type data: typing.Any
5353
"""
5454
self._attributes = {k.lower(): v for k, v in attributes.items()}
55-
self.data = data
55+
self._data = data
5656
if "specversion" not in self._attributes:
5757
self._attributes["specversion"] = "1.0"
5858
if "id" not in self._attributes:
@@ -75,12 +75,20 @@ def __init__(self, attributes: typing.Dict[str, str], data: typing.Any = None):
7575
)
7676

7777
@property
78-
def _attributes_read_model(self) -> typing.Dict[str, typing.Any]:
78+
def attributes(self) -> typing.Dict[str, typing.Any]:
7979
return self._attributes
8080

8181
@property
82-
def _data_read_model(self) -> typing.Optional[typing.Any]:
83-
return self.data
82+
def data(self) -> typing.Optional[typing.Any]:
83+
return self._data
84+
85+
@data.setter
86+
def data(self, value) -> None:
87+
"""
88+
Exists for backwards compatibility
89+
:param value: new data vale
90+
"""
91+
self._data = value
8492

8593
def __setitem__(self, key: str, value: typing.Any) -> None:
8694
self._attributes[key] = value

cloudevents/tests/test_abstract_cloudevent.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,17 @@ def test_create_is_abstract():
2727
assert CloudEvent.create({}, None) is None
2828

2929

30-
def test_data_read_is_abstract():
30+
def test_data_is_abstract():
3131
"""
3232
exists mainly for coverage reasons
3333
"""
3434
with pytest.raises(NotImplementedError):
35-
CloudEvent()._data_read_model
35+
CloudEvent().data
3636

3737

38-
def test_attributes_read_model_is_abstract():
38+
def test_attributes_is_abstract():
3939
"""
4040
exists mainly for coverage reasons
4141
"""
4242
with pytest.raises(NotImplementedError):
43-
CloudEvent()._attributes_read_model
43+
CloudEvent().attributes

0 commit comments

Comments
 (0)