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="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="/path/to/ca.pem",
        server_name="broker.example.com",
        client_cert_path="/path/to/client.pem",  # Optional: mTLS
        client_key_path="/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()
    print(f"Producer ID: {await producer_state.producer_id}, Epoch: {await 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.18-cp312-cp312-manylinux_2_28_aarch64.whl (869.8 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ ARM64

rivven-0.0.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (897.8 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

rivven-0.0.18-cp312-cp312-macosx_11_0_arm64.whl (820.8 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

File details

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

File metadata

File hashes

Hashes for rivven-0.0.18-cp312-cp312-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 c013ff627713006b6eb23d7d7f8d39e693f7c5910c9eb4ee67c2a76a30dd76f0
MD5 de80734ffb68c2d4c7368e1ea25df30c
BLAKE2b-256 abc6660020ef001ddba1e8150d1e47e26996883091a1c48d4c2da2efea95866b

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for rivven-0.0.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d53b31a5792c16f798a4f0deb830670735ef67135ed16c666fbbf42380da8712
MD5 a976dc330ae995f80022b13745aef2e4
BLAKE2b-256 8b9db98d5cb45ff61c19aec6b3d998b2f1f4879a5d6b731553265346ade99daf

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for rivven-0.0.18-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 90ab609969ed14217d7acac600850e3bb61f7414f807628b389461035f055234
MD5 4f746ae3a554bc60a41afb088dbb8d92
BLAKE2b-256 fa7c09e2af99e56b863d7fd726320c463b7098e4ded8a6822d1fbdba525b5672

See more details on using hashes here.

Provenance

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