Skip to content

Release v2#280

Merged
Klaudioz merged 29 commits intomainfrom
v2
Mar 24, 2026
Merged

Release v2#280
Klaudioz merged 29 commits intomainfrom
v2

Conversation

@xSAVIKx
Copy link
Copy Markdown
Member

@xSAVIKx xSAVIKx commented Mar 23, 2026

This Pull Request marks the official release of v2.0.0 of the CloudEvents Python SDK. This version is a ground-up rewrite designed to provide a more robust, type-safe, and spec-compliant experience for Python developers.

🚀 Key Features and Improvements

  • Protocol-Based Design: Replaced the base class with a Protocol-based architecture (BaseCloudEvent), allowing for more flexible and decoupled event implementations.
  • Strict Validation: Events are now validated at construction time, ensuring compliance with the CloudEvents specification for attribute names, types, and values.
  • Immutability and Explicit Getters: Events are immutable after creation. Dict-like access has been replaced with explicit getter methods (e.g., event.get_source(), event.get_type()) for better IDE support and type safety.
  • Enhanced Protocol Bindings:
    • HTTP: New to_binary_event and from_http_event helpers using an HTTPMessage dataclass.
    • Kafka: Updated Kafka binding with better typing and frozen dataclasses for messages.
    • AMQP (New): Native support for AMQP 1.0 protocol binding.
  • Custom Serialization: Introduced a Format protocol (replacing marshaller callbacks) to support custom serialization formats like YAML or Protobuf.
  • Modern Python Support: Updated requirements to Python 3.10+ and removed heavy dependencies, making python-dateutil the only core requirement.
  • Type Safety: Full mypy strict compliance across the core v2 codebase.

⚠️ Breaking Changes & Migration

The v2 release includes several breaking changes compared to v1. To ease the transition:

  • Compatibility Layer: We have provided a cloudevents.v1 package. You can continue using v1-style logic by updating your imports (e.g., from cloudevents.v1.http import CloudEvent).
  • Migration Guide: A comprehensive MIGRATION.md is included, detailing all architectural shifts, API changes, and import mappings.

✅ Verification Results

  • Tests: All unit tests passed, including new conformance tests for the v2 core and compatibility tests for the v1 layer.
  • Linting: 100% compliance with ruff and mypy (strict).
  • Documentation: README and MIGRATION guides updated to reflect the new API.

xSAVIKx and others added 29 commits September 30, 2024 21:42
* Migrate project to rye and ruff for v2

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* Just run ruff

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* Add the core package stub

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* Move cloudevents to v1

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* Add extra rye configs. update locks to be OS-aware

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* Migrate from rye to uv

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* Use python 3.12 by default for linting

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* Do not mention rye in docs

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Use stricter mypy rules. exclude v1

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* Run isort, flake8

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* fix isort

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* Run ruff with isort

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* Move mypy config to pyproject

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* Exclude samples as well

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* Exclude samples as well

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* Fix mypy pre-commit setup

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

