Skip to content

Commit 9357beb

Browse files
committed
Adding back can_read to converters
Signed-off-by: Denis Makogon <[email protected]>
1 parent 043236b commit 9357beb

File tree

9 files changed

+133
-3
lines changed

9 files changed

+133
-3
lines changed

README.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,63 @@ In this topic you'd find various example how to integrate an SDK with various HT
7676

7777
### Python requests
7878

79+
One of popular framework is [0.2-force-improvements](http://docs.python-requests.org/en/master/).
7980

8081

82+
#### CloudEvent to request
83+
84+
The code below shows how integrate both libraries in order to convert a CloudEvent into an HTTP request:
85+
86+
```python
87+
def run_binary(event, url):
88+
binary_headers, binary_data = http_marshaller.ToRequest(
89+
event, converters.TypeBinary, json.dumps)
90+
91+
print("binary CloudEvent")
92+
for k, v in binary_headers.items():
93+
print("{0}: {1}\r\n".format(k, v))
94+
print(binary_data.getvalue())
95+
response = requests.post(url,
96+
headers=binary_headers,
97+
data=binary_data.getvalue())
98+
response.raise_for_status()
99+
100+
101+
def run_structured(event, url):
102+
structured_headers, structured_data = http_marshaller.ToRequest(
103+
event, converters.TypeStructured, json.dumps
104+
)
105+
print("structured CloudEvent")
106+
print(structured_data.getvalue())
107+
108+
response = requests.post(url,
109+
headers=structured_headers,
110+
data=structured_data.getvalue())
111+
response.raise_for_status()
112+
113+
```
114+
115+
Complete example of turning a CloudEvent into a request you can find [here](samples/python-requests/cloudevent_to_request.py).
116+
117+
#### Request to CloudEvent
118+
119+
The code below shows how integrate both libraries in order to create a CloudEvent from an HTTP request:
120+
```python
121+
response = requests.get(url)
122+
response.raise_for_status()
123+
headers = response.headers
124+
data = io.BytesIO(response.content)
125+
event = v02.Event()
126+
http_marshaller = marshaller.NewDefaultHTTPMarshaller()
127+
event = http_marshaller.FromRequest(
128+
event, headers, data, json.load)
129+
130+
```
131+
Complete example of turning a CloudEvent into a request you can find [here](samples/python-requests/request_to_cloudevent.py).
132+
133+
134+
## SDK versioning
135+
81136
The goal of this package is to provide support for all released versions of CloudEvents, ideally while maintaining
82137
the same API. It will use semantic versioning with following rules:
83138
* MAJOR version increments when backwards incompatible changes is introduced.

cloudevents/sdk/converters/base.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ def read(self, event, headers: dict, body: typing.IO,
2525
data_unmarshaller: typing.Callable) -> base.BaseEvent:
2626
raise Exception("not implemented")
2727

28+
def can_read(self, content_type):
29+
raise Exception("not implemented")
30+
2831
def write(self, event: base.BaseEvent,
2932
data_marshaller: typing.Callable) -> (dict, typing.IO):
3033
raise Exception("not implemented")

cloudevents/sdk/converters/binary.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ class BinaryHTTPCloudEventConverter(base.Converter):
2525
TYPE = "binary"
2626
SUPPORTED_VERSIONS = [v02.Event, ]
2727

28+
def can_read(self, content_type):
29+
return True
30+
2831
def read(self,
2932
event: event_base.BaseEvent,
3033
headers: dict, body: typing.IO,

cloudevents/sdk/converters/structured.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ class JSONHTTPCloudEventConverter(base.Converter):
2323

2424
TYPE = "structured"
2525

26+
def can_read(self, content_type):
27+
return content_type == "application/cloudevents+json"
28+
2629
def read(self, event: event_base.BaseEvent,
2730
headers: dict,
2831
body: typing.IO,

cloudevents/sdk/exceptions.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,10 @@ class NoSuchConverter(Exception):
3131
def __init__(self, converter_type):
3232
super().__init__(
3333
"No such converter {0}".format(converter_type))
34+
35+
36+
class UnsupportedEventConverter(Exception):
37+
def __init__(self, content_type):
38+
super().__init__(
39+
"Unable to identify valid event converter "
40+
"for content-type: '{0}'".format(content_type))

cloudevents/sdk/marshaller.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,14 @@ def FromRequest(self, event: event_base.BaseEvent,
5555
:return: a CloudEvent
5656
:rtype: event_base.BaseEvent
5757
"""
58+
content_type = headers.get(
59+
"content-type", headers.get("Content-Type"))
60+
5861
for _, cnvrtr in self.__converters.items():
59-
return cnvrtr.read(event, headers, body, data_unmarshaller)
62+
if cnvrtr.can_read(content_type):
63+
return cnvrtr.read(event, headers, body, data_unmarshaller)
64+
65+
raise exceptions.UnsupportedEventConverter(content_type)
6066

6167
def ToRequest(self, event: event_base.BaseEvent,
6268
converter_type: str,

cloudevents/tests/test_event_from_request_converter.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ def test_structured_converter_upstream():
5858
assert event.Get("id") == (data.ce_id, True)
5959

6060

61-
# todo: clarify whether spec 0.1 doesn't support binary format
6261
def test_binary_converter_v01():
6362
m = marshaller.NewHTTPMarshaller(
6463
[
@@ -69,7 +68,20 @@ def test_binary_converter_v01():
6968
pytest.raises(
7069
exceptions.UnsupportedEvent,
7170
m.FromRequest,
72-
v01.Event, None, None, None)
71+
v01.Event, {}, None, None)
72+
73+
74+
def test_unsupported_converter_v01():
75+
m = marshaller.NewHTTPMarshaller(
76+
[
77+
structured.NewJSONHTTPCloudEventConverter()
78+
]
79+
)
80+
81+
pytest.raises(
82+
exceptions.UnsupportedEventConverter,
83+
m.FromRequest,
84+
v01.Event, {}, None, None)
7385

7486

7587
def test_structured_converter_v01():

samples/with_requests.py renamed to samples/python-requests/cloudevent_to_request.py

File renamed without changes.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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+
import json
16+
import io
17+
import requests
18+
import sys
19+
20+
from cloudevents.sdk import marshaller
21+
22+
from cloudevents.sdk.event import v02
23+
24+
25+
if __name__ == "__main__":
26+
27+
if len(sys.argv) < 2:
28+
sys.exit("Usage: python with_requests.py "
29+
"<CloudEvent source URL>")
30+
31+
url = sys.argv[1]
32+
response = requests.get(url)
33+
response.raise_for_status()
34+
headers = response.headers
35+
data = io.BytesIO(response.content)
36+
event = v02.Event()
37+
http_marshaller = marshaller.NewDefaultHTTPMarshaller()
38+
event = http_marshaller.FromRequest(
39+
event, headers, data, json.load)
40+
41+
print(json.dumps(event.Properties()))

0 commit comments

Comments
 (0)