-
Notifications
You must be signed in to change notification settings - Fork 61
Expand file tree
/
Copy pathevent.py
More file actions
145 lines (115 loc) · 4.99 KB
/
event.py
File metadata and controls
145 lines (115 loc) · 4.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# Copyright 2018-Present The CloudEvents Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import typing
from abc import abstractmethod
from types import MappingProxyType
from typing import Mapping
AnyCloudEvent = typing.TypeVar("AnyCloudEvent", bound="CloudEvent")
class CloudEvent:
"""
The CloudEvent Python wrapper contract exposing generically-available
properties and APIs.
Implementations might handle fields and have other APIs exposed but are
obliged to follow this contract.
"""
@classmethod
def create(
cls: typing.Type[AnyCloudEvent],
attributes: typing.Mapping[str, typing.Any],
data: typing.Optional[typing.Any],
) -> AnyCloudEvent:
"""
Creates a new instance of the CloudEvent using supplied `attributes`
and `data`.
This method should be preferably used over the constructor to create events
while custom framework-specific implementations may require or assume
different arguments.
:param attributes: The attributes of the CloudEvent instance.
:param data: The payload of the CloudEvent instance.
:returns: A new instance of the CloudEvent created from the passed arguments.
"""
raise NotImplementedError()
def get_attributes(self) -> Mapping[str, typing.Any]:
"""
Returns a read-only view on the attributes of the event.
:returns: Read-only view on the attributes of the event.
"""
return MappingProxyType(self._get_attributes())
@abstractmethod
def _get_attributes(self) -> typing.Dict[str, typing.Any]:
"""
Returns the attributes of the event.
The implementation MUST assume that the returned value MAY be mutated.
Having a function over a property simplifies integration for custom
framework-specific implementations.
:returns: Attributes of the event.
"""
raise NotImplementedError()
@abstractmethod
def get_data(self) -> typing.Optional[typing.Any]:
"""
Returns the data of the event.
The implementation MUST assume that the returned value MAY be mutated.
Having a function over a property simplifies integration for custom
framework-specific implementations.
:returns: Data of the event.
"""
raise NotImplementedError()
def __eq__(self, other: typing.Any) -> bool:
if isinstance(other, CloudEvent):
same_data = self.get_data() == other.get_data()
same_attributes = self._get_attributes() == other._get_attributes()
return same_data and same_attributes
return False
def __getitem__(self, key: str) -> typing.Any:
"""
Returns a value of an attribute of the event denoted by the given `key`.
The `data` of the event should be accessed by the `.data` accessor rather
than this mapping.
:param key: The name of the event attribute to retrieve the value for.
:returns: The event attribute value.
"""
return self._get_attributes()[key]
def get(
self, key: str, default: typing.Optional[typing.Any] = None
) -> typing.Optional[typing.Any]:
"""
Retrieves an event attribute value for the given `key`.
Returns the `default` value if the attribute for the given key does not exist.
The implementation MUST NOT throw an error when the key does not exist, but
rather should return `None` or the configured `default`.
:param key: The name of the event attribute to retrieve the value for.
:param default: The default value to be returned when
no attribute with the given key exists.
:returns: The event attribute value if exists, default value or None otherwise.
"""
return self._get_attributes().get(key, default)
def __iter__(self) -> typing.Iterator[typing.Any]:
"""
Returns an iterator over the event attributes.
"""
return iter(self._get_attributes())
def __len__(self) -> int:
"""
Returns the number of the event attributes.
"""
return len(self._get_attributes())
def __contains__(self, key: str) -> bool:
"""
Determines if an attribute with a given `key` is present
in the event attributes.
"""
return key in self._get_attributes()
def __repr__(self) -> str:
return str({"attributes": self._get_attributes(), "data": self.get_data()})