---------

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>
…lidation (#242)

* feat: base `CloudEvent` class as per v1 specs, including attribute validation

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: add typings and docstrings

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: Add support for custom extension names and validate them

Signed-off-by: Tudor <plugaru.tudor@protonmail.com>

* chore: Add copyright and fix missing type info

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: Add getters for attributes and test happy path

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* fix: typing

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: Split validation logic into smaller methods

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: Add method to extract extension by name

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: configure ruff to sort imports also

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: Returns all the errors at ones instead of raising early. Improve tests

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* fix missing type info

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: Improve exceptions handling. Have exceptions grouped by attribute name and typed exceptions

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: Skip type checing for getters of required attributes

We can't use TypedDict here becuase it does not allow for arbitrary keys which we need in order to support custom extension attributes.

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* fix: missing type

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: Improve exceptions and introduce a new one for invalid values

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* fix: str representation for validation error

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix: Fix missing type definitions

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* small fix

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* remove cast of defaultdict to dict

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

---------

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>
Signed-off-by: Tudor <plugaru.tudor@protonmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* feat: draft implementation for JSON format. Only CloudEvent serialization included.

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* Implement read method

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* small fix to read method

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* wrap up JSON format completely and make it compliant with the spec

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* add type annotations

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore(docs): move docstrings from implementation to protocol class

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore(docs): document Format protocol

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

---------

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>
* chore: drop support for PY3.9 since it reached EOL

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: run tests for 3.13 and 3.14

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: update docs

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: update actions to latest version

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

---------

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>
* chore: fix uv lock warnings

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* feat: implement http bindings

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: fix mypy in tests

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: more mypy fixes

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: another try

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: switch from using `Dict` to `dict` for type hints

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: switch type hints to use `|` rather than `Union`

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* refactor: simplify header normalization in from_http function

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* refactor: streamline header normalization in from_binary function

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* refactor: remove redundant comment in from_binary function

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

---------

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>
* feat: full implementation of kafka bindings

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: no need to re-export functions from core module. let users explicitly import

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

---------

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>
* feat(v2): full AMQP 1.0 implementation

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* feat(v2): Support both `_` and `:` when reading AMQP messages

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: define type alias for EventFactory and use it everywhere

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

---------

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>
…and structured even formats (#255)

* chore: provide simplified interface to read/write CE for both binary and
structured even formats

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* fix typing

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

---------

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>
* refactor(config): update dependencies and dev tools versions

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* refactor(workflows): update GitHub Actions and OS versions in workflows

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* docs(releasing): simplify and update releasing guidelines

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* docs(github): enhance pull request template with detailed guidelines and checklist

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
…mline build/publish process using `uv` (#259)

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>
Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>
Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>
* feat: add support for spec version 0.3

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: make ruff fail on unused imports

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

* chore: Move spec version constants to spec module

Moves SPECVERSION_V1_0 and SPECVERSION_V0_3 from the core __init__.py to
a new cloudevents.core.spec module.

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>

---------

Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>
Signed-off-by: Tudor Plugaru <plugaru.tudor@protonmail.com>
* chore: add default values for `id`, `time` and `specversion`

Signed-off-by: PlugaruT <plugaru.tudor@protonmail.com>

* Update MIGRATION.md

Signed-off-by: PlugaruT <plugaru.tudor@protonmail.com>

* chore: update docstrings

Signed-off-by: PlugaruT <plugaru.tudor@protonmail.com>

---------

Signed-off-by: PlugaruT <plugaru.tudor@protonmail.com>
#268)

Per CloudEvents HTTP binding spec (section 3.1.3.2), only these should
  be percent-encoded: space (U+0020), double-quote (U+0022), percent
  (U+0025), and characters outside printable ASCII (U+0021-U+007E).

Signed-off-by: PlugaruT <plugaru.tudor@protonmail.com>
…ode (#269)

* fix(kafka): headers don't need encoding as per kafka binding spec

Signed-off-by: PlugaruT <plugaru.tudor@protonmail.com>

* fix(kafka): partitionkey shall still be passed in kafka headers in
binary mode.

Signed-off-by: PlugaruT <plugaru.tudor@protonmail.com>

---------

Signed-off-by: PlugaruT <plugaru.tudor@protonmail.com>
#267)

The isinstance check in to_structured had a duplicate `bytes` entry
instead of `bytearray`, meaning bytearray data would not be correctly
base64-encoded in the structured kafka message.

Signed-off-by: Artem Muterko <artem@sopho.tech>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>
Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>
* refactor(samples): update to `cloudevents` 2.0.0a1 and modernize usage

- Migrated to `cloudevents` 2.0.0a1 including updated imports and APIs.
- Replaced deprecated `from_http`, `to_binary`, and `to_structured` with the new `from_http_event`, `to_binary_event`, and `to_structured_event`.
- Added required `id` and `specversion` attributes to Cloudevents examples.
- Updated README and client script for consistency and improved usability.

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* refactor(samples): migrate to `cloudevents` 2.0.0a1 and enhance examples

- Updated server, client, and test code to use the updated `cloudevents` 2.0.0a1 API with `from_http_event`, `to_binary_event`, and `to_structured_event`.
- Included required `id` and `specversion` attributes in Cloudevent examples.
- Synchronized README and scripts for better clarity and usability.
- Pinned `cloudevents==2.0.0a1` in `requirements.txt`.

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* chore(samples): bump `cloudevents` to 2.0.0a2 in requirements

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* chore(cloudevents): bump version to 2.0.0-alpha3

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* chore(samples): update `cloudevents` to 2.0.0a3 in requirements

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

---------

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>
Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>
Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

chore(cloudevents): bump version to 2.0.0-alpha4

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

chore(tox): remove tox configuration file

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>
* fix(event): validate attributes for null or empty values

Ensure required attributes ('id', 'source', and 'type') are neither null nor empty across v03 and v1 event versions. Includes stricter validation and new test cases.

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* fix(event): remove max length restriction for extension attributes

Remove the 20-character maximum length restriction for extension attribute names in both v03 and v1 event versions. Update validation error messages and add tests to ensure compatibility with longer attribute names.

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* chore(cloudevents): bump version to 2.0.0-alpha5

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* chore(CHANGELOG): update for 2.0.0-alpha5 with PR #275

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

---------

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>
* fix: standardize import paths from `cloudevents_v1` to `cloudevents.v1` to fix compatibility layer

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* chore(dependencies): add `deprecation` package with version constraint `>=2.0,<3.0` for v1 compat layer

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* chore(tests): relocate v1 test files to `test_v1_compat` directory for improved organization

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* chore(dependencies): update `uv.lock` to add new dependencies and version constraints for libraries including `anyio`, `sanic`, `pydantic`, and others

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* chore(dependencies): reorganize `deprecation` imports across deprecated `v1` modules for consistency

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* chore(tests): standardize import formatting across `test_v1_compat` files for consistency

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* docs(migration): add guidance for using `cloudevents.v1` compatibility layer

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* docs(migration): update `MIGRATION.md` with clarified import mappings, format protocol, and v2 API changes

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* chore(tests): add missing `pytest` import in `test_base_events`

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* chore(tests): add `pytest_ignore_collect` to skip `pydantic` tests on Python 3.14+

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

---------

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>
* chore(pre-commit): bump ruff-pre-commit to v0.15.7

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* chore(pyproject): include MIGRATION.md in build targets

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* chore(dependencies): bump dev dependencies (ruff, isort, pytest-cov, types-python-dateutil)

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* chore(workflows): bump GitHub Actions dependencies

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* chore(dependencies): bump cloudevents to 2.0.0-alpha6

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* chore(CHANGELOG): add entries for v2.0.0-alpha6 changes and fixes

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

---------

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>
* chore(pre-commit): update mypy exclude to ignore test_v1_compat

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* chore(cloudevents): release stable v2.0.0

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

* chore(workflow): remove deprecated branch 'v2' from PyPI release triggers

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>

---------

Signed-off-by: Yurii Serhiichuk <savik.ne@gmail.com>
@xSAVIKx xSAVIKx requested a review from Klaudioz March 23, 2026 18:17
@Klaudioz
Copy link
Copy Markdown

The root-level cloudevents/ directory (old v1 source) shadows src/cloudevents/ (v2). Running import cloudevents.core from a clean clone fails with ModuleNotFoundError. This needs to be resolved before merge either remove the root cloudevents/ directory (since v1 code now lives under src/cloudevents/v1/), or add a [tool.hatch.build.targets.wheel] config and ensure the test runner uses the installed package. As-is, the tests cannot run from source.

@xSAVIKx
Copy link
Copy Markdown
Member Author

xSAVIKx commented Mar 23, 2026

@Klaudioz there's no cloudevents root folder anymore, not sure what you are referring to.

Here's a complete work tree of the v2 branch:

├───.github
│   └───workflows
├───samples
│   ├───http-image-cloudevents
│   └───http-json-cloudevents
├───src
│   └───cloudevents
│       ├───core
│       │   ├───bindings
│       │   ├───formats
│       │   ├───v03
│       │   └───v1
│       └───v1
│           ├───abstract
│           ├───http
│           ├───kafka
│           ├───pydantic
│           │   ├───v1
│           │   └───v2
│           └───sdk
│               ├───converters
│               └───event
└───tests
    ├───test_cloudevents
    ├───test_core
    │   ├───test_bindings
    │   ├───test_format
    │   ├───test_v03
    │   └───test_v1
    └───test_v1_compat

I just grabbed a fresh clone and re-setup the whole env with:

  • uv sync
  • uv run pytest

@xSAVIKx
Copy link
Copy Markdown
Member Author

xSAVIKx commented Mar 24, 2026

@Klaudioz PTAL again. Let me know if you still have issues

Copy link
Copy Markdown

@Klaudioz Klaudioz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rechecking this, I don’t think the packaging concern is real, so I’m retracting that review comment. The branch uses a src layout, and CI installs the project before running the test suite.

@Klaudioz Klaudioz merged commit 435fa56 into main Mar 24, 2026
35 checks passed
@Klaudioz Klaudioz deleted the v2 branch March 24, 2026 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants