Skip to main content

High-performance Python client for Rivven distributed streaming platform

Project description

rivven-python

High-performance Python bindings for the Rivven event streaming platform.

Features

  • Native Performance: Zero-copy message handling through Rust bindings (PyO3)
  • Async-First: Full async/await support with Python's asyncio
  • Type-Safe: Complete type annotations for IDE support
  • Transaction Support: Exactly-once semantics with transactional producers
  • Authentication: Multiple auth methods (simple, SCRAM-SHA-256)
  • Admin Operations: Full topic and partition management

Installation

pip install rivven

Usage

Basic Connection

import asyncio
import rivven

async def main():
    # Connect to Rivven cluster
    client = await rivven.connect("localhost:9092")
    
    # Create a topic
    await client.create_topic("my-topic", partitions=3)
    
    # List topics
    topics = await client.list_topics()
    print(f"Topics: {topics}")

asyncio.run(main())

Producer

import asyncio
import rivven

async def produce():
    client = await rivven.connect("localhost:9092")
    producer = client.producer("my-topic")
    
    # Send a message
    offset = await producer.send(b'{"event": "login"}', key=b"user-123")
    print(f"Sent at offset: {offset}")
    
    # Send to specific partition
    await producer.send_to_partition(b"value", partition=0, key=b"key")
    
    # Batch send for better throughput
    offsets = await producer.send_batch([b"msg1", b"msg2", b"msg3"])

asyncio.run(produce())

Consumer

import asyncio
import rivven

async def consume():
    client = await rivven.connect("localhost:9092")
    consumer = client.consumer("my-topic", group_id="my-group")
    
    # Fetch messages
    messages = await consumer.fetch(max_messages=100)
    for msg in messages:
        print(f"Offset {msg.offset}: {msg.value_str()}")
    
    # Commit offsets
    await consumer.commit()
    
    # Or use async iterator
    async for msg in consumer:
        print(f"Received: {msg.value_str()}")
        await consumer.commit()

asyncio.run(consume())

Admin Operations

import asyncio
import rivven

async def admin():
    client = await rivven.connect("localhost:9092")
    
    # Create topic
    await client.create_topic("new-topic", partitions=3, replication_factor=1)
    
    # List topics
    topics = await client.list_topics()
    print(f"Topics: {topics}")
    
    # Get topic configuration
    configs = await client.describe_topic_configs("new-topic")
    print(f"Configs: {configs}")
    
    # Modify topic configuration
    await client.alter_topic_config("new-topic", "retention.ms", "86400000")
    
    # Add partitions
    await client.create_partitions("new-topic", new_total=6)
    
    # Get offset for timestamp
    offset = await client.get_offset_for_timestamp("new-topic", 0, 1699900000000)
    
    # Delete records before offset
    await client.delete_records("new-topic", 0, before_offset=100)
    
    # Delete topic
    await client.delete_topic("old-topic")

asyncio.run(admin())

Authentication

import asyncio
import rivven

async def authenticated():
    client = await rivven.connect("localhost:9092")
    
    # Simple authentication
    await client.authenticate("username", "password")
    
    # Or SCRAM-SHA-256 authentication
    await client.authenticate_scram("username", "password")
    
    # Use client as normal
    topics = await client.list_topics()

asyncio.run(authenticated())

TLS Connection

import asyncio
import rivven

async def secure():
    # Connect with TLS
    client = await rivven.connect_tls(
        "localhost:9093",
        ca_cert="/path/to/ca.crt",
        client_cert="/path/to/client.crt",  # Optional: mTLS
        client_key="/path/to/client.key",   # Optional: mTLS
    )
    
    topics = await client.list_topics()

asyncio.run(secure())

Transactions (Exactly-Once Semantics)

import asyncio
import rivven

