WKafka 🚀
Professional, Decorator-based Kafka Wrapper for Python.
WKafka simplifies Apache Kafka integration by providing a high-level, intuitive API focused on developer productivity. It includes built-in support for complex data types like JSON, YAML, Images, Files, and Pydantic models, making it ideal for modern microservices, IoT, and Computer Vision pipelines.
🌟 Features
- Decorator-driven API: Minimalistic and clean message handling.
- Modern Python: Fully typed, PEP 8 compliant, supporting Python 3.9 through 3.14.
- Enterprise Security: Built-in support for SASL (PLAIN, SCRAM) and KRaft mode.
- Multimedia & File Native: Seamlessly send and receive images (OpenCV/NumPy/PIL) and arbitrary files (PDF, ZIP, TXT) via
format="file". - Type-safe Pydantic Validation: Automatic schema validation with
format="pydantic". - Manual Offset Commit: Control At-Least-Once delivery semantics with
auto_commit=Falseandmsg.commit(). - Immediate Commit on Receive: Built-in support for At-Most-Once / early acknowledgment with
commit_on_receive=True. - Decoupled Background Execution: Non-blocking background worker dispatch with
background=Trueandbackground_workers=Nto prevent Kafka heartbeat timeouts during long-running tasks. - Partition Auto-scaling & Retries: Automatic topic partition scaling with
describe_topicsinspection and exponential backoff retry resilience against transientNodeNotReadyError. - Async/Await Support: Define non-blocking
async defconsumer handlers. - Professional Ops: Structured logging via
loguruand multi-version testing withtox.
📦 Installation
# Via pip
pip install wkafka
# Via poetry
poetry add wkafka
Optional snappy compression:
pip install wkafka[snappy]
🚀 Quick Start
Basic Producer & Consumer
from wkafka import WKafka
# Configures automatically via KAFKA_SERVER or defaults to localhost:9092
kafka = WKafka(bootstrap_servers="localhost:9092")
@kafka.consumer(topic="orders", format="json")
def handle_order(msg):
print(f"New order received: {msg.value}")
# Start consumers in a background thread pool
kafka.run_consumers(block=True)
# Produce with context manager safety
with kafka.producer() as p:
p.send("orders", value={"id": 123, "item": "Coffee"}, format="json")
Manual Offset Commit
@kafka.consumer(topic="transactions", format="json", auto_commit=False)
def handle_tx(msg):
# Process business logic
save_to_db(msg.value)
# Explicitly commit offset only after success
msg.commit()
Retries & DLQ Routing
@kafka.consumer(
topic="unstable_events",
format="json",
max_retries=3,
retry_delay=1.0,
dlq_topic="unstable_events.DLQ"
)
def handle_event(msg):
process_payload(msg.value)
Immediate Commit on Receive (Early Acknowledgment)
@kafka.consumer(topic="events", format="json", commit_on_receive=True)
def handle_early_ack(msg):
# Offset is committed immediately upon receipt before entering this function
process_quick_event(msg.value)
Long-Running Tasks & Decoupled Background Workers (The ML & Video Dilemma)
In Apache Kafka, if a consumer handler takes longer than max_poll_interval_ms (default: 5 minutes) to return:
- The Kafka broker assumes the consumer has crashed or deadlocked.
- The broker evicts the consumer from the consumer group (Consumer Group Rebalance).
- The message offset is never committed, and another consumer (or the restarted consumer) picks up the same message in an infinite duplicate loop.
WKafka provides two native solutions that can be used independently or combined:
commit_on_receive=True: Forces an immediate offset commit to the Kafka broker as soon as the message is dequeued, before entering your handler function. This ensures that the message is acknowledged and will not be re-delivered if processing is interrupted.background=True: Dispatches the execution of your callback to an internalThreadPoolExecutor. The main Kafka polling thread returns immediately to itspoll()loop, continually answering broker heartbeats. Your heavy processing function can run for minutes or hours without ever triggering a timeout or rebalance!background_workers=N: Controls the maximum number of concurrent tasks executed in parallel.
from wkafka import WKafka
kafka = WKafka(bootstrap_servers="localhost:9092")
# Perfect for ML inference, video processing, or PDF generation that takes hours
@kafka.consumer(
topic="reports.generate",
format="json",
commit_on_receive=True, # 1. Commit offset immediately upon receipt
background=True, # 2. Offload execution to a background worker pool
background_workers=4, # 3. Allow up to 4 parallel heavy tasks
)
def handle_long_task(msg):
# Runs in a separate thread.
# The Kafka consumer loop never blocks and never triggers max_poll_interval_ms rebalances!
generate_heavy_report_and_pdf(msg.value)
Architecture Flow:
Kafka Topic ────────► Consumer Thread (poll)
│
├─► commit_on_receive=True ──► [Commit Offset to Broker Immediately]
│
└─► background=True ─────────► [ThreadPoolExecutor Worker 1] ──► Long Task (Hours)
├─► [ThreadPoolExecutor Worker 2] ──► Long Task (Hours)
└─► Consumer Thread Continues Polling (Heartbeats Active!)
📋 Consumer Configuration Reference (@kafka.consumer)
| Parameter | Type | Default | Description |
|---|---|---|---|
topic |
str | List[str] |
None |
Topic or list of topics to subscribe to. |
pattern |
str |
None |
Regex pattern for dynamic multi-topic matching. |
group_id |
str |
Auto-generated | Consumer group identifier. |
format |
str |
"json" |
Deserializer format ("json", "yaml", "image", "file", "pydantic"). |
auto_commit |
bool |
True |
Enables periodic automatic background offset commits by Kafka. |
commit_on_receive |
bool |
False |
Immediately commits the offset upon receipt before executing the handler. |
background |
bool |
False |
Executes handler in a background worker thread to keep the consumer poll loop active. |
background_workers |
int |
1 |
Maximum parallel worker threads when background=True. |
max_retries |
int |
0 |
Number of retry attempts on exception before routing to DLQ. |
retry_delay |
float |
1.0 |
Initial exponential backoff delay in seconds between retries. |
dlq_topic |
str |
None |
Dead Letter Queue topic to route permanently failed messages. |
model |
BaseModel |
None |
Pydantic model class for automatic typed validation when format="pydantic". |
key_filter |
str |
None |
Only processes messages matching this specific partition key. |
partition_scale |
bool |
None |
Enables dynamic partition scaling via KafkaAdminClient for true parallel workers. |
📂 Project Structure
wkafka.core: Orchestration and base logic (WKafka,Message).wkafka.serializers: Extensible serialization system (JSONSerializer,YAMLSerializer,ImageSerializer,PydanticSerializer,FileSerializer).wkafka.controller: Backward compatibility layer for legacy code.examples/: 15 complete, production-ready example modules (01_basicthrough15_long_running_background_tasks).environment/: Production-ready Docker setups (KRaft, SASL).
🛠️ Tecnologías y Librerías Relevantes
- Python (3.9 - 3.14): Lenguaje principal de desarrollo y ejecución.
- kafka-python-ng / kafka-python: Client library for low-level communication with Apache Kafka.
- OpenCV (
opencv-python) & Pillow: Procesamiento, renderizado, serialización y deserialización de imágenes. - Pydantic: Validación de esquemas y modelos de datos tipados (
format="pydantic"). - NumPy: Manejo de estructuras de datos matriciales multidimensionales para imágenes.
- PyYAML: Serialización y deserialización nativa de estructuras YAML.
- Loguru: Sistema avanzado de logging estructurado.
🧪 Unit Testing & Coverage
To run the unit test suite, calculate coverage, or execute tests inside a sandboxed Docker container:
Run Locally (pytest)
poetry run pytest tests/
Coverage Report (80% Minimum Guaranteed)
./run_coverage.sh
El script genera un informe de cobertura HTML (htmlcov/index.html) garantizando una cobertura mínima global de 80%.
Sandboxed Testing with Docker
./run_tests_docker.sh
👤 Author & Affiliation
- William Steve Rodriguez Villamizar (Wisrovi)
- Cargo: Principal AI Engineer & Applied AI Solutions Architect | Scientific Researcher
- 🌐 Official Website: wisrovi.dev
- 💼 LinkedIn: wisrovi-rodriguez
- 🆔 ORCID: 0009-0005-0710-1861
- 📦 PyPI: pypi.org/user/wisrovi/
- 🐙 GitHub: @wisrovi
📜 License
Distributed under the MIT License. Open for industrial and research use.
Metadata
Release files for wkafka 1.4.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| wkafka-1.4.1.tar.gz | 18.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| wkafka-1.4.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 34.0 kB
Release files / wkafka-1.4.1.tar.gz
| Download URL | wkafka-1.4.1.tar.gz |
|---|---|
| Size | 18.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f547895904264cb9508cec6aa8efdcc7c274e4ec4524bbce8b09a424933a3b5d
|
|
BLAKE2b-256 checksum How to use checksums |
df8f4539f417f8e17e7ba107863ed238ef4a6ce955a38cc62da285ac47b08ab4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.8.0 CPython/3.12.3 Linux/6.17.0-29-generic
|
Release files / wkafka-1.4.1-py3-none-any.whl
| Download URL | wkafka-1.4.1-py3-none-any.whl |
|---|---|
| Size | 16.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7ddaad8a1b3114b933c0feeae8ecebc2f1121c5098680ac2d2800c03788ddd9e
|
|
BLAKE2b-256 checksum How to use checksums |
261c6d0f3792ab8b8b59cbcae822492042bbdfd3a39b3f129f5e252d2aaae738
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.8.0 CPython/3.12.3 Linux/6.17.0-29-generic
|
Security for wkafka 1.4.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.