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.9-cp312-cp312-manylinux_2_28_aarch64.whl (804.8 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ ARM64

rivven-0.0.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (832.9 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

rivven-0.0.9-cp312-cp312-macosx_11_0_arm64.whl (759.5 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

File details

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

File metadata

File hashes

Hashes for rivven-0.0.9-cp312-cp312-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 b41a7b085f32b6824d09d402bd7a999230a79cd83e474c43480bd153e130e3dc
MD5 3c30a1855335c9c745ef8ab3d0a0757b
BLAKE2b-256 8877e738fa85fda75de8d3092ee158b84d3be03df72c041961bafd633bbe2654

See more details on using hashes here.

Provenance

The following attestation bundles were made for rivven-0.0.9-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.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rivven-0.0.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 2938d2599b0d13ac9d97427f7330299db774c7b070a87ef1a36d75e9463b395e
MD5 059608f7f4dc980341cb3350f1ce53b6
BLAKE2b-256 256560020a19a1f2ea9752438b513ef44d1efb00cad45ce00fe49c763cae8fb0

See more details on using hashes here.

Provenance

The following attestation bundles were made for rivven-0.0.9-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.9-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rivven-0.0.9-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e5cbbcec2c2fa1a75f4aa1a5461a93f7a24ca93b1251d87f60c9f289b8e4e6e1
MD5 6298b4383d597ce85ccadc4979de1401
BLAKE2b-256 a54f6800540b793777e54b913a399afae2f78a58455bdaf3a30c34b2bd3e2343

See more details on using hashes here.

Provenance

The following attestation bundles were made for rivven-0.0.9-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