@@ -20,19 +20,21 @@ def from_http(
2020 Unwrap a CloudEvent (binary or structured) from an HTTP request.
2121 :param headers: the HTTP headers
2222 :type headers: typing.Dict[str, str]
23- :param data: the HTTP request body
23+ :param data: the HTTP request body. If set to None, "" or b'', the returned
24+ event's data field will be set to None
2425 :type data: typing.IO
2526 :param data_unmarshaller: Callable function to map data to a python object
2627 e.g. lambda x: x or lambda x: json.loads(x)
2728 :type data_unmarshaller: types.UnmarshallerType
2829 """
29- if data is None :
30+ if data is None or data == b"" :
31+ # Empty string will cause data to be marshalled into None
3032 data = ""
3133
3234 if not isinstance (data , (str , bytes , bytearray )):
3335 raise cloud_exceptions .InvalidStructuredJSON (
3436 "Expected json of type (str, bytes, bytearray), "
35- f"but instead found { type (data )} . "
37+ f"but instead found type { type (data )} "
3638 )
3739
3840 headers = {key .lower (): value for key , value in headers .items ()}
@@ -47,22 +49,28 @@ def from_http(
4749 try :
4850 raw_ce = json .loads (data )
4951 except json .decoder .JSONDecodeError :
50- raise cloud_exceptions .InvalidStructuredJSON (
51- "Failed to read fields from structured event. "
52- f"The following can not be parsed as json: { data } . "
52+ raise cloud_exceptions .MissingRequiredFields (
53+ "Failed to read specversion from both headers and data. "
54+ f"The following can not be parsed as json: { data } "
55+ )
56+ if hasattr (raw_ce , "get" ):
57+ specversion = raw_ce .get ("specversion" , None )
58+ else :
59+ raise cloud_exceptions .MissingRequiredFields (
60+ "Failed to read specversion from both headers and data. "
61+ f"The following deserialized data has no 'get' method: { raw_ce } "
5362 )
54- specversion = raw_ce .get ("specversion" , None )
5563
5664 if specversion is None :
5765 raise cloud_exceptions .MissingRequiredFields (
58- "Failed to find specversion in HTTP request. "
66+ "Failed to find specversion in HTTP request"
5967 )
6068
6169 event_handler = _obj_by_version .get (specversion , None )
6270
6371 if event_handler is None :
6472 raise cloud_exceptions .InvalidRequiredFields (
65- f"Found invalid specversion { specversion } . "
73+ f"Found invalid specversion { specversion } "
6674 )
6775
6876 event = marshall .FromRequest (
@@ -73,7 +81,13 @@ def from_http(
7381 attrs .pop ("extensions" , None )
7482 attrs .update (** event .extensions )
7583
76- return CloudEvent (attrs , event .data )
84+ if event .data == "" or event .data == b"" :
85+ # TODO: Check binary unmarshallers to debug why setting data to ""
86+ # returns an event with data set to None, but structured will return ""
87+ data = None
88+ else :
89+ data = event .data
90+ return CloudEvent (attrs , data )
7791
7892
7993def _to_http (
@@ -96,7 +110,7 @@ def _to_http(
96110
97111 if event ._attributes ["specversion" ] not in _obj_by_version :
98112 raise cloud_exceptions .InvalidRequiredFields (
99- f"Unsupported specversion: { event ._attributes ['specversion' ]} . "
113+ f"Unsupported specversion: { event ._attributes ['specversion' ]} "
100114 )
101115
102116 event_handler = _obj_by_version [event ._attributes ["specversion" ]]()
0 commit comments