Skip to content

Commit 0aa01ba

Browse files
authored
Implemented to_json and from_json (cloudevents#72)
* added test_to_json test Signed-off-by: Curtis Mason <cumason@google.com> * implemented to_json with tests Signed-off-by: Curtis Mason <cumason@google.com> * from_json and to_json tests Signed-off-by: Curtis Mason <cumason@google.com> * Tests for to_json being able to talk to from_json Signed-off-by: Curtis Mason <cumason@google.com> * lint fix Signed-off-by: Curtis Mason <cumason@google.com> * added documentation for to_json and from_json Signed-off-by: Curtis Mason <cumason@google.com> * lint fix Signed-off-by: Curtis Mason <cumason@google.com> * lint fix Signed-off-by: Curtis Mason <cumason@google.com>
1 parent b2a87a8 commit 0aa01ba

File tree

3 files changed

+159
-11
lines changed

3 files changed

+159
-11
lines changed

cloudevents/sdk/http/__init__.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ def from_http(
4343
headers: typing.Dict[str, str],
4444
data_unmarshaller: types.UnmarshallerType = None,
4545
):
46-
"""Unwrap a CloudEvent (binary or structured) from an HTTP request.
46+
"""
47+
Unwrap a CloudEvent (binary or structured) from an HTTP request.
4748
:param data: the HTTP request body
4849
:type data: typing.IO
4950
:param headers: the HTTP headers
@@ -82,5 +83,32 @@ def from_http(
8283
return CloudEvent(attrs, event.data)
8384

8485

85-
def from_json():
86-
raise NotImplementedError
86+
def to_json(
87+
event: EventClass, data_marshaller: types.MarshallerType = None
88+
) -> typing.Union[str, bytes]:
89+
"""
90+
Cast an EventClass into a json object
91+
:param event: EventClass which will be converted into a json object
92+
:type event: EventClass
93+
:param data_marshaller: Callable function which will cast event.data
94+
into a json object
95+
:type data_marshaller: typing.Callable
96+
:returns: json object representing the given event
97+
"""
98+
return to_structured_http(event, data_marshaller=data_marshaller)[1]
99+
100+
101+
def from_json(
102+
data: typing.Union[str, bytes],
103+
data_unmarshaller: types.UnmarshallerType = None,
104+
) -> EventClass:
105+
"""
106+
Cast json encoded data into an EventClass
107+
:param data: json encoded cloudevent data
108+
:type event: typing.Union[str, bytes]
109+
:param data_unmarshaller: Callable function which will cast json encoded
110+
data into a python object retrievable from returned EventClass.data
111+
:type data_marshaller: typing.Callable
112+
:returns: EventClass representing given cloudevent json object
113+
"""
114+
return from_http(data=data, headers={}, data_unmarshaller=data_unmarshaller)

cloudevents/sdk/http/event.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,3 @@ def to_binary_http(
176176
format=converters.TypeBinary,
177177
data_marshaller=data_marshaller,
178178
)
179-
180-
181-
def to_json():
182-
raise NotImplementedError
183-
184-
185-
def from_json():
186-
raise NotImplementedError
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
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+
import base64
15+
import json
16+
17+
import pytest
18+
19+
from cloudevents.sdk.http import CloudEvent, from_json, to_json
20+
21+
test_data = json.dumps({"data-key": "val"})
22+
test_attributes = {
23+
"type": "com.example.string",
24+
"source": "https://example.com/event-producer",
25+
}
26+
27+
28+
@pytest.mark.parametrize("specversion", ["0.3", "1.0"])
29+
def test_to_json(specversion):
30+
event = CloudEvent(test_attributes, test_data)
31+
event_json = to_json(event)
32+
event_dict = json.loads(event_json)
33+
34+
for key, val in test_attributes.items():
35+
assert event_dict[key] == val
36+
37+
assert event_dict["data"] == test_data
38+
39+
40+
@pytest.mark.parametrize("specversion", ["0.3", "1.0"])
41+
def test_to_json_base64(specversion):
42+
data = b"test123"
43+
44+
event = CloudEvent(test_attributes, data)
45+
event_json = to_json(event)
46+
event_dict = json.loads(event_json)
47+
48+
for key, val in test_attributes.items():
49+
assert event_dict[key] == val
50+
51+
# test data was properly marshalled into data_base64
52+
data_base64 = event_dict["data_base64"].encode()
53+
test_data_base64 = base64.b64encode(data)
54+
55+
assert data_base64 == test_data_base64
56+
57+
58+
@pytest.mark.parametrize("specversion", ["0.3", "1.0"])
59+
def test_from_json(specversion):
60+
payload = {
61+
"type": "com.example.string",
62+
"source": "https://example.com/event-producer",
63+
"id": "1234",
64+
"specversion": specversion,
65+
"data": {"data-key": "val"},
66+
}
67+
event = from_json(json.dumps(payload))
68+
69+
for key, val in payload.items():
70+
if key == "data":
71+
assert event.data == payload["data"]
72+
else:
73+
assert event[key] == val
74+
75+
76+
@pytest.mark.parametrize("specversion", ["0.3", "1.0"])
77+
def test_from_json_base64(specversion):
78+
# Create base64 encoded data
79+
raw_data = {"data-key": "val"}
80+
data = json.dumps(raw_data).encode()
81+
data_base64_str = base64.b64encode(data).decode()
82+
83+
# Create json payload
84+
payload = {
85+
"type": "com.example.string",
86+
"source": "https://example.com/event-producer",
87+
"id": "1234",
88+
"specversion": specversion,
89+
"data_base64": data_base64_str,
90+
}
91+
payload_json = json.dumps(payload)
92+
93+
# Create event
94+
event = from_json(payload_json)
95+
96+
# Test fields were marshalled properly
97+
for key, val in payload.items():
98+
if key == "data_base64":
99+
# Check data_base64 was unmarshalled properly
100+
assert event.data == raw_data
101+
else:
102+
assert event[key] == val
103+
104+
105+
@pytest.mark.parametrize("specversion", ["0.3", "1.0"])
106+
def test_json_can_talk_to_itself(specversion):
107+
event = CloudEvent(test_attributes, test_data)
108+
event_json = to_json(event)
109+
110+
event = from_json(event_json)
111+
112+
for key, val in test_attributes.items():
113+
assert event[key] == val
114+
assert event.data == test_data
115+
116+
117+
@pytest.mark.parametrize("specversion", ["0.3", "1.0"])
118+
def test_json_can_talk_to_itself_base64(specversion):
119+
data = b"test123"
120+
121+
event = CloudEvent(test_attributes, data)
122+
event_json = to_json(event)
123+
124+
event = from_json(event_json)
125+
126+
for key, val in test_attributes.items():
127+
assert event[key] == val
128+
assert event.data == data

0 commit comments

Comments
 (0)