Skip to content

Commit 67e3525

Browse files
authored
Merge pull request cloudevents#2 from cloudevents/sdk-spec
Make SDK compliant with CloudEvents SDK spec
2 parents a0acdcf + 22b8b89 commit 67e3525

File tree

14 files changed

+101
-130
lines changed

14 files changed

+101
-130
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,4 @@ venv
123123
ChangeLog
124124
AUTHORS
125125
.pytest_cache/
126+
.idea

README.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ Package **cloudevents** provides primitives to work with CloudEvents specificati
66

77
Parsing upstream Event from HTTP Request:
88
```python
9-
from cloudevents.sdk.event import upstream
9+
from cloudevents.sdk.event import v02
1010
from cloudevents.sdk import marshaller
1111

1212
data = "<this is where your CloudEvent comes from>"
13-
m = marshaller.NewDefaultHTTPMarshaller(upstream.Event)
13+
m = marshaller.NewDefaultHTTPMarshaller(v02.Event)
1414
event = m.FromRequest(
1515
{"Content-Type": "application/cloudevents+json"},
1616
data,
@@ -25,12 +25,12 @@ from cloudevents.sdk.event import v01
2525

2626
event = (
2727
v01.Event().
28-
WithContentType("application/json").
29-
WithData('{"name":"john"}').
30-
WithEventID("my-id").
31-
WithSource("from-galaxy-far-far-away").
32-
WithEventTime("tomorrow").
33-
WithEventType("cloudevent.greet.you")
28+
SetContentType("application/json").
29+
SetData('{"name":"john"}').
30+
SetEventID("my-id").
31+
SetSource("from-galaxy-far-far-away").
32+
SetEventTime("tomorrow").
33+
SetEventType("cloudevent.greet.you")
3434
)
3535

3636
```
@@ -44,12 +44,12 @@ from cloudevents.sdk.event import v01
4444

