From c4d9ce55552cf48dcc0020ab6bb8b93a0c139ef3 Mon Sep 17 00:00:00 2001 From: Curtis Mason Date: Thu, 30 Jul 2020 14:29:10 -0700 Subject: [PATCH 1/3] Modularized http and made http a top level module Modularized the http directory by separating related functions into different scripts. Also removed EventClass and kept a singular CloudEvent. Finally, CloudEvent.__repr__ was refactored such that it doesn't depend on external methods. Signed-off-by: Curtis Mason --- README.md | 6 +- cloudevents/http/__init__.py | 30 +++++ cloudevents/{sdk => }/http/event.py | 100 +-------------- cloudevents/http/json_methods.py | 34 +++++ cloudevents/http/mappings.py | 15 +++ cloudevents/http/requests.py | 120 ++++++++++++++++++ cloudevents/http/util.py | 20 +++ cloudevents/sdk/http/__init__.py | 114 ----------------- cloudevents/tests/test_event_extensions.py | 2 +- cloudevents/tests/test_http_events.py | 2 +- cloudevents/tests/test_http_json_methods.py | 2 +- samples/http-image-cloudevents/client.py | 2 +- samples/http-image-cloudevents/server.py | 2 +- .../test_image_sample.py | 2 +- samples/http-json-cloudevents/client.py | 2 +- samples/http-json-cloudevents/server.py | 2 +- 16 files changed, 234 insertions(+), 221 deletions(-) create mode 100644 cloudevents/http/__init__.py rename cloudevents/{sdk => }/http/event.py (50%) create mode 100644 cloudevents/http/json_methods.py create mode 100644 cloudevents/http/mappings.py create mode 100644 cloudevents/http/requests.py create mode 100644 cloudevents/http/util.py delete mode 100644 cloudevents/sdk/http/__init__.py diff --git a/README.md b/README.md index 80158165..bee33e3c 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Below we will provide samples on how to send cloudevents using the popular ### Binary HTTP CloudEvent ```python -from cloudevents.sdk.http import CloudEvent, to_binary_http +from cloudevents.http import CloudEvent, to_binary_http import requests @@ -43,7 +43,7 @@ requests.post("", data=body, headers=headers) ### Structured HTTP CloudEvent ```python -from cloudevents.sdk.http import CloudEvent, to_structured_http +from cloudevents.http import CloudEvent, to_structured_http import requests @@ -70,7 +70,7 @@ The code below shows how to consume a cloudevent using the popular python web fr ```python from flask import Flask, request -from cloudevents.sdk.http import from_http +from cloudevents.http import from_http app = Flask(__name__) diff --git a/cloudevents/http/__init__.py b/cloudevents/http/__init__.py new file mode 100644 index 00000000..f2bf9844 --- /dev/null +++ b/cloudevents/http/__init__.py @@ -0,0 +1,30 @@ +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +import json +import typing + +from cloudevents.http.event import ( + CloudEvent +) +from cloudevents.http.json_methods import to_json, from_json +from cloudevents.http.requests import from_http, to_binary_http, to_structured_http + + + + + + + + + diff --git a/cloudevents/sdk/http/event.py b/cloudevents/http/event.py similarity index 50% rename from cloudevents/sdk/http/event.py rename to cloudevents/http/event.py index c7d4b0a8..a31b894b 100644 --- a/cloudevents/sdk/http/event.py +++ b/cloudevents/http/event.py @@ -13,39 +13,13 @@ # under the License. import datetime -import json import typing import uuid -from cloudevents.sdk import converters, marshaller, types -from cloudevents.sdk.converters import is_binary -from cloudevents.sdk.event import v1, v03 -from cloudevents.sdk.marshaller import HTTPMarshaller +from cloudevents.http.mappings import _required_by_version -def default_marshaller(content: any): - if content is None or len(content) == 0: - return None - try: - return json.dumps(content) - except TypeError: - return content - - -_marshaller_by_format = { - converters.TypeStructured: lambda x: x, - converters.TypeBinary: default_marshaller, -} - -_obj_by_version = {"1.0": v1.Event, "0.3": v03.Event} - -_required_by_version = { - "1.0": v1.Event._ce_required_fields, - "0.3": v03.Event._ce_required_fields, -} - - -class EventClass: +class CloudEvent: """ Python-friendly cloudevent class supporting v1 events Supports both binary and structured mode CloudEvents @@ -114,71 +88,5 @@ def __len__(self): def __contains__(self, key): return key in self._attributes - -def _to_http( - event: EventClass, - format: str = converters.TypeStructured, - data_marshaller: types.MarshallerType = None, -) -> (dict, typing.Union[bytes, str]): - """ - Returns a tuple of HTTP headers/body dicts representing this cloudevent - - :param format: constant specifying an encoding format - :type format: str - :param data_marshaller: Callable function to cast event.data into - either a string or bytes - :type data_marshaller: types.MarshallerType - :returns: (http_headers: dict, http_body: bytes or str) - """ - if data_marshaller is None: - data_marshaller = _marshaller_by_format[format] - - if event._attributes["specversion"] not in _obj_by_version: - raise ValueError( - f"Unsupported specversion: {event._attributes['specversion']}" - ) - - event_handler = _obj_by_version[event._attributes["specversion"]]() - for k, v in event._attributes.items(): - event_handler.Set(k, v) - event_handler.data = event.data - - return marshaller.NewDefaultHTTPMarshaller().ToRequest( - event_handler, format, data_marshaller=data_marshaller - ) - - -def to_structured_http( - event: EventClass, data_marshaller: types.MarshallerType = None, -) -> (dict, typing.Union[bytes, str]): - """ - Returns a tuple of HTTP headers/body dicts representing this cloudevent - - :param event: CloudEvent to cast into http data - :type event: CloudEvent - :param data_marshaller: Callable function to cast event.data into - either a string or bytes - :type data_marshaller: types.MarshallerType - :returns: (http_headers: dict, http_body: bytes or str) - """ - return _to_http(event=event, data_marshaller=data_marshaller) - - -def to_binary_http( - event: EventClass, data_marshaller: types.MarshallerType = None, -) -> (dict, typing.Union[bytes, str]): - """ - Returns a tuple of HTTP headers/body dicts representing this cloudevent - - :param event: CloudEvent to cast into http data - :type event: CloudEvent - :param data_marshaller: Callable function to cast event.data into - either a string or bytes - :type data_marshaller: types.UnmarshallerType - :returns: (http_headers: dict, http_body: bytes or str) - """ - return _to_http( - event=event, - format=converters.TypeBinary, - data_marshaller=data_marshaller, - ) + def __repr__(self): + return str({"attributes": self._attributes, "data": self.data}) diff --git a/cloudevents/http/json_methods.py b/cloudevents/http/json_methods.py new file mode 100644 index 00000000..0370061a --- /dev/null +++ b/cloudevents/http/json_methods.py @@ -0,0 +1,34 @@ +from cloudevents.http.event import CloudEvent +from cloudevents.sdk import types +from cloudevents.http.requests import to_structured_http, from_http +import typing + +def to_json( + event: CloudEvent, data_marshaller: types.MarshallerType = None +) -> typing.Union[str, bytes]: + """ + Cast an CloudEvent into a json object + :param event: CloudEvent which will be converted into a json object + :type event: CloudEvent + :param data_marshaller: Callable function which will cast event.data + into a json object + :type data_marshaller: typing.Callable + :returns: json object representing the given event + """ + return to_structured_http(event, data_marshaller=data_marshaller)[1] + + +def from_json( + data: typing.Union[str, bytes], + data_unmarshaller: types.UnmarshallerType = None, +) -> CloudEvent: + """ + Cast json encoded data into an CloudEvent + :param data: json encoded cloudevent data + :type event: typing.Union[str, bytes] + :param data_unmarshaller: Callable function which will cast data to a + python object + :type data_unmarshaller: typing.Callable + :returns: CloudEvent representing given cloudevent json object + """ + return from_http(data=data, headers={}, data_unmarshaller=data_unmarshaller) diff --git a/cloudevents/http/mappings.py b/cloudevents/http/mappings.py new file mode 100644 index 00000000..16db89f4 --- /dev/null +++ b/cloudevents/http/mappings.py @@ -0,0 +1,15 @@ +from cloudevents.sdk.event import v1, v03 +from cloudevents.sdk import converters +from cloudevents.http.util import default_marshaller + +_marshaller_by_format = { + converters.TypeStructured: lambda x: x, + converters.TypeBinary: default_marshaller, +} + +_obj_by_version = {"1.0": v1.Event, "0.3": v03.Event} + +_required_by_version = { + "1.0": v1.Event._ce_required_fields, + "0.3": v03.Event._ce_required_fields, +} diff --git a/cloudevents/http/requests.py b/cloudevents/http/requests.py new file mode 100644 index 00000000..fcaed216 --- /dev/null +++ b/cloudevents/http/requests.py @@ -0,0 +1,120 @@ +from cloudevents.http.mappings import _marshaller_by_format, _obj_by_version +from cloudevents.http.event import CloudEvent +from cloudevents.sdk import types, converters, marshaller +from cloudevents.http.util import _json_or_string +import typing +import json + + +def from_http( + data: typing.Union[str, bytes], + headers: typing.Dict[str, str], + data_unmarshaller: types.UnmarshallerType = None, +): + """ + Unwrap a CloudEvent (binary or structured) from an HTTP request. + :param data: the HTTP request body + :type data: typing.IO + :param headers: the HTTP headers + :type headers: typing.Dict[str, str] + :param data_unmarshaller: Callable function to map data to a python object + e.g. lambda x: x or lambda x: json.loads(x) + :type data_unmarshaller: types.UnmarshallerType + """ + if data_unmarshaller is None: + data_unmarshaller = _json_or_string + + marshall = marshaller.NewDefaultHTTPMarshaller() + + if converters.is_binary(headers): + specversion = headers.get("ce-specversion", None) + else: + raw_ce = json.loads(data) + specversion = raw_ce.get("specversion", None) + + if specversion is None: + raise ValueError("could not find specversion in HTTP request") + + event_handler = _obj_by_version.get(specversion, None) + + if event_handler is None: + raise ValueError(f"found invalid specversion {specversion}") + + event = marshall.FromRequest( + event_handler(), headers, data, data_unmarshaller=data_unmarshaller + ) + attrs = event.Properties() + attrs.pop("data", None) + attrs.pop("extensions", None) + attrs.update(**event.extensions) + + return CloudEvent(attrs, event.data) + + +def _to_http( + event: CloudEvent, + format: str = converters.TypeStructured, + data_marshaller: types.MarshallerType = None, +) -> (dict, typing.Union[bytes, str]): + """ + Returns a tuple of HTTP headers/body dicts representing this cloudevent + + :param format: constant specifying an encoding format + :type format: str + :param data_marshaller: Callable function to cast event.data into + either a string or bytes + :type data_marshaller: types.MarshallerType + :returns: (http_headers: dict, http_body: bytes or str) + """ + if data_marshaller is None: + data_marshaller = _marshaller_by_format[format] + + if event._attributes["specversion"] not in _obj_by_version: + raise ValueError( + f"Unsupported specversion: {event._attributes['specversion']}" + ) + + event_handler = _obj_by_version[event._attributes["specversion"]]() + for k, v in event._attributes.items(): + event_handler.Set(k, v) + event_handler.data = event.data + + return marshaller.NewDefaultHTTPMarshaller().ToRequest( + event_handler, format, data_marshaller=data_marshaller + ) + + +def to_structured_http( + event: CloudEvent, data_marshaller: types.MarshallerType = None, +) -> (dict, typing.Union[bytes, str]): + """ + Returns a tuple of HTTP headers/body dicts representing this cloudevent + + :param event: CloudEvent to cast into http data + :type event: CloudEvent + :param data_marshaller: Callable function to cast event.data into + either a string or bytes + :type data_marshaller: types.MarshallerType + :returns: (http_headers: dict, http_body: bytes or str) + """ + return _to_http(event=event, data_marshaller=data_marshaller) + + +def to_binary_http( + event: CloudEvent, data_marshaller: types.MarshallerType = None, +) -> (dict, typing.Union[bytes, str]): + """ + Returns a tuple of HTTP headers/body dicts representing this cloudevent + + :param event: CloudEvent to cast into http data + :type event: CloudEvent + :param data_marshaller: Callable function to cast event.data into + either a string or bytes + :type data_marshaller: types.UnmarshallerType + :returns: (http_headers: dict, http_body: bytes or str) + """ + return _to_http( + event=event, + format=converters.TypeBinary, + data_marshaller=data_marshaller, + ) diff --git a/cloudevents/http/util.py b/cloudevents/http/util.py new file mode 100644 index 00000000..d51c3988 --- /dev/null +++ b/cloudevents/http/util.py @@ -0,0 +1,20 @@ +import json +import typing + + +def default_marshaller(content: any): + if content is None or len(content) == 0: + return None + try: + return json.dumps(content) + except TypeError: + return content + + +def _json_or_string(content: typing.Union[str, bytes]): + if len(content) == 0: + return None + try: + return json.loads(content) + except (json.JSONDecodeError, TypeError) as e: + return content \ No newline at end of file diff --git a/cloudevents/sdk/http/__init__.py b/cloudevents/sdk/http/__init__.py deleted file mode 100644 index 90904024..00000000 --- a/cloudevents/sdk/http/__init__.py +++ /dev/null @@ -1,114 +0,0 @@ -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -import json -import typing - -from cloudevents.sdk import converters, marshaller, types -from cloudevents.sdk.event import v1, v03 -from cloudevents.sdk.http.event import ( - EventClass, - _obj_by_version, - to_binary_http, - to_structured_http, -) - - -class CloudEvent(EventClass): - def __repr__(self): - return to_structured_http(self)[1].decode() - - -def _json_or_string(content: typing.Union[str, bytes]): - if len(content) == 0: - return None - try: - return json.loads(content) - except (json.JSONDecodeError, TypeError) as e: - return content - - -def from_http( - data: typing.Union[str, bytes], - headers: typing.Dict[str, str], - data_unmarshaller: types.UnmarshallerType = None, -): - """ - Unwrap a CloudEvent (binary or structured) from an HTTP request. - :param data: the HTTP request body - :type data: typing.IO - :param headers: the HTTP headers - :type headers: typing.Dict[str, str] - :param data_unmarshaller: Callable function to map data to a python object - e.g. lambda x: x or lambda x: json.loads(x) - :type data_unmarshaller: types.UnmarshallerType - """ - if data_unmarshaller is None: - data_unmarshaller = _json_or_string - - marshall = marshaller.NewDefaultHTTPMarshaller() - - if converters.is_binary(headers): - specversion = headers.get("ce-specversion", None) - else: - raw_ce = json.loads(data) - specversion = raw_ce.get("specversion", None) - - if specversion is None: - raise ValueError("could not find specversion in HTTP request") - - event_handler = _obj_by_version.get(specversion, None) - - if event_handler is None: - raise ValueError(f"found invalid specversion {specversion}") - - event = marshall.FromRequest( - event_handler(), headers, data, data_unmarshaller=data_unmarshaller - ) - attrs = event.Properties() - attrs.pop("data", None) - attrs.pop("extensions", None) - attrs.update(**event.extensions) - - return CloudEvent(attrs, event.data) - - -def to_json( - event: EventClass, data_marshaller: types.MarshallerType = None -) -> typing.Union[str, bytes]: - """ - Cast an EventClass into a json object - :param event: EventClass which will be converted into a json object - :type event: EventClass - :param data_marshaller: Callable function which will cast event.data - into a json object - :type data_marshaller: typing.Callable - :returns: json object representing the given event - """ - return to_structured_http(event, data_marshaller=data_marshaller)[1] - - -def from_json( - data: typing.Union[str, bytes], - data_unmarshaller: types.UnmarshallerType = None, -) -> EventClass: - """ - Cast json encoded data into an EventClass - :param data: json encoded cloudevent data - :type event: typing.Union[str, bytes] - :param data_unmarshaller: Callable function which will cast data to a - python object - :type data_unmarshaller: typing.Callable - :returns: EventClass representing given cloudevent json object - """ - return from_http(data=data, headers={}, data_unmarshaller=data_unmarshaller) diff --git a/cloudevents/tests/test_event_extensions.py b/cloudevents/tests/test_event_extensions.py index 57afff47..b9731ab3 100644 --- a/cloudevents/tests/test_event_extensions.py +++ b/cloudevents/tests/test_event_extensions.py @@ -15,7 +15,7 @@ import pytest -from cloudevents.sdk.http import ( +from cloudevents.http import ( CloudEvent, from_http, to_binary_http, diff --git a/cloudevents/tests/test_http_events.py b/cloudevents/tests/test_http_events.py index 140fb823..ece71f4a 100644 --- a/cloudevents/tests/test_http_events.py +++ b/cloudevents/tests/test_http_events.py @@ -21,7 +21,7 @@ from sanic import Sanic, response from cloudevents.sdk import converters -from cloudevents.sdk.http import ( +from cloudevents.http import ( CloudEvent, from_http, to_binary_http, diff --git a/cloudevents/tests/test_http_json_methods.py b/cloudevents/tests/test_http_json_methods.py index 293a9efc..71074b19 100644 --- a/cloudevents/tests/test_http_json_methods.py +++ b/cloudevents/tests/test_http_json_methods.py @@ -16,7 +16,7 @@ import pytest -from cloudevents.sdk.http import CloudEvent, from_json, to_json +from cloudevents.http import CloudEvent, from_json, to_json test_data = json.dumps({"data-key": "val"}) test_attributes = { diff --git a/samples/http-image-cloudevents/client.py b/samples/http-image-cloudevents/client.py index 8b2fc695..3b856d1f 100644 --- a/samples/http-image-cloudevents/client.py +++ b/samples/http-image-cloudevents/client.py @@ -15,7 +15,7 @@ import requests -from cloudevents.sdk.http import CloudEvent, to_binary_http, to_structured_http +from cloudevents.http import CloudEvent, to_binary_http, to_structured_http resp = requests.get( "https://raw.githubusercontent.com/cncf/artwork/master/projects/cloudevents/horizontal/color/cloudevents-horizontal-color.png" diff --git a/samples/http-image-cloudevents/server.py b/samples/http-image-cloudevents/server.py index 7704a30a..07d9a892 100644 --- a/samples/http-image-cloudevents/server.py +++ b/samples/http-image-cloudevents/server.py @@ -16,7 +16,7 @@ from flask import Flask, Response, request from PIL import Image -from cloudevents.sdk.http import from_http +from cloudevents.http import from_http app = Flask(__name__) diff --git a/samples/http-image-cloudevents/test_image_sample.py b/samples/http-image-cloudevents/test_image_sample.py index 0fb295fb..5b1c4030 100644 --- a/samples/http-image-cloudevents/test_image_sample.py +++ b/samples/http-image-cloudevents/test_image_sample.py @@ -7,7 +7,7 @@ from PIL import Image from server import app -from cloudevents.sdk.http import ( +from cloudevents.http import ( CloudEvent, from_http, to_binary_http, diff --git a/samples/http-json-cloudevents/client.py b/samples/http-json-cloudevents/client.py index c7a507ad..a77fd33d 100644 --- a/samples/http-json-cloudevents/client.py +++ b/samples/http-json-cloudevents/client.py @@ -16,7 +16,7 @@ import requests -from cloudevents.sdk.http import CloudEvent, to_binary_http, to_structured_http +from cloudevents.http import CloudEvent, to_binary_http, to_structured_http def send_binary_cloud_event(url): diff --git a/samples/http-json-cloudevents/server.py b/samples/http-json-cloudevents/server.py index e1fbfda0..c36afc82 100644 --- a/samples/http-json-cloudevents/server.py +++ b/samples/http-json-cloudevents/server.py @@ -13,7 +13,7 @@ # under the License. from flask import Flask, request -from cloudevents.sdk.http import from_http +from cloudevents.http import from_http app = Flask(__name__) From ce964c3802ebe21ed076bf7a15e5443456c92612 Mon Sep 17 00:00:00 2001 From: Curtis Mason Date: Thu, 30 Jul 2020 14:33:08 -0700 Subject: [PATCH 2/3] renamed requests.py to http_methods Signed-off-by: Curtis Mason --- cloudevents/http/{requests.py => http_methods.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename cloudevents/http/{requests.py => http_methods.py} (100%) diff --git a/cloudevents/http/requests.py b/cloudevents/http/http_methods.py similarity index 100% rename from cloudevents/http/requests.py rename to cloudevents/http/http_methods.py From d32e0778c683c770d4d40dd4462bab5623527d52 Mon Sep 17 00:00:00 2001 From: Curtis Mason Date: Thu, 30 Jul 2020 14:34:14 -0700 Subject: [PATCH 3/3] lint fixes Signed-off-by: Curtis Mason --- cloudevents/http/__init__.py | 19 ++++++------------- cloudevents/http/http_methods.py | 9 +++++---- cloudevents/http/json_methods.py | 6 ++++-- cloudevents/http/mappings.py | 4 ++-- cloudevents/http/util.py | 2 +- cloudevents/tests/test_http_events.py | 2 +- 6 files changed, 19 insertions(+), 23 deletions(-) diff --git a/cloudevents/http/__init__.py b/cloudevents/http/__init__.py index f2bf9844..80fc5a74 100644 --- a/cloudevents/http/__init__.py +++ b/cloudevents/http/__init__.py @@ -14,17 +14,10 @@ import json import typing -from cloudevents.http.event import ( - CloudEvent +from cloudevents.http.event import CloudEvent +from cloudevents.http.http_methods import ( + from_http, + to_binary_http, + to_structured_http, ) -from cloudevents.http.json_methods import to_json, from_json -from cloudevents.http.requests import from_http, to_binary_http, to_structured_http - - - - - - - - - +from cloudevents.http.json_methods import from_json, to_json diff --git a/cloudevents/http/http_methods.py b/cloudevents/http/http_methods.py index fcaed216..113e1969 100644 --- a/cloudevents/http/http_methods.py +++ b/cloudevents/http/http_methods.py @@ -1,9 +1,10 @@ -from cloudevents.http.mappings import _marshaller_by_format, _obj_by_version +import json +import typing + from cloudevents.http.event import CloudEvent -from cloudevents.sdk import types, converters, marshaller +from cloudevents.http.mappings import _marshaller_by_format, _obj_by_version from cloudevents.http.util import _json_or_string -import typing -import json +from cloudevents.sdk import converters, marshaller, types def from_http( diff --git a/cloudevents/http/json_methods.py b/cloudevents/http/json_methods.py index 0370061a..8d6bfdd6 100644 --- a/cloudevents/http/json_methods.py +++ b/cloudevents/http/json_methods.py @@ -1,7 +1,9 @@ +import typing + from cloudevents.http.event import CloudEvent +from cloudevents.http.http_methods import from_http, to_structured_http from cloudevents.sdk import types -from cloudevents.http.requests import to_structured_http, from_http -import typing + def to_json( event: CloudEvent, data_marshaller: types.MarshallerType = None diff --git a/cloudevents/http/mappings.py b/cloudevents/http/mappings.py index 16db89f4..4a85175c 100644 --- a/cloudevents/http/mappings.py +++ b/cloudevents/http/mappings.py @@ -1,6 +1,6 @@ -from cloudevents.sdk.event import v1, v03 -from cloudevents.sdk import converters from cloudevents.http.util import default_marshaller +from cloudevents.sdk import converters +from cloudevents.sdk.event import v1, v03 _marshaller_by_format = { converters.TypeStructured: lambda x: x, diff --git a/cloudevents/http/util.py b/cloudevents/http/util.py index d51c3988..d641df7a 100644 --- a/cloudevents/http/util.py +++ b/cloudevents/http/util.py @@ -17,4 +17,4 @@ def _json_or_string(content: typing.Union[str, bytes]): try: return json.loads(content) except (json.JSONDecodeError, TypeError) as e: - return content \ No newline at end of file + return content diff --git a/cloudevents/tests/test_http_events.py b/cloudevents/tests/test_http_events.py index ece71f4a..883e01b8 100644 --- a/cloudevents/tests/test_http_events.py +++ b/cloudevents/tests/test_http_events.py @@ -20,13 +20,13 @@ import pytest from sanic import Sanic, response -from cloudevents.sdk import converters from cloudevents.http import ( CloudEvent, from_http, to_binary_http, to_structured_http, ) +from cloudevents.sdk import converters invalid_test_headers = [ {