feat(core): add JSON Batch format support#299
Open
PlugaruT wants to merge 2 commits into
Open
Conversation
Implement the CloudEvents JSON Batch format (application/cloudevents-batch+json) in the core package. - formats/json.py: extract shared _event_to_dict/_dict_to_event helpers and add BATCH_CONTENT_TYPE, write_batch, read_batch, get_batch_content_type - formats/base.py: extend the Format protocol with the batch methods - bindings/http.py: add to_batch/from_batch and to_batch_event/from_batch_event, and reject batch payloads in from_http with a clear error - tests: cover round-trip, empty batch, mixed 0.3/1.0 versions, data_base64, invalid-element abort, non-array body, and from_http batch rejection Signed-off-by: PlugaruT <plugaru.tudor@protonmail.com>
xSAVIKx
reviewed
Jun 28, 2026
- Split batch methods (write_batch/read_batch/get_batch_content_type) out of the Format protocol into a separate, runtime-checkable BatchFormat protocol so non-batch formats need not implement batching and existing Format implementations keep working. - Rename HTTP convenience wrappers to_batch_event/from_batch_event to to_events_batch/from_events_batch (a batch of events, not a batch event). - from_http: guard batch detection behind isinstance(BatchFormat), compare content types case-insensitively on both sides, and report the received vs. expected content type in the error. - read_batch: include the actual JSON type in the non-array error, reject non-object elements, and wrap per-element failures with the element index for a clearer error. Signed-off-by: PlugaruT <plugaru.tudor@protonmail.com>
04fc5ed to
dc60518
Compare
xSAVIKx
reviewed
Jul 11, 2026
Comment on lines
+339
to
+345
| content_type = "" | ||
| for key, value in message.headers.items(): | ||
| if key.lower() == CONTENT_TYPE_HEADER: | ||
| content_type = value | ||
| break | ||
|
|
||
| received_content_type = content_type.split(";")[0].strip().lower() |
Member
There was a problem hiding this comment.
this content_type and received_content_type lines are only relevant if we're processing BatchFormat. Let's move them under the check or better have a private named method.
| paths cannot drift. | ||
| """ | ||
| event_data = event.get_data() | ||
| event_dict: dict[str, Any] = dict(event.get_attributes()) |
Member
There was a problem hiding this comment.
Suggested change
| event_dict: dict[str, Any] = dict(event.get_attributes()) | |
| event_attributes: dict[str, Any] = dict(event.get_attributes()) |
| event_dict: dict[str, Any] = dict(event.get_attributes()) | ||
| specversion = event_dict.get("specversion", SPECVERSION_V1_0) | ||
|
|
||
| if event_data is not None: |
Member
There was a problem hiding this comment.
Why don't we invert the condition? This way you'll have a fast way out with return event_dict and then just continue processing the branches. this will allow us to get rid of the nesting
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds support for the CloudEvents JSON Batch format (
application/cloudevents-batch+json) to thecloudevents.corepackage, across the JSON format layer and the HTTP binding.Batch mode is only defined by the spec for the HTTP protocol binding (via the JSON Batch format); Kafka and AMQP define only structured/binary modes, so this change is intentionally scoped to JSON + HTTP.
Changes
formats/json.py: refactorwrite/readonto shared_event_to_dict/_dict_to_eventhelpers (no behavior change), then addBATCH_CONTENT_TYPE,write_batch,read_batch, andget_batch_content_type.formats/base.py: extend theFormatprotocol withwrite_batch/read_batch/get_batch_content_typeso any format implements the same contract.bindings/http.py: addto_batch/from_batchplus theto_batch_event/from_batch_eventJSON-default wrappers;from_httpnow rejects batch payloads with a clear, case-insensitive error pointing callers tofrom_batch.Behavior
data_base64for v1.0,datacontentencoding: base64for v0.3).ValueError.Tests
Added coverage for round-trip, empty batch, mixed-version batches,
data_base64elements, invalid-element abort, non-array body, andfrom_httpbatch rejection (incl. charset param and mixed-case content type). Fulltests/test_coresuite passes (356 tests);ruffclean.