4545
event = (
4646
v01.Event().
47-
WithContentType("application/json").
48-
WithData('{"name":"john"}').
49-
WithEventID("my-id").
50-
WithSource("from-galaxy-far-far-away").
51-
WithEventTime("tomorrow").
52-
WithEventType("cloudevent.greet.you")
47+
SetContentType("application/json").
48+
SetData('{"name":"john"}').
49+
SetEventID("my-id").
50+
SetSource("from-galaxy-far-far-away").
51+
SetEventTime("tomorrow").
52+
SetEventType("cloudevent.greet.you")
5353
)
5454
m = marshaller.NewHTTPMarshaller(
5555
[

cloudevents/sdk/converters/base.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,7 @@ class Converter(object):
2121

2222
TYPE = None
2323

24-
def __init__(
25-
self, event_class: base.BaseEvent,
26-
supported_media_types: typing.Mapping[str, bool]):
27-
self.event = event_class()
28-
self.supported_media_types = supported_media_types
29-
30-
def can_read(self, media_type: str) -> bool:
31-
return media_type in self.supported_media_types
32-
33-
def read(self, headers: dict, body: typing.IO,
24+
def read(self, event, headers: dict, body: typing.IO,
3425
data_unmarshaller: typing.Callable) -> base.BaseEvent:
3526
raise Exception("not implemented")
3627

cloudevents/sdk/converters/binary.py

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,20 @@
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 v01
20+
from cloudevents.sdk.event import v02
2121

2222

2323
class BinaryHTTPCloudEventConverter(base.Converter):
2424

2525
TYPE = "binary"
26-
27-
def __init__(self, event_class: event_base.BaseEvent,
28-
supported_media_types: typing.Mapping[str, bool]):
29-
if event_class == v01.Event:
30-
raise exceptions.UnsupportedEvent(event_class)
31-
32-
super().__init__(event_class, supported_media_types)
26+
SUPPORTED_VERSIONS = [v02.Event, ]
3327

3428
def read(self,
29+
event: event_base.BaseEvent,
3530
headers: dict, body: typing.IO,
3631
data_unmarshaller: typing.Callable) -> event_base.BaseEvent:
37-
# we ignore headers, since the whole CE is in request body
38-
event = self.event
32+
if type(event) not in self.SUPPORTED_VERSIONS:
33+
raise exceptions.UnsupportedEvent(type(event))
3934
event.UnmarshalBinary(headers, body, data_unmarshaller)
4035
return event
4136

@@ -48,11 +43,5 @@ def write(self, event: event_base.BaseEvent,
4843
return hs, data_marshaller(data)
4944

5045

51-
def NewBinaryHTTPCloudEventConverter(
52-
event_class: event_base.BaseEvent) -> BinaryHTTPCloudEventConverter:
53-
media_types = {
54-
"application/json": True,
55-
"application/xml": True,
56-
"application/octet-stream": True,
57-
}
58-
return BinaryHTTPCloudEventConverter(event_class, media_types)
46+
def NewBinaryHTTPCloudEventConverter() -> BinaryHTTPCloudEventConverter:
47+
return BinaryHTTPCloudEventConverter()

cloudevents/sdk/converters/structured.py

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,10 @@ class JSONHTTPCloudEventConverter(base.Converter):
2323

2424
TYPE = "structured"
2525

26-
def __init__(self, event_class: event_base.BaseEvent,
27-
supported_media_types: typing.Mapping[str, bool]):
28-
super().__init__(event_class, supported_media_types)
29-
30-
def read(self, headers: dict,
26+
def read(self, event: event_base.BaseEvent,
27+
headers: dict,
3128
body: typing.IO,
3229
data_unmarshaller: typing.Callable) -> event_base.BaseEvent:
33-
# we ignore headers, since the whole CE is in request body
34-
event = self.event
3530
event.UnmarshalJSON(body, data_unmarshaller)
3631
return event
3732

@@ -44,10 +39,5 @@ def write(self,
4439
return {}, event.MarshalJSON(data_marshaller)
4540

4641

47-
def NewJSONHTTPCloudEventConverter(
48-
event_class: event_base.BaseEvent) -> JSONHTTPCloudEventConverter:
49-
media_types = {
50-
"application/cloudevents+json": True,
51-
}
52-
53-
return JSONHTTPCloudEventConverter(event_class, media_types)
42+
def NewJSONHTTPCloudEventConverter() -> JSONHTTPCloudEventConverter:
43+
return JSONHTTPCloudEventConverter()

cloudevents/sdk/event/base.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,28 +50,28 @@ def ContentType(self) -> str:
5050
# CloudEvent attribute constructors
5151
# Each setter return an instance of its class
5252
# in order to build a pipeline of setter
53-
def WithEventType(self, eventType: str) -> object:
53+
def SetEventType(self, eventType: str) -> object:
5454
raise Exception("not implemented")
5555

56-
def WithSource(self, source: str) -> object:
56+
def SetSource(self, source: str) -> object:
5757
raise Exception("not implemented")
5858

59-
def WithEventID(self, eventID: str) -> object:
59+
def SetEventID(self, eventID: str) -> object:
6060
raise Exception("not implemented")
6161

62-
def WithEventTime(self, eventTime: str) -> object:
62+
def SetEventTime(self, eventTime: str) -> object:
6363
raise Exception("not implemented")
6464

65-
def WithSchemaURL(self, schemaURL: str) -> object:
65+
def SetSchemaURL(self, schemaURL: str) -> object:
6666
raise Exception("not implemented")
6767

68-
def WithData(self, data: object) -> object:
68+
def SetData(self, data: object) -> object:
6969
raise Exception("not implemented")
7070

71-
def WithExtensions(self, extensions: dict) -> object:
71+
def SetExtensions(self, extensions: dict) -> object:
7272
raise Exception("not implemented")
7373

74-
def WithContentType(self, contentType: str) -> object:
74+
def SetContentType(self, contentType: str) -> object:
7575
raise Exception("not implemented")
7676

7777

cloudevents/sdk/event/v01.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,35 +59,35 @@ def Extensions(self) -> dict:
5959
def ContentType(self) -> str:
6060
return self.ce__contentType.get()
6161

62-
def WithEventType(self, eventType: str) -> base.BaseEvent:
62+
def SetEventType(self, eventType: str) -> base.BaseEvent:
6363
self.Set("eventType", eventType)
6464
return self
6565

66-
def WithSource(self, source: str) -> base.BaseEvent:
66+
def SetSource(self, source: str) -> base.BaseEvent:
6767
self.Set("source", source)
6868
return self
6969

70-
def WithEventID(self, eventID: str) -> base.BaseEvent:
70+
def SetEventID(self, eventID: str) -> base.BaseEvent:
7171
self.Set("eventID", eventID)
7272
return self
7373

74-
def WithEventTime(self, eventTime: str) -> base.BaseEvent:
74+
def SetEventTime(self, eventTime: str) -> base.BaseEvent:
7575
self.Set("eventTime", eventTime)
7676
return self
7777

78-
def WithSchemaURL(self, schemaURL: str) -> base.BaseEvent:
78+
def SetSchemaURL(self, schemaURL: str) -> base.BaseEvent:
7979
self.Set("schemaURL", schemaURL)
8080
return self
8181

82-
def WithData(self, data: object) -> base.BaseEvent:
82+
def SetData(self, data: object) -> base.BaseEvent:
8383
self.Set("data", data)
8484
return self
8585

86-
def WithExtensions(self, extensions: dict) -> base.BaseEvent:
86+
def SetExtensions(self, extensions: dict) -> base.BaseEvent:
8787
self.Set("extension", extensions)
8888
return self
8989

90-
def WithContentType(self, contentType: str) -> base.BaseEvent:
90+
def SetContentType(self, contentType: str) -> base.BaseEvent:
9191
self.Set("contentType", contentType)
9292
return self
9393

cloudevents/sdk/event/upstream.py renamed to cloudevents/sdk/event/v02.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
class Event(base.BaseEvent):
2020

2121
def __init__(self):
22-
self.ce__specversion = opt.Option("specversion", "0.1", True)
22+
self.ce__specversion = opt.Option("specversion", "0.2", True)
2323
self.ce__type = opt.Option("type", None, True)
2424
self.ce__source = opt.Option("source", None, True)
2525
self.ce__id = opt.Option("id", None, True)
@@ -56,34 +56,34 @@ def Extensions(self) -> dict:
5656
def ContentType(self) -> str:
5757
return self.ce__contenttype.get()
5858

59-
def WithEventType(self, eventType: str) -> base.BaseEvent:
59+
def SetEventType(self, eventType: str) -> base.BaseEvent:
6060
self.Set("type", eventType)
6161
return self
6262

63-
def WithSource(self, source: str) -> base.BaseEvent:
63+
def SetSource(self, source: str) -> base.BaseEvent:
6464
self.Set("source", source)
6565
return self
6666

67-
def WithEventID(self, eventID: str) -> base.BaseEvent:
67+
def SetEventID(self, eventID: str) -> base.BaseEvent:
6868
self.Set("id", eventID)
6969
return self
7070

71-
def WithEventTime(self, eventTime: str) -> base.BaseEvent:
71+
def SetEventTime(self, eventTime: str) -> base.BaseEvent:
7272
self.Set("time", eventTime)
7373
return self
7474

75-
def WithSchemaURL(self, schemaURL: str) -> base.BaseEvent:
75+
def SetSchemaURL(self, schemaURL: str) -> base.BaseEvent:
7676
self.Set("schemaurl", schemaURL)
7777
return self
7878

79-
def WithData(self, data: object) -> base.BaseEvent:
79+
def SetData(self, data: object) -> base.BaseEvent:
8080
self.Set("data", data)
8181
return self
8282

83-
def WithExtensions(self, extensions: dict) -> base.BaseEvent:
83+
def SetExtensions(self, extensions: dict) -> base.BaseEvent:
8484
self.Set("extension", extensions)
8585
return self
8686

87-
def WithContentType(self, contentType: str) -> base.BaseEvent:
87+
def SetContentType(self, contentType: str) -> base.BaseEvent:
8888
self.Set("contenttype", contentType)
8989
return self

cloudevents/sdk/exceptions.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,6 @@
1313
# under the License.
1414

1515

16-
class InvalidMimeTypeFromRequest(Exception):
17-
18-
def __init__(self, mime_type):
19-
super().__init__(
20-
"Unable to read CloudEvent from request, "
21-
"invalid MIME type: {0}".format(mime_type))
22-
23-
2416
class UnsupportedEvent(Exception):
2517

2618
def __init__(self, event_class):

cloudevents/sdk/marshaller.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,15 @@ def __init__(self, converters: typing.List[base.Converter]):
3737
"""
3838
self.__converters = {c.TYPE: c for c in converters}
3939

40-
def FromRequest(self, headers: dict,
40+
def FromRequest(self, event: event_base.BaseEvent,
41+
headers: dict,
4142
body: typing.IO,
4243
data_unmarshaller:
4344
typing.Callable) -> event_base.BaseEvent:
4445
"""
4546
Reads a CloudEvent from an HTTP headers and request body
47+
:param event: CloudEvent placeholder
48+
:type event: cloudevents.sdk.event.base.BaseEvent
4649
:param headers: a dict-like HTTP headers
4750
:type headers: dict
4851
:param body: a stream-like HTTP request body
@@ -52,12 +55,8 @@ def FromRequest(self, headers: dict,
5255
:return: a CloudEvent
5356
:rtype: event_base.BaseEvent
5457
"""
55-
mimeType = headers.get("Content-Type")
5658
for _, cnvrtr in self.__converters.items():
57-
if cnvrtr.can_read(mimeType):
58-
return cnvrtr.read(headers, body, data_unmarshaller)
59-
60-
raise exceptions.InvalidMimeTypeFromRequest(mimeType)
59+
return cnvrtr.read(event, headers, body, data_unmarshaller)
6160

6261
def ToRequest(self, event: event_base.BaseEvent,
6362
converter_type: str,
@@ -80,19 +79,16 @@ def ToRequest(self, event: event_base.BaseEvent,
8079
raise exceptions.NoSuchConverter(converter_type)
8180

8281

83-
def NewDefaultHTTPMarshaller(
84-
event_class: event_base.BaseEvent) -> HTTPMarshaller:
82+
def NewDefaultHTTPMarshaller() -> HTTPMarshaller:
8583
"""
8684
Creates the default HTTP marshaller with both structured
8785
and binary converters
88-
:param event_class: CloudEvent spec class
89-
:type event_class: event_base.BaseEvent
9086
:return: an instance of HTTP marshaller
9187
:rtype: cloudevents.sdk.marshaller.HTTPMarshaller
9288
"""
9389
return HTTPMarshaller([
94-
structured.NewJSONHTTPCloudEventConverter(event_class),
95-
binary.NewBinaryHTTPCloudEventConverter(event_class),
90+
structured.NewJSONHTTPCloudEventConverter(),
91+
binary.NewBinaryHTTPCloudEventConverter(),
9692
])
9793

9894

cloudevents/tests/data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
ce_type = "word.found.exclamation"
1717
ce_id = "16fb5f0b-211e-1102-3dfe-ea6e2806f124"
1818
source = "pytest"
19-
specversion = "0.1"
19+
specversion = "0.2"
2020
eventTime = "2018-10-23T12:28:23.3464579Z"
2121
body = '{"name":"john"}'
2222
headers = {

0 commit comments

Comments
 (0)