Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed

- Fixed `kafka.to_binary()` raising `KeyError` for events without a
`datacontenttype` and `AttributeError` for non-string attribute values; it now
omits the content-type header when `datacontenttype` is unset and stringifies
attribute values before encoding. ([#305])

## [2.2.0]

### Changed
Expand Down Expand Up @@ -368,3 +375,4 @@ CloudEvents v2 is a rewrite with ongoing development ([#271])
[#279]: https://github.com/cloudevents/sdk-python/pull/279
[#284]: https://github.com/cloudevents/sdk-python/pull/284
[#291]: https://github.com/cloudevents/sdk-python/pull/291
[#305]: https://github.com/cloudevents/sdk-python/pull/305
7 changes: 4 additions & 3 deletions src/cloudevents/v1/kafka/conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,13 @@ def to_binary(
)

headers = {}
if event["datacontenttype"]:
headers["content-type"] = event["datacontenttype"].encode("utf-8")
datacontenttype = event.get("datacontenttype")
if datacontenttype:
headers["content-type"] = datacontenttype.encode("utf-8")
for attr, value in event.get_attributes().items():
if attr not in ["data", "partitionkey", "datacontenttype"]:
if value is not None:
headers["ce_{0}".format(attr)] = value.encode("utf-8")
headers["ce_{0}".format(attr)] = str(value).encode("utf-8")

try:
data = data_marshaller(event.get_data())
Expand Down
14 changes: 14 additions & 0 deletions tests/test_v1_compat/test_kafka_conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,20 @@ def test_sets_headers(self, source_event):
assert "data" not in result.headers
assert "partitionkey" not in result.headers

def test_no_datacontenttype(self, source_event):
# datacontenttype is optional; to_binary must not raise KeyError when it
# is absent, and should simply omit the content-type header.
del source_event["datacontenttype"]
result = to_binary(source_event)
assert "content-type" not in result.headers

def test_non_string_extension_attribute(self, source_event):
# Extension attributes may be non-string (e.g. int) per the CloudEvents
# spec; to_binary must stringify them rather than raising AttributeError.
source_event["extension1"] = 5
result = to_binary(source_event)
assert result.headers["ce_extension1"] == b"5"

def test_raise_marshaller_exception(self, source_event):
with pytest.raises(cloud_exceptions.DataMarshallerError):
to_binary(source_event, data_marshaller=failing_func)
Expand Down