A Python client for the Jolt in-memory messaging broker
Project description
A fast, lightweight Python client for the Jolt in-memory messaging broker.
This is a Python port of the jolt-java-api, providing identical functionality with a Pythonic interface.
- Plain TCP + NDJSON (newline-delimited JSON)
- No external dependencies (standard library only)
- Supports:
auth- Authenticationsub/unsub- Subscribe/Unsubscribe to topicspub- Publish messagesping- Keep-alive
- Designed for low latency and high throughput
1. Requirements
- Python 3.7 or newer
- A running Jolt server (the Go broker):
- Example:
./broker -config=config.json - Default port:
8080(unless changed inconfig.json)
- Example:
2. Installation
From source:
git clone https://github.com/DevArqf/jolt-python-api.git
cd jolt-python-api
pip install -e .
Using pip:
pip install jolt-python-api
3. Project Structure
jolt-python-api/
├── src/
│ └── jolt/
│ ├── __init__.py
│ ├── client.py # Main JoltClient class
│ ├── config.py # JoltConfig and builder
│ ├── handler.py # JoltMessageHandler abstract class
│ ├── request.py # JoltRequestBuilder
│ ├── response.py # Response parsers and models
│ └── exceptions.py # JoltException
├── examples/
│ └── simple_example.py
├── tests/
├── setup.py
├── README.md
└── requirements.txt
4. Quick Start
4.1 Basic Usage
from jolt import JoltClient, JoltConfig, JoltMessageHandler
from jolt import JoltErrorResponse, JoltTopicMessage
from typing import Optional
# 1. Configure connection
config = JoltConfig.new_builder() \
.host("127.0.0.1") \
.port(8080) \
.build()
# 2. Define message handler
class MyHandler(JoltMessageHandler):
def on_ok(self, raw_line: str):
print(f"[OK] {raw_line}")
def on_error(self, error: JoltErrorResponse, raw_line: str):
print(f"[ERROR] {error.get_error()}")
def on_topic_message(self, msg: JoltTopicMessage, raw_line: str):
print(f"[MSG] {msg.get_topic()} -> {msg.get_data()}")
def on_disconnected(self, cause: Optional[Exception]):
print(f"[DISCONNECTED] {cause if cause else 'closed'}")
# 3. Create and connect client
handler = MyHandler()
client = JoltClient(config, handler)
client.connect()
# 4. Authenticate (if server requires it)
client.auth("username", "password")
# 5. Subscribe and publish
client.subscribe("chat.room1")
client.publish("chat.room1", "Hello from Python!")
# 6. Ping server
client.ping()
# 7. Clean shutdown
client.close()
4.2 Complete Example
import time
from jolt import JoltClient, JoltConfig, JoltMessageHandler
from jolt import JoltErrorResponse, JoltTopicMessage
from typing import Optional
class ChatHandler(JoltMessageHandler):
def on_ok(self, raw_line: str):
print(f"✓ Operation successful")
def on_error(self, error: JoltErrorResponse, raw_line: str):
print(f"✗ Error: {error.get_error()}")
def on_topic_message(self, msg: JoltTopicMessage, raw_line: str):
print(f"📩 [{msg.get_topic()}] {msg.get_data()}")
def on_disconnected(self, cause: Optional[Exception]):
if cause:
print(f"⚠ Disconnected: {cause}")
else:
print("👋 Connection closed")
def main():
# Setup
config = JoltConfig.new_builder() \
.host("127.0.0.1") \
.port(8080) \
.build()
handler = ChatHandler()
client = JoltClient(config, handler)
try:
# Connect
print("🔌 Connecting to Jolt server...")
client.connect()
print("✓ Connected!")
# Auth (if needed)
# client.auth("jolt-chat", "password123")
# Subscribe to topics
client.subscribe("chat.general")
client.subscribe("notifications")
# Publish some messages
client.publish("chat.general", "Hello, everyone!")
client.publish("chat.general", "This is from Python!")
# Keep running to receive messages
print("\n📡 Listening for messages (Ctrl+C to exit)...")
while True:
time.sleep(1)
except KeyboardInterrupt:
print("\n\n👋 Shutting down...")
finally:
client.close()
if __name__ == "__main__":
main()
5. API Reference
JoltConfig
Configuration object for the Jolt client.
# Using builder pattern
config = JoltConfig.new_builder() \
.host("127.0.0.1") \
.port(8080) \
.build()
# Direct instantiation
config = JoltConfig(host="127.0.0.1", port=8080)
Methods:
get_host()→str: Get the server hostget_port()→int: Get the server port
JoltClient
Main client for interacting with the Jolt broker.
Constructor:
client = JoltClient(config: JoltConfig, handler: JoltMessageHandler)
Methods:
connect(): Connect to the Jolt serverauth(username: str, password: str): Authenticate with the serversubscribe(topic: str): Subscribe to a topicunsubscribe(topic: str): Unsubscribe from a topicpublish(topic: str, data: str): Publish a message to a topicping(): Send a ping to the serverclose(): Close the connectionis_connected()→bool: Check connection status
JoltMessageHandler
Abstract base class for handling server messages. Implement all methods:
class MyHandler(JoltMessageHandler):
def on_ok(self, raw_line: str):
"""Called when receiving an OK response"""
pass
def on_error(self, error: JoltErrorResponse, raw_line: str):
"""Called when receiving an error response"""
pass
def on_topic_message(self, msg: JoltTopicMessage, raw_line: str):
"""Called when receiving a message on a subscribed topic"""
pass
def on_disconnected(self, cause: Optional[Exception]):
"""Called when disconnected from the server"""
pass
JoltTopicMessage
Represents a message received on a subscribed topic.
Methods:
get_topic()→str: Get the topic nameget_data()→str: Get the message data
JoltErrorResponse
Represents an error response from the server.
Methods:
get_error()→str: Get the error message
JoltException
Exception raised for Jolt client errors.
6. Comparison with Java API
This Python implementation maintains feature parity with the Java API:
| Feature | Java API | Python API |
|---|---|---|
| TCP Connection | ✅ | ✅ |
| NDJSON Protocol | ✅ | ✅ |
| Auth | ✅ | ✅ |
| Subscribe/Unsubscribe | ✅ | ✅ |
| Publish | ✅ | ✅ |
| Ping | ✅ | ✅ |
| Message Handler | ✅ | ✅ |
| Thread-safe Writing | ✅ | ✅ |
| Background Reader | ✅ | ✅ |
| No Dependencies | ✅ | ✅ |
API Naming Conventions:
The Python API follows Pythonic naming while maintaining similar structure:
- Java:
JoltConfig.newBuilder()→ Python:JoltConfig.new_builder() - Java:
error.getError()→ Python:error.get_error() - Java:
msg.getTopic()→ Python:msg.get_topic()
7. Advanced Usage
Multiple Topics
topics = ["news", "sports", "weather"]
for topic in topics:
client.subscribe(topic)
# Publish to different topics
client.publish("news", "Breaking: Python API released!")
client.publish("sports", "Game score: 3-2")
Topic-Specific Handlers
class SmartHandler(JoltMessageHandler):
def on_topic_message(self, msg: JoltTopicMessage, raw_line: str):
topic = msg.get_topic()
data = msg.get_data()
if topic.startswith("alert."):
print(f"🚨 ALERT: {data}")
elif topic.startswith("chat."):
print(f"💬 Chat: {data}")
else:
print(f"📨 {topic}: {data}")
Reconnection Logic
import time
class ReconnectingHandler(JoltMessageHandler):
def __init__(self, client):
self.client = client
self.should_reconnect = True
def on_disconnected(self, cause: Optional[Exception]):
print(f"Disconnected: {cause}")
if self.should_reconnect:
print("Attempting to reconnect...")
time.sleep(5)
try:
self.client.connect()
print("Reconnected!")
except Exception as e:
print(f"Reconnection failed: {e}")
8. Notes
- This API does not provide TLS. To secure transport:
- Run Jolt behind a TLS-terminating proxy (e.g. Nginx, HAProxy), or
- Use OS-level tunnels (SSH, VPN)
- All JSON is handled using Python's built-in
jsonmodule - The client uses a single background thread for reading and a thread-safe writer
- Messages are automatically framed with newlines (NDJSON format)
9. Testing
Run tests (when implemented):
pytest tests/
Run with coverage:
pytest --cov=jolt tests/
10. Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
11. License
MIT License
Copyright (c) 2025 DevArqf
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12. Credits
This is a Python port of the jolt-java-api created for the Jolt Database project.
13. Support
For issues, questions, or contributions:
- Open an issue
- Contact the Jolt Database team
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jolt_python_api-1.2.1.tar.gz.
File metadata
- Download URL: jolt_python_api-1.2.1.tar.gz
- Upload date:
- Size: 8.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b2051236722508f12346f7fc24c43c36df5002fce060231c36ebecd49973cd06
|
|
| MD5 |
99dbee889cf1c62c2679c11faa85922c
|
|
| BLAKE2b-256 |
076e2eae6b8e1947f4ebf87e77328c67caf8587ac0b1b9db976e00cc7646497e
|
File details
Details for the file jolt_python_api-1.2.1-py3-none-any.whl.
File metadata
- Download URL: jolt_python_api-1.2.1-py3-none-any.whl
- Upload date:
- Size: 10.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4205a649bcc59fd67014420232b4d0a1d298fdaca51b551dd9e14e81b8e48219
|
|
| MD5 |
5aff39e4622eda5eb004b505703925ed
|
|
| BLAKE2b-256 |
32e3a63733b690642ea428d936e66fa0f1322d9144fa0821869e49b39b584627
|