Skip to content

Commit d95b130

Browse files
cumason123grantDoug Davis
authored
cloudevents version 1.0.1 release (#102)
* docs: rename receiving cloudevents (#91) Signed-off-by: Grant Timmerman <[email protected]> * add coc ref (#90) Signed-off-by: Doug Davis <[email protected]> Co-authored-by: Curtis Mason <[email protected]> * CloudEvents equality override (#98) * added tests to cloudevent eq Signed-off-by: Curtis Mason <[email protected]> * lint fix Signed-off-by: Curtis Mason <[email protected]> * modified changelog Signed-off-by: Curtis Mason <[email protected]> * version bump Signed-off-by: Curtis Mason <[email protected]> * cloudevent fields type checking adjustments (#97) * added exceptions and more indepth can_read Signed-off-by: Curtis Mason <[email protected]> * moved is_binary, is_structured into http module Signed-off-by: Curtis Mason <[email protected]> * changelog and version bump Signed-off-by: Curtis Mason <[email protected]> * removed unused import and spacing Signed-off-by: Curtis Mason <[email protected]> * lint fix Signed-off-by: Curtis Mason <[email protected]> * reverted auto format change Signed-off-by: Curtis Mason <[email protected]> * reverted changelog and auto format changes Signed-off-by: Curtis Mason <[email protected]> * changelog 1.0.1 update (#101) Signed-off-by: Curtis Mason <[email protected]> Co-authored-by: Grant Timmerman <[email protected]> Co-authored-by: Doug Davis <[email protected]>
1 parent 390134c commit d95b130

File tree

15 files changed

+218
-82
lines changed

15 files changed

+218
-82
lines changed

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,21 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [1.0.1]
8+
### Added
9+
- CloudEvent exceptions and event type checking in http module ([#96])
10+
- CloudEvent equality override ([#98])
11+
712
## [1.0.0]
813
### Added
14+
- Update types and handle data_base64 structured ([#34])
915
- Added a user friendly CloudEvent class with data validation ([#36])
1016
- CloudEvent structured cloudevent support ([#47])
17+
- Separated http methods into cloudevents.http module ([#60])
18+
- Implemented to_json and from_json in http module ([#72])
19+
20+
### Fixed
21+
- Fixed top level extensions bug ([#71])
1122

1223
### Removed
1324
- Removed support for Cloudevents V0.2 and V0.1 ([#43])
@@ -74,6 +85,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7485
[#23]: https://github.com/cloudevents/sdk-python/pull/23
7586
[#25]: https://github.com/cloudevents/sdk-python/pull/25
7687
[#27]: https://github.com/cloudevents/sdk-python/pull/27
88+
[#34]: https://github.com/cloudevents/sdk-python/pull/34
7789
[#36]: https://github.com/cloudevents/sdk-python/pull/36
7890
[#43]: https://github.com/cloudevents/sdk-python/pull/43
7991
[#47]: https://github.com/cloudevents/sdk-python/pull/47
92+
[#60]: https://github.com/cloudevents/sdk-python/pull/60
93+
[#71]: https://github.com/cloudevents/sdk-python/pull/71
94+
[#72]: https://github.com/cloudevents/sdk-python/pull/72
95+
[#96]: https://github.com/cloudevents/sdk-python/pull/96
96+
[#98]: https://github.com/cloudevents/sdk-python/pull/98

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ requests.post("<some-url>", data=body, headers=headers)
6464

6565
You can find a complete example of turning a CloudEvent into a HTTP request [in the samples directory](samples/http-json-cloudevents/client.py).
6666

67-
#### Request to CloudEvent
67+
## Receiving CloudEvents
6868

6969
The code below shows how to consume a cloudevent using the popular python web framework
7070
[flask](https://flask.palletsprojects.com/en/1.1.x/quickstart/):
@@ -120,6 +120,17 @@ the same API. It will use semantic versioning with following rules:
120120
- Email: https://lists.cncf.io/g/cncf-cloudevents-sdk
121121
- Contact for additional information: Denis Makogon (`@denysmakogon` on slack).
122122

123+
Each SDK may have its own unique processes, tooling and guidelines, common
124+
governance related material can be found in the
125+
[CloudEvents `community`](https://github.com/cloudevents/spec/tree/master/community)
126+
directory. In particular, in there you will find information concerning
127+
how SDK projects are
128+
[managed](https://github.com/cloudevents/spec/blob/master/community/SDK-GOVERNANCE.md),
129+
[guidelines](https://github.com/cloudevents/spec/blob/master/community/SDK-maintainer-guidelines.md)
130+
for how PR reviews and approval, and our
131+
[Code of Conduct](https://github.com/cloudevents/spec/blob/master/community/GOVERNANCE.md#additional-information)
132+
information.
133+
123134
## Maintenance
124135

125136
We use black and isort for autoformatting. We setup a tox environment to reformat

cloudevents/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "1.0.0"
1+
__version__ = "1.0.1"

cloudevents/exceptions.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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+
class CloudEventMissingRequiredFields(Exception):
15+
pass
16+
17+
18+
class CloudEventTypeErrorRequiredFields(Exception):
19+
pass

cloudevents/http/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import typing
1616

1717
from cloudevents.http.event import CloudEvent
18+
from cloudevents.http.event_type import is_binary, is_structured
1819
from cloudevents.http.http_methods import (
1920
from_http,
2021
to_binary_http,

cloudevents/http/event.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import typing
1717
import uuid
1818

19+
import cloudevents.exceptions as cloud_exceptions
1920
from cloudevents.http.mappings import _required_by_version
2021

2122

@@ -57,17 +58,20 @@ def __init__(
5758
).isoformat()
5859

5960
if self._attributes["specversion"] not in _required_by_version:
60-
raise ValueError(
61+
raise cloud_exceptions.CloudEventMissingRequiredFields(
6162
f"Invalid specversion: {self._attributes['specversion']}"
6263
)
6364
# There is no good way to default 'source' and 'type', so this
6465
# checks for those (or any new required attributes).
6566
required_set = _required_by_version[self._attributes["specversion"]]
6667
if not required_set <= self._attributes.keys():
67-
raise ValueError(
68+
raise cloud_exceptions.CloudEventMissingRequiredFields(
6869
f"Missing required keys: {required_set - attributes.keys()}"
6970
)
7071

72+
def __eq__(self, other):
73+
return self.data == other.data and self._attributes == other._attributes
74+
7175
# Data access is handled via `.data` member
7276
# Attribute access is managed via Mapping type
7377
def __getitem__(self, key):

cloudevents/http/event_type.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import typing
2+
3+
from cloudevents.sdk.converters import binary, structured
4+
5+
6+
def is_binary(headers: typing.Dict[str, str]) -> bool:
7+
"""Uses internal marshallers to determine whether this event is binary
8+
:param headers: the HTTP headers
9+
:type headers: typing.Dict[str, str]
10+
:returns bool: returns a bool indicating whether the headers indicate a binary event type
11+
"""
12+
headers = {key.lower(): value for key, value in headers.items()}
13+
content_type = headers.get("content-type", "")
14+
binary_parser = binary.BinaryHTTPCloudEventConverter()
15+
return binary_parser.can_read(content_type=content_type, headers=headers)
16+
17+
18+
def is_structured(headers: typing.Dict[str, str]) -> bool:
19+
"""Uses internal marshallers to determine whether this event is structured
20+
:param headers: the HTTP headers
21+
:type headers: typing.Dict[str, str]
22+
:returns bool: returns a bool indicating whether the headers indicate a structured event type
23+
"""
24+
headers = {key.lower(): value for key, value in headers.items()}
25+
content_type = headers.get("content-type", "")
26+
structured_parser = structured.JSONHTTPCloudEventConverter()
27+
return structured_parser.can_read(
28+
content_type=content_type, headers=headers
29+
)

cloudevents/http/http_methods.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import json
22
import typing
33

4+
import cloudevents.exceptions as cloud_exceptions
45
from cloudevents.http.event import CloudEvent
6+
from cloudevents.http.event_type import is_binary, is_structured
57
from cloudevents.http.mappings import _marshaller_by_format, _obj_by_version
68
from cloudevents.http.util import _json_or_string
79
from cloudevents.sdk import converters, marshaller, types
@@ -27,19 +29,23 @@ def from_http(
2729

2830
marshall = marshaller.NewDefaultHTTPMarshaller()
2931

30-
if converters.is_binary(headers):
32+
if is_binary(headers):
3133
specversion = headers.get("ce-specversion", None)
3234
else:
3335
raw_ce = json.loads(data)
3436
specversion = raw_ce.get("specversion", None)
3537

3638
if specversion is None:
37-
raise ValueError("could not find specversion in HTTP request")
39+
raise cloud_exceptions.CloudEventMissingRequiredFields(
40+
"could not find specversion in HTTP request"
41+
)
3842

3943
event_handler = _obj_by_version.get(specversion, None)
4044

4145
if event_handler is None:
42-
raise ValueError(f"found invalid specversion {specversion}")
46+
raise cloud_exceptions.CloudEventTypeErrorRequiredFields(
47+
f"found invalid specversion {specversion}"
48+
)
4349

4450
event = marshall.FromRequest(
4551
event_handler(), headers, data, data_unmarshaller=data_unmarshaller
@@ -71,7 +77,7 @@ def _to_http(
7177
data_marshaller = _marshaller_by_format[format]
7278

7379
if event._attributes["specversion"] not in _obj_by_version:
74-
raise ValueError(
80+
raise cloud_exceptions.CloudEventTypeErrorRequiredFields(
7581
f"Unsupported specversion: {event._attributes['specversion']}"
7682
)
7783

cloudevents/sdk/converters/__init__.py

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,36 +11,7 @@
1111
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1212
# License for the specific language governing permissions and limitations
1313
# under the License.
14-
15-
import typing
16-
1714
from cloudevents.sdk.converters import binary, structured
1815

1916
TypeBinary = binary.BinaryHTTPCloudEventConverter.TYPE
2017
TypeStructured = structured.JSONHTTPCloudEventConverter.TYPE
21-
22-
23-
def is_binary(headers: typing.Dict[str, str]) -> bool:
24-
"""Uses internal marshallers to determine whether this event is binary
25-
:param headers: the HTTP headers
26-
:type headers: typing.Dict[str, str]
27-
:returns bool: returns a bool indicating whether the headers indicate a binary event type
28-
"""
29-
headers = {key.lower(): value for key, value in headers.items()}
30-
content_type = headers.get("content-type", "")
31-
binary_parser = binary.BinaryHTTPCloudEventConverter()
32-
return binary_parser.can_read(content_type=content_type, headers=headers)
33-
34-
35-
def is_structured(headers: typing.Dict[str, str]) -> bool:
36-
"""Uses internal marshallers to determine whether this event is structured
37-
:param headers: the HTTP headers
38-
:type headers: typing.Dict[str, str]
39-
:returns bool: returns a bool indicating whether the headers indicate a structured event type
40-
"""
41-
headers = {key.lower(): value for key, value in headers.items()}
42-
content_type = headers.get("content-type", "")
43-
structured_parser = structured.JSONHTTPCloudEventConverter()
44-
return structured_parser.can_read(
45-
content_type=content_type, headers=headers
46-
)

cloudevents/sdk/converters/binary.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
from cloudevents.sdk import exceptions, types
1818
from cloudevents.sdk.converters import base
19-
from cloudevents.sdk.converters.structured import JSONHTTPCloudEventConverter
19+
from cloudevents.sdk.converters.util import has_binary_headers
2020
from cloudevents.sdk.event import base as event_base
2121
from cloudevents.sdk.event import v1, v03
2222

@@ -28,13 +28,11 @@ class BinaryHTTPCloudEventConverter(base.Converter):
2828

2929
def can_read(
3030
self,
31-
content_type: str,
31+
content_type: str = None,
3232
headers: typing.Dict[str, str] = {"ce-specversion": None},
3333
) -> bool:
34-
return ("ce-specversion" in headers) and not (
35-
isinstance(content_type, str)
36-
and content_type.startswith(JSONHTTPCloudEventConverter.MIME_TYPE)
37-
)
34+
35+
return has_binary_headers(headers)
3836

3937
def event_supported(self, event: object) -> bool:
4038
return type(event) in self.SUPPORTED_VERSIONS

0 commit comments

Comments
 (0)