From 9329fab1e28ab2105c6ea24227ca600ce682b5c6 Mon Sep 17 00:00:00 2001 From: Yurii Serhiichuk Date: Tue, 26 May 2026 20:04:00 +0200 Subject: [PATCH 1/5] test(kafka): add test for `datacontenttype` header processing Signed-off-by: Yurii Serhiichuk --- cloudevents/tests/test_kafka_conversions.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cloudevents/tests/test_kafka_conversions.py b/cloudevents/tests/test_kafka_conversions.py index 584a05e4..c57410a3 100644 --- a/cloudevents/tests/test_kafka_conversions.py +++ b/cloudevents/tests/test_kafka_conversions.py @@ -17,8 +17,6 @@ import json import pytest - -from cloudevents import exceptions as cloud_exceptions from cloudevents.abstract.event import AnyCloudEvent from cloudevents.http import CloudEvent from cloudevents.kafka.conversion import ( @@ -31,6 +29,8 @@ from cloudevents.kafka.exceptions import KeyMapperError from cloudevents.sdk import types +from cloudevents import exceptions as cloud_exceptions + def simple_serialize(data: dict) -> bytes: return bytes(json.dumps(data).encode("utf-8")) @@ -335,6 +335,13 @@ def test_sets_headers(self, source_event): "utf-8" ) + def test_datacontenttype_attribute_present_after_setting_header(self, source_event): + result = to_structured(source_event) + datacontenttype = source_event.get("datacontenttype") + assert len(result.headers) == 1 + assert result.headers["content-type"] == datacontenttype.encode("utf-8") + assert datacontenttype in result.value.decode("utf-8") + def test_datamarshaller_exception(self, source_event): with pytest.raises(cloud_exceptions.DataMarshallerError): to_structured(source_event, data_marshaller=failing_func) From dc1aaf7b533a7de706c7d03afdfcc94dccc0fd53 Mon Sep 17 00:00:00 2001 From: Yurii Serhiichuk Date: Tue, 26 May 2026 20:05:51 +0200 Subject: [PATCH 2/5] fix(kafka): use `get` for safekeeping `datacontenttype` header retrieval Signed-off-by: Yurii Serhiichuk --- cloudevents/kafka/conversion.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/cloudevents/kafka/conversion.py b/cloudevents/kafka/conversion.py index bdf2acab..c6e765fc 100644 --- a/cloudevents/kafka/conversion.py +++ b/cloudevents/kafka/conversion.py @@ -15,12 +15,13 @@ import json import typing -from cloudevents import exceptions as cloud_exceptions -from cloudevents import http from cloudevents.abstract import AnyCloudEvent from cloudevents.kafka.exceptions import KeyMapperError from cloudevents.sdk import types +from cloudevents import exceptions as cloud_exceptions +from cloudevents import http + JSON_MARSHALLER: types.MarshallerType = json.dumps JSON_UNMARSHALLER: types.UnmarshallerType = json.loads IDENTITY_MARSHALLER = IDENTITY_UNMARSHALLER = lambda x: x @@ -213,8 +214,9 @@ def to_structured( attrs["data"] = data headers = {} - if "datacontenttype" in attrs: - headers["content-type"] = attrs.pop("datacontenttype").encode("utf-8") + datacontenttype = attrs.get("datacontenttype") + if datacontenttype is not None: + headers["content-type"] = datacontenttype.encode("utf-8") try: value = envelope_marshaller(attrs) From 4f9aa4866250a766b95757c0fce9c71c1ffd72d7 Mon Sep 17 00:00:00 2001 From: Yurii Serhiichuk Date: Tue, 26 May 2026 20:08:16 +0200 Subject: [PATCH 3/5] test(kafka): extend tests to include `datacontenttype` field verification Signed-off-by: Yurii Serhiichuk --- cloudevents/tests/test_kafka_conversions.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cloudevents/tests/test_kafka_conversions.py b/cloudevents/tests/test_kafka_conversions.py index c57410a3..e50fa469 100644 --- a/cloudevents/tests/test_kafka_conversions.py +++ b/cloudevents/tests/test_kafka_conversions.py @@ -247,6 +247,7 @@ def test_sets_value_default_marshallers(self, source_event): "source": source_event["source"], "type": source_event["type"], "time": source_event["time"], + "datacontenttype": source_event["datacontenttype"], "partitionkey": source_event["partitionkey"], "data": self.expected_data, } @@ -263,6 +264,7 @@ def test_sets_value_custom_data_marshaller_default_envelope( "source": source_event["source"], "type": source_event["type"], "time": source_event["time"], + "datacontenttype": source_event["datacontenttype"], "partitionkey": source_event["partitionkey"], "data_base64": base64.b64encode( custom_marshaller(self.expected_data) @@ -281,6 +283,7 @@ def test_sets_value_custom_envelope_marshaller( "source": source_event["source"], "type": source_event["type"], "time": source_event["time"], + "datacontenttype": source_event["datacontenttype"], "partitionkey": source_event["partitionkey"], "data": self.expected_data, } @@ -299,6 +302,7 @@ def test_sets_value_custom_marshallers(self, source_event, custom_marshaller): "source": source_event["source"], "type": source_event["type"], "time": source_event["time"], + "datacontenttype": source_event["datacontenttype"], "partitionkey": source_event["partitionkey"], "data_base64": base64.b64encode( custom_marshaller(self.expected_data) From 3d2304d266073a246d95ab6f448f0afab8df17c2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 26 May 2026 18:14:12 +0000 Subject: [PATCH 4/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- cloudevents/kafka/conversion.py | 5 ++--- cloudevents/tests/test_kafka_conversions.py | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/cloudevents/kafka/conversion.py b/cloudevents/kafka/conversion.py index c6e765fc..8ecac6b8 100644 --- a/cloudevents/kafka/conversion.py +++ b/cloudevents/kafka/conversion.py @@ -15,13 +15,12 @@ import json import typing +from cloudevents import exceptions as cloud_exceptions +from cloudevents import http from cloudevents.abstract import AnyCloudEvent from cloudevents.kafka.exceptions import KeyMapperError from cloudevents.sdk import types -from cloudevents import exceptions as cloud_exceptions -from cloudevents import http - JSON_MARSHALLER: types.MarshallerType = json.dumps JSON_UNMARSHALLER: types.UnmarshallerType = json.loads IDENTITY_MARSHALLER = IDENTITY_UNMARSHALLER = lambda x: x diff --git a/cloudevents/tests/test_kafka_conversions.py b/cloudevents/tests/test_kafka_conversions.py index e50fa469..5deab891 100644 --- a/cloudevents/tests/test_kafka_conversions.py +++ b/cloudevents/tests/test_kafka_conversions.py @@ -17,6 +17,8 @@ import json import pytest + +from cloudevents import exceptions as cloud_exceptions from cloudevents.abstract.event import AnyCloudEvent from cloudevents.http import CloudEvent from cloudevents.kafka.conversion import ( @@ -29,8 +31,6 @@ from cloudevents.kafka.exceptions import KeyMapperError from cloudevents.sdk import types -from cloudevents import exceptions as cloud_exceptions - def simple_serialize(data: dict) -> bytes: return bytes(json.dumps(data).encode("utf-8")) From b1e73df4dae48af745d9f8965e90feee75f2a819 Mon Sep 17 00:00:00 2001 From: Yurii Serhiichuk Date: Tue, 26 May 2026 20:15:52 +0200 Subject: [PATCH 5/5] chore(release): prepare 1.13.0 with `datacontenttype` fix in Kafka converter Signed-off-by: Yurii Serhiichuk --- CHANGELOG.md | 7 +++++++ cloudevents/__init__.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a8f3341..512a43f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.13.0] + +### Fixed +- Kafka `to_structured` converter dropping `datacontentype` attribute + when setting a header. ([#296]) + ## [1.12.1] ### Changed @@ -310,3 +316,4 @@ CloudEvents v2 is a rewrite with ongoing development ([#271]) [#248]: https://github.com/cloudevents/sdk-python/pull/248 [#249]: https://github.com/cloudevents/sdk-python/pull/249 [#271]: https://github.com/cloudevents/sdk-python/pull/271 +[#296]: https://github.com/cloudevents/sdk-python/pull/296 diff --git a/cloudevents/__init__.py b/cloudevents/__init__.py index 63da30fc..6ecab33a 100644 --- a/cloudevents/__init__.py +++ b/cloudevents/__init__.py @@ -12,4 +12,4 @@ # License for the specific language governing permissions and limitations # under the License. -__version__ = "1.12.1" +__version__ = "1.13.0"