async def transactional():
    client = await rivven.connect("localhost:9092")
    
    # Initialize transactional producer - returns a ProducerState object
    producer_state = await client.init_producer_id("my-txn-id")
    print(f"Producer ID: {producer_state.producer_id}, Epoch: {producer_state.producer_epoch}")
    
    try:
        # Begin transaction
        await client.begin_transaction("my-txn-id", producer_state)
        
        # Add partitions to transaction
        await client.add_partitions_to_txn("my-txn-id", producer_state, [
            ("my-topic", 0),
            ("my-topic", 1),
        ])
        
        # Publish with idempotent semantics - sequence is auto-incremented
        await client.publish_idempotent(
            topic="my-topic",
            value=b"message-1",
            producer_state=producer_state,
            key=b"key-1"
        )
        
        await client.publish_idempotent(
            topic="my-topic",
            value=b"message-2",
            producer_state=producer_state,
            key=b"key-2"
        )
        
        # Commit transaction
        await client.commit_transaction("my-txn-id", producer_state)
        
    except Exception as e:
        # Abort on error
        await client.abort_transaction("my-txn-id", producer_state)
        raise

asyncio.run(transactional())

Exception Handling

Rivven provides a hierarchy of exception types for granular error handling:

from rivven import (
    RivvenException,        # Base exception for all Rivven errors
    ConnectionException,    # Connection-related errors
    ServerException,        # Server-side errors
    TimeoutException,       # Request timeouts
    SerializationException, # Serialization/deserialization errors
    ConfigException,        # Configuration errors
)

try:
    client = await rivven.connect("localhost:9092")
except ConnectionException as e:
    print(f"Failed to connect: {e}")
except TimeoutException as e:
    print(f"Connection timed out: {e}")
except RivvenException as e:
    print(f"General Rivven error: {e}")

Testing

Running Tests

# Install test dependencies
pip install -r requirements-test.txt

# Run API tests (no broker required)
pytest tests/test_api.py -v

# Run integration tests (requires running broker)
export RIVVEN_BROKER="localhost:9092"
pytest tests/test_integration.py -v -m integration

Type Checking

The package includes type stubs (rivven.pyi) for IDE support and static type checking:

pip install mypy
mypy your_code.py

Building from Source

# Install maturin
pip install maturin

# Build wheel
cd crates/rivven-python
maturin build --release

# Install locally
pip install target/wheels/rivven-*.whl

# Development install (editable)
maturin develop --release

Documentation

License

Apache-2.0. See LICENSE.

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

rivven-0.0.11-cp312-cp312-manylinux_2_28_aarch64.whl (803.4 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ ARM64

rivven-0.0.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (835.1 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

rivven-0.0.11-cp312-cp312-macosx_11_0_arm64.whl (761.9 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

File details

Details for the file rivven-0.0.11-cp312-cp312-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for rivven-0.0.11-cp312-cp312-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 f21566a5a34c560c8177a3e3f610586918e52b9af8ccc79acdbbc8c35d7d0122
MD5 f617cc6e6ad15d16ce403b962ebc2db9
BLAKE2b-256 ecfe93236846753fb7aa66b35eb89be56222fdf7affb1f927f74ff9433ee9535

See more details on using hashes here.

Provenance

The following attestation bundles were made for rivven-0.0.11-cp312-cp312-manylinux_2_28_aarch64.whl:

Publisher: release.yml on hupe1980/rivven

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

File details

Details for the file rivven-0.0.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rivven-0.0.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 3516f86fe624c1daf9e0a83c61e6921d6de4983c5dec1a92a297eed6d9f398eb
MD5 c95c5d285faba4ec9dde24203207f067
BLAKE2b-256 676663d33c7b0918493a479e5d70168338e3213a7b2d36b89614f132aa87ff53

See more details on using hashes here.

Provenance

The following attestation bundles were made for rivven-0.0.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on hupe1980/rivven

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

File details

Details for the file rivven-0.0.11-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rivven-0.0.11-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3b765155f997498f1a2812e16407dcb1dd31f3b8b7e6e51a4e1580fa53c6c766
MD5 a108409964bd10cba88f877360ee1a49
BLAKE2b-256 c292cbbd190b6421c0732e431f545e6ee7956406d0a454bb93f9ae44873df0f3

See more details on using hashes here.

Provenance

The following attestation bundles were made for rivven-0.0.11-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: release.yml on hupe1980/rivven

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

Supported by

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