Skip to content

Commit bcacf33

Browse files
slinkydeveloperdi
andauthored
Added Cloudevents V0.3 and V1 implementations (cloudevents#22)
* Added v1 and v03 specs Signed-off-by: Francesco Guardiani <francescoguard@gmail.com> * Added v1 and v03 specs implementations Signed-off-by: Francesco Guardiani <francescoguard@gmail.com> * linter Signed-off-by: Francesco Guardiani <francescoguard@gmail.com> * linter 2 Signed-off-by: Francesco Guardiani <francescoguard@gmail.com> * Add changelog entry Signed-off-by: Dustin Ingram <di@users.noreply.github.com> Co-authored-by: Dustin Ingram <di@users.noreply.github.com>
1 parent b7ad8c2 commit bcacf33

File tree

11 files changed

+328
-69
lines changed

11 files changed

+328
-69
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88
### Added
9+
- Added Cloudevents V0.3 and V1 implementations ([#22])
910
- Add helpful text to README ([#23])
1011
- Add link to email in README ([#27])
1112

@@ -61,6 +62,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6162
[#15]: https://github.com/cloudevents/sdk-python/pull/15
6263
[#17]: https://github.com/cloudevents/sdk-python/pull/17
6364
[#21]: https://github.com/cloudevents/sdk-python/pull/21
65+
[#22]: https://github.com/cloudevents/sdk-python/pull/22
6466
[#23]: https://github.com/cloudevents/sdk-python/pull/23
6567
[#25]: https://github.com/cloudevents/sdk-python/pull/25
6668
[#27]: https://github.com/cloudevents/sdk-python/pull/27

cloudevents/sdk/converters/binary.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@
1717
from cloudevents.sdk import exceptions
1818
from cloudevents.sdk.converters import base
1919
from cloudevents.sdk.event import base as event_base
20-
from cloudevents.sdk.event import v02
20+
from cloudevents.sdk.event import v02, v03, v1
2121

2222

2323
class BinaryHTTPCloudEventConverter(base.Converter):
2424

2525
TYPE = "binary"
26-
SUPPORTED_VERSIONS = [v02.Event]
26+
SUPPORTED_VERSIONS = [v02.Event, v03.Event, v1.Event]
2727

2828
def can_read(self, content_type: str) -> bool:
2929
return True

cloudevents/sdk/event/base.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
import typing
1818

1919

20+
# TODO(slinkydeveloper) is this really needed?
2021
class EventGetterSetter(object):
22+
2123
def CloudEventVersion(self) -> str:
2224
raise Exception("not implemented")
2325

@@ -126,16 +128,10 @@ def UnmarshalBinary(
126128
body: typing.IO,
127129
data_unmarshaller: typing.Callable
128130
):
129-
binary_mapping = {
130-
"content-type": "contenttype",
131-
# TODO(someone): add Distributed Tracing. It's not clear
132-
# if this is one extension or two.
133-
# https://github.com/cloudevents/spec/blob/master/extensions/distributed-tracing.md
134-
}
135131
for header, value in headers.items():
136132
header = header.lower()
137-
if header in binary_mapping:
138-
self.Set(binary_mapping[header], value)
133+
if header == "content-type":
134+
self.SetContentType(value)
139135
elif header.startswith("ce-"):
140136
self.Set(header[3:], value)
141137

cloudevents/sdk/event/v03.py

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
15+
from cloudevents.sdk.event import base
16+
from cloudevents.sdk.event import opt
17+
18+
19+
class Event(base.BaseEvent):
20+
def __init__(self):
21+
self.ce__specversion = opt.Option("specversion", "0.3", True)
22+
self.ce__id = opt.Option("id", None, True)
23+
self.ce__source = opt.Option("source", None, True)
24+
self.ce__type = opt.Option("type", None, True)
25+
26+
self.ce__datacontenttype = opt.Option("datacontenttype", None, False)
27+
self.ce__datacontentencoding = opt.Option(
28+
"datacontentencoding",
29+
None,
30+
False
31+
)
32+
self.ce__subject = opt.Option("subject", None, False)
33+
self.ce__time = opt.Option("time", None, False)
34+
self.ce__schemaurl = opt.Option("schemaurl", None, False)
35+
self.ce__data = opt.Option("data", None, False)
36+
self.ce__extensions = opt.Option("extensions", dict(), False)
37+
38+
def CloudEventVersion(self) -> str:
39+
return self.ce__specversion.get()
40+
41+
def EventType(self) -> str:
42+
return self.ce__type.get()
43+
44+
def Source(self) -> str:
45+
return self.ce__source.get()
46+
47+
def EventID(self) -> str:
48+
return self.ce__id.get()
49+
50+
def EventTime(self) -> str:
51+
return self.ce__time.get()
52+
53+
def Subject(self) -> str:
54+
return self.ce__subject.get()
55+
56+
def SchemaURL(self) -> str:
57+
return self.ce__schemaurl.get()
58+
59+
def Data(self) -> object:
60+
return self.ce__data.get()
61+
62+
def Extensions(self) -> dict:
63+
return self.ce__extensions.get()
64+
65+
def ContentType(self) -> str:
66+
return self.ce__datacontenttype.get()
67+
68+
def ContentEncoding(self) -> str:
69+
return self.ce__datacontentencoding.get()
70+
71+
def SetEventType(self, eventType: str) -> base.BaseEvent:
72+
self.Set("type", eventType)
73+
return self
74+
75+
def SetSource(self, source: str) -> base.BaseEvent:
76+
self.Set("source", source)
77+
return self
78+
79+
def SetEventID(self, eventID: str) -> base.BaseEvent:
80+
self.Set("id", eventID)
81+
return self
82+
83+
def SetEventTime(self, eventTime: str) -> base.BaseEvent:
84+
self.Set("time", eventTime)
85+
return self
86+
87+
def SetSubject(self, subject: str) -> base.BaseEvent:
88+
self.Set("subject", subject)
89+
return self
90+
91+
def SetSchemaURL(self, schemaURL: str) -> base.BaseEvent:
92+
self.Set("schemaurl", schemaURL)
93+
return self
94+
95+
def SetData(self, data: object) -> base.BaseEvent:
96+
self.Set("data", data)
97+
return self
98+
99+
def SetExtensions(self, extensions: dict) -> base.BaseEvent:
100+
self.Set("extensions", extensions)
101+
return self
102+
103+
def SetContentType(self, contentType: str) -> base.BaseEvent:
104+
self.Set("datacontenttype", contentType)
105+
return self
106+
107+
def SetContentEncoding(self, contentEncoding: str) -> base.BaseEvent:
108+
self.Set("datacontentencoding", contentEncoding)
109+
return self

cloudevents/sdk/event/v1.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
15+
from cloudevents.sdk.event import base
16+
from cloudevents.sdk.event import opt
17+
18+
19+
class Event(base.BaseEvent):
20+
def __init__(self):
21+
self.ce__specversion = opt.Option("specversion", "1.0", True)
22+
self.ce__id = opt.Option("id", None, True)
23+
self.ce__source = opt.Option("source", None, True)
24+
self.ce__type = opt.Option("type", None, True)
25+
26+
self.ce__datacontenttype = opt.Option("datacontenttype", None, False)
27+
self.ce__dataschema = opt.Option("dataschema", None, False)
28+
self.ce__subject = opt.Option("subject", None, False)
29+
self.ce__time = opt.Option("time", None, False)
30+
self.ce__data = opt.Option("data", None, False)
31+
self.ce__extensions = opt.Option("extensions", dict(), False)
32+
33+
def CloudEventVersion(self) -> str:
34+
return self.ce__specversion.get()
35+
36+
def EventType(self) -> str:
37+
return self.ce__type.get()
38+
39+
def Source(self) -> str:
40+
return self.ce__source.get()
41+
42+
def EventID(self) -> str:
43+
return self.ce__id.get()
44+
45+
def EventTime(self) -> str:
46+
return self.ce__time.get()
47+
48+
def Subject(self) -> str:
49+
return self.ce__subject.get()
50+
51+
def Schema(self) -> str:
52+
return self.ce__dataschema.get()
53+
54+
def ContentType(self) -> str:
55+
return self.ce__datacontenttype.get()
56+
57+
def Data(self) -> object:
58+
return self.ce__data.get()
59+
60+
def Extensions(self) -> dict:
61+
return self.ce__extensions.get()
62+
63+
def SetEventType(self, eventType: str) -> base.BaseEvent:
64+
self.Set("type", eventType)
65+
return self
66+
67+
def SetSource(self, source: str) -> base.BaseEvent:
68+
self.Set("source", source)
69+
return self
70+
71+
def SetEventID(self, eventID: str) -> base.BaseEvent:
72+
self.Set("id", eventID)
73+
return self
74+
75+
def SetEventTime(self, eventTime: str) -> base.BaseEvent:
76+
self.Set("time", eventTime)
77+
return self
78+
79+
def SetSubject(self, subject: str) -> base.BaseEvent:
80+
self.Set("subject", subject)
81+
return self
82+
83+
def SetSchema(self, schema: str) -> base.BaseEvent:
84+
self.Set("dataschema", schema)
85+
return self
86+
87+
def SetContentType(self, contentType: str) -> base.BaseEvent:
88+
self.Set("datacontenttype", contentType)
89+
return self
90+
91+
def SetData(self, data: object) -> base.BaseEvent:
92+
self.Set("data", data)
93+
return self
94+
95+
def SetExtensions(self, extensions: dict) -> base.BaseEvent:
96+
self.Set("extensions", extensions)
97+
return self

cloudevents/sdk/marshaller.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ def FromRequest(
6161
if not isinstance(data_unmarshaller, typing.Callable):
6262
raise exceptions.InvalidDataUnmarshaller()
6363

64-
content_type = headers.get("content-type", headers.get("Content-Type"))
64+
# Lower all header keys
65+
headers = {key.lower(): value for key, value in headers.items()}
66+
content_type = headers.get("content-type", None)
6567

6668
for cnvrtr in self.__converters:
6769
if cnvrtr.can_read(content_type) and cnvrtr.event_supported(event):

cloudevents/tests/data.py

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,65 @@
1212
# License for the specific language governing permissions and limitations
1313
# under the License.
1414

15+
from cloudevents.sdk.event import v02, v03, v1
16+
1517
contentType = "application/json"
1618
ce_type = "word.found.exclamation"
1719
ce_id = "16fb5f0b-211e-1102-3dfe-ea6e2806f124"
1820
source = "pytest"
19-
specversion = "0.2"
2021
eventTime = "2018-10-23T12:28:23.3464579Z"
2122
body = '{"name":"john"}'
23+
2224
headers = {
23-
"ce-specversion": specversion,
24-
"ce-type": ce_type,
25-
"ce-id": ce_id,
26-
"ce-time": eventTime,
27-
"ce-source": source,
28-
"Content-Type": contentType,
25+
v02.Event: {
26+
"ce-specversion": "0.2",
27+
"ce-type": ce_type,
28+
"ce-id": ce_id,
29+
"ce-time": eventTime,
30+
"ce-source": source,
31+
"Content-Type": contentType,
32+
},
33+
v03.Event: {
34+
"ce-specversion": "0.3",
35+
"ce-type": ce_type,
36+
"ce-id": ce_id,
37+
"ce-time": eventTime,
38+
"ce-source": source,
39+
"Content-Type": contentType,
40+
},
41+
v1.Event: {
42+
"ce-specversion": "1.0",
43+
"ce-type": ce_type,
44+
"ce-id": ce_id,
45+
"ce-time": eventTime,
46+
"ce-source": source,
47+
"Content-Type": contentType,
48+
},
2949
}
30-
ce = {
31-
"specversion": specversion,
32-
"type": ce_type,
33-
"id": ce_id,
34-
"time": eventTime,
35-
"source": source,
36-
"contenttype": contentType,
50+
51+
json_ce = {
52+
v02.Event: {
53+
"specversion": "0.2",
54+
"type": ce_type,
55+
"id": ce_id,
56+
"time": eventTime,
57+
"source": source,
58+
"contenttype": contentType,
59+
},
60+
v03.Event: {
61+
"specversion": "0.3",
62+
"type": ce_type,
63+
"id": ce_id,
64+
"time": eventTime,
65+
"source": source,
66+
"datacontenttype": contentType,
67+
},
68+
v1.Event: {
69+
"specversion": "1.0",
70+
"type": ce_type,
71+
"id": ce_id,
72+
"time": eventTime,
73+
"source": source,
74+
"datacontenttype": contentType,
75+
},
3776
}

0 commit comments

Comments
 (0)