Skip to main content

kafkian

code-checks code-checks PyPI

kafkian is a opinionated a high-level consumer and producer on top of confluent-kafka-python/librdkafka and partially inspired by confluent_kafka_helpers. It is intended for use primarily in CQRS/EventSourced systems when usage is mostly limited to producing and consuming encoded messages.

kafkian partially mimics Kafka JAVA API, partially is more pythonic, partially just like the maintainer likes it.

Instead of configuring all the things via properties, most of the things are planned to be configured explicitely and, wneh possible, via dependency injection for easier testing. The configuration dictionaries for both producer and consumer are passed-through directly to underlying confluent producer and consumer, hidden behind a facade.

The library provides a base serializer and deserializer classes, as well as their specialized Avro subclasses, AvroSerializer and AvroDeserializer. This allows having, say, a plain string key and and avro-encoded message, or vice versa. Quite often an avro-encoded string is used as a key, for this purpose we provide AvroStringKeySerializer.

Unlike the Confluent library, we support supplying the specific Avro schema together with the message, just like the Kafka JAVA API. Schemas could be automatically registered with schema registry, also we provide three SubjectNameStrategy, again compatible with Kafka JAVA API.

Usage

Producing messages

1. Initialize the producer

from kafkian import Producer
from kafkian.serde.serialization import AvroSerializer, AvroStringKeySerializer, SubjectNameStrategy

producer = Producer(
    {
        'bootstrap.servers': config.KAFKA_BOOTSTRAP_SERVERS,
    },
    key_serializer=AvroStringKeySerializer(schema_registry_url=config.SCHEMA_REGISTRY_URL),
    value_serializer=AvroSerializer(schema_registry_url=config.SCHEMA_REGISTRY_URL,
                                    subject_name_strategy=SubjectNameStrategy.RecordNameStrategy)
)

2. Define your message schema(s)

from confluent_kafka import avro
from kafkian.serde.avroserdebase import AvroRecord


value_schema_str = """
{
   "namespace": "auth.users",
   "name": "UserCreated",
   "type": "record",
   "fields" : [
     {
       "name" : "uuid",
       "type" : "string"
     },
     {
       "name" : "name",
       "type" : "string"
     },
     {
        "name": "timestamp",
        "type": {
            "type": "long",
            "logicalType": "timestamp-millis"
        }
     }
   ]
}
"""


class UserCreated(AvroRecord):
    _schema = avro.loads(value_schema_str)

3. Produce the message

producer.produce(
    "auth.users.events",
    user.uuid,
    UserCreated({
        "uuid": user.uuid,
        "name": user.name,
        "timestamp": int(user.timestamp.timestamp() * 1000)
    }),
    sync=True
)

Consuming messages

1. Initialize the consumer

CONSUMER_CONFIG = {
    'bootstrap.servers': config.KAFKA_BOOTSTRAP_SERVERS,
    'default.topic.config': {
        'auto.offset.reset': 'latest',
    },
    'group.id': 'notifications'
}

consumer = Consumer(
    CONSUMER_CONFIG,
    topics=["auth.users.events"],
    key_deserializer=AvroDeserializer(schema_registry_url=config.SCHEMA_REGISTRY_URL),
    value_deserializer=AvroDeserializer(schema_registry_url=config.SCHEMA_REGISTRY_URL),
)

2. Consume the messages via the generator

for message in consumer:
    handle_message(message)
    consumer.commit()

Here, message is an instance of Message class, that wraps the original message exposed by the confluent-kafka-python, and you can access the decoded key and value via .key and .value properties respectively.

Notice that deserialization will happen on first access of the properties, so you can properly handle deserialization errors (log it, send to DLQ, etc)

Both key and value are wrapped in a dynamically-generated class, that has the full name same as the corresponding Avro schema full name. In the example above, the value would have class named auth.users.UserCreated.

Avro schemas for the consumed message key and value are accessible via .schema property.

In addition, topic, partition, offset, timestamp, headers properties are available.

Contributing

This library is, as stated, quite opinionated, however, I'm open to suggestions. Write your questions and suggestions as issues here on github!

Running tests

Both unit and system tests are provided.

To run unit-tests, install the requirements and just run

py.test tests/unit/

To run system tests, a Kafka cluster together with a schema registry is required. A Docker compose file is provided, just run

docker-compose up

and once the cluster is up and running, run system tests via

py.test tests/system/

Metadata

Release files for kafkian 0.15.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for kafkian 0.15.1
File Size Uploaded
kafkian-0.15.1.tar.gz 20.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for kafkian 0.15.1
File Interpreter ABI Platform
kafkian-0.15.1-py3-none-any.whl Python 3 none any Details

Total release size: 38.1 kB

Release files / kafkian-0.15.1.tar.gz

Download URL kafkian-0.15.1.tar.gz
Size 20.8 kB
Tags Source
SHA-256 checksum
How to use checksums
b2aff83cff5f92419b67ee6416290845cb41068d8aea55dcedc76b450905d9af
BLAKE2b-256 checksum
How to use checksums
1f3d5b14fbe630e7743dbd39fd1ac96f8c6a19d03de064ff5d2b25a1e40502bc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.3

Release files / kafkian-0.15.1-py3-none-any.whl

Download URL kafkian-0.15.1-py3-none-any.whl
Size 17.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
842eb09099e28ebf0988ef82631f19ef2f7368707dc7e4bed372a73a5a5eedb4
BLAKE2b-256 checksum
How to use checksums
d38860f5b90952afee8ab88afcb6740fe633efadddf1b5eb4380f6cef469f6b3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

0.15.1 This release

2 release files

0.13.0

3 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page