Skip to main content

PyEventCloud

CloudEvents SDK for Python - A complete, type-safe implementation of the CloudEvents specification with zero dependencies.

PyPI version Python versions License

Installation

pip install pyeventcloud

Quick Start

Creating CloudEvents

from pyeventcloud import CloudEvent, create_event

# Create with auto-generated ID
event = create_event(
    source="https://example.com/source",
    type="com.example.event",
    data={"message": "Hello CloudEvents!"}
)

# Create with explicit ID
event = CloudEvent(
    id="custom-id-123",
    source="https://example.com/source",
    type="com.example.event",
    specversion="1.0",
    datacontenttype="application/json",
    data={"key": "value"}
)

# Access attributes directly
print(event.id)        # custom-id-123
print(event.source)    # https://example.com/source
print(event.data)      # {'key': 'value'}

JSON Serialization

from pyeventcloud import to_json, from_json

# Serialize to JSON
json_str = to_json(event)

# Deserialize from JSON
event = from_json(json_str)

# Batch operations
from pyeventcloud import to_json_batch, from_json_batch

events = [event1, event2, event3]
json_str = to_json_batch(events)
events = from_json_batch(json_str)

HTTP Binding

from pyeventcloud import HTTPBinding, JSONFormatter

binding = HTTPBinding()
formatter = JSONFormatter()

# Structured content mode (event in body)
body, headers = binding.to_structured(event, formatter)
# body is bytes, headers is dict[str, str]
# Content-Type: application/cloudevents+json

# Binary content mode (attributes in headers)
body, headers = binding.to_binary(event)
# headers["ce-id"], headers["ce-source"], etc.
# body contains event data

# Parse from HTTP request
event = binding.from_structured(request.body, request.headers, formatter)
event = binding.from_binary(request.body, request.headers)

Kafka Binding

from pyeventcloud import KafkaBinding, JSONFormatter

binding = KafkaBinding()
formatter = JSONFormatter()

# Structured content mode
message = binding.to_structured(event, formatter)
# Returns: KafkaMessage with value, headers, key

# Binary content mode
message = binding.to_binary(event)
# message["value"]: bytes
# message["headers"]: list[tuple[str, bytes]]
# message["key"]: bytes | None

# 'partitionkey' extension maps to Kafka message key
event = CloudEvent(
    id="123",
    source="app",
    type="order.created",
    partitionkey="customer-456"  # Maps to Kafka partition key
)
message = binding.to_binary(event)
# message["key"] == b"customer-456"

Extensions

from pyeventcloud import CloudEvent, register_extension

# Built-in partitionkey extension
event = CloudEvent(
    id="123",
    source="app",
    type="event.type",
    partitionkey="partition-1"  # Built-in extension
)

# Custom extensions
event = CloudEvent(
    id="123",
    source="app",
    type="event.type",
    customextension="value"  # Any custom extension
)

# Access extensions
print(event.extensions["customextension"])  # "value"

# Register custom extension
class MyExtension:
    name = "myext"
    attributes = {"myfield": str}

    def validate(self, event):
        value = event.extensions.get("myfield")
        if value and not isinstance(value, str):
            raise ValidationError("myfield must be a string")

    def get_attributes(self, event):
        return {"myfield": event.extensions.get("myfield")}

register_extension(MyExtension())

Factory Pattern

from pyeventcloud import JSONFormatter, from_dict

formatter = JSONFormatter()

# Custom factory for event creation
def custom_factory(data: dict) -> CloudEvent:
    # Add metadata or transform data
    data["id"] = f"prefix-{data['id']}"
    return from_dict(data)

event = formatter.deserialize(json_str, event_factory=custom_factory)

API Reference

Core

  • CloudEvent - Main CloudEvent class
  • create_event() - Factory function with auto-generated ID
  • from_dict() - Create CloudEvent from dictionary

Formats

  • JSONFormatter - JSON serialization/deserialization
  • to_json() - Serialize single event to JSON
  • from_json() - Deserialize single event from JSON
  • to_json_batch() - Serialize multiple events
  • from_json_batch() - Deserialize multiple events

Bindings

  • HTTPBinding - HTTP protocol binding (structured & binary modes)
  • KafkaBinding - Kafka protocol binding (structured & binary modes)
  • EventSerializer - Protocol for custom serializers

Extensions

  • PartitioningExtension - Built-in partitionkey extension
  • register_extension() - Register custom extension
  • get_extension() - Get registered extension
  • ExtensionRegistry - Extension registry class

Exceptions

  • CloudEventError - Base exception
  • ValidationError - Validation failures
  • SerializationError - Serialization/deserialization errors
  • BindingError - Protocol binding errors
  • ExtensionError - Extension-related errors

Design Philosophy

Fail-Fast Validation

PyEventCloud validates events immediately when created, raising clear errors:

# Invalid event raises ValidationError immediately
try:
    event = CloudEvent(
        id="",  # Empty ID
        source="https://example.com",
        type="event.type"
    )
except ValidationError as e:
    print(e)  # "id must be a non-empty string"
    print(e.attribute)  # "id"

Format Decoupling

Bindings are completely decoupled from formats via the EventSerializer protocol:

# Any serializer implementing the protocol works
binding = HTTPBinding()
body, headers = binding.to_structured(event, JSONFormatter())
body, headers = binding.to_structured(event, AvroFormatter())  # Future
body, headers = binding.to_structured(event, ProtobufFormatter())  # Future

Development

Setup

# Install uv if you haven't already
curl -LsSf https://astral.sh/uv/install.sh | sh

# Clone the repository
git clone https://github.com/plugarut/pyeventcloud.git
cd pyeventcloud

# Install dependencies
uv sync --dev

Running Tests

# Run all tests
uv run pytest

# Run with coverage
uv run pytest --cov=src/pyeventcloud --cov-report=term-missing

# Run type checking
uv run mypy src/

# Run specific test file
uv run pytest tests/unit/test_event.py -v

Building

# Build distribution packages
uv build

# Check build artifacts
ls -lh dist/

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure all tests pass and mypy is happy
  5. Submit a pull request

License

Apache License 2.0 - See LICENSE for details.

Acknowledgments

Links

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyeventcloud-0.1.0.tar.gz (20.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyeventcloud-0.1.0-py3-none-any.whl (30.2 kB view details)

Uploaded Python 3

File details

Details for the file pyeventcloud-0.1.0.tar.gz.

File metadata

  • Download URL: pyeventcloud-0.1.0.tar.gz
  • Upload date:
  • Size: 20.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyeventcloud-0.1.0.tar.gz
Algorithm Hash digest
SHA256 97530fc8216a6a4779a62f270c37260896f1bc345d9966ff793ccfec2b4a48a2
MD5 7c2d90819d8a0e932f430b1447fc76f7
BLAKE2b-256 5c19f488b82fff88b10a89ff8dc0ec31822ce3dec08e8f80ec0c6cc417812451

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyeventcloud-0.1.0.tar.gz:

Publisher: publish.yaml on PlugaruT/pyeventcloud

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyeventcloud-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pyeventcloud-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 30.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyeventcloud-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6264d97f06e3764e16c76f7c4ed67d6f3c280a9d1eb301dade42fdfb1aeb6aa6
MD5 122433e13870936e9e06e1eb3fc0ccfb
BLAKE2b-256 e642696774490e15c965e971794edb515c366e8d6203bd94c6ce743c2eb0ffc3

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyeventcloud-0.1.0-py3-none-any.whl:

Publisher: publish.yaml on PlugaruT/pyeventcloud

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page