A minimalist real-time messaging platform
Project description
A minimalist real-time messaging service.
Chalk is a lightweight messaging service built on WebSocket. It provides group chats, direct messages, and real-time event delivery - nothing more, nothing less.
What is Chalk?
Chalk is a messaging service, Think of it as a simple, self-hosted alternative to Slack or Discord, designed for programmatic use.
What Chalk provides:
- Real-time messaging via WebSocket
- Group chats and direct messages
- Message history and persistence
- Event-driven message handling
- User authentication
What Chalk does NOT provide:
- AI/LLM capabilities
- Agent orchestration
- Task scheduling
- Business logic
Chalk is infrastructure. You build whatever you want on top of it.
Core Features
Minimalist API
Start a server in 2 lines, connect a client in 3:
# Server
from chalk.server import ChalkServer
server = ChalkServer(
redis_url="redis://localhost:6379", # Redis for pub/sub
db_path="chalk.db", # SQLite for data persistence
host="0.0.0.0", # Listen on all interfaces
port=8000 # Server port
)
server.run()
# Client
from chalk.client import Client
alice = Client(
name="alice",
password="password123",
server="localhost:8000" # Server address
)
chat = await alice.create_group_chat("My Chat")
await chat.send("Hello!")
Real-Time Messaging
- WebSocket-based: Instant bidirectional communication
- Event-driven: React to messages with decorators
- Persistent: Full message history in SQLite
- Reliable: Auto-reconnect on network issues
Group & Direct Chats
- Group chats: Multi-party conversations, unlimited members
- Direct messages: 1-on-1 private chats
- Message history: Query past messages anytime
- Member management: Add/remove members dynamically
Quick Start
Installation
pip install chalks
1. Start the Server
from chalk.server import ChalkServer
server = ChalkServer(
redis_url="redis://localhost:6379", # Redis for pub/sub
db_path="chalk.db" # SQLite for data persistence
)
server.run()
Prerequisites:
- Redis must be running:
redis-server
2. Send Your First Message
import asyncio
from chalk.client import Client
async def main():
# Create client
alice = Client("alice", "password123")
# Create a group chat
chat = await alice.create_group_chat("My First Chat")
await chat.send("Hello world!")
print(f"Chat created: {chat.id}")
asyncio.run(main())
3. Receive Messages
# Bob joins the same chat
bob = Client("bob", "password456")
# Register message handler
@bob.on("message")
async def handle_message(msg):
print(f"{msg.sender.name}: {msg.content}")
# Join Alice's chat
await bob.join_chat(chat.id)
# Bob receives all messages in real-time
await asyncio.Event().wait()
Core Concepts
Client
Represents a user or agent in the system:
alice = Client(
name="alice", # Username
password="pass123", # Password (auto-registers if new)
bio="AI assistant", # Optional bio
server="localhost:8000" # Server address
)
Chat
Two types of chats:
Group Chat - Multi-party conversations:
# Create group
chat = await alice.create_group_chat("Team Chat")
# Add members
await chat.add_member(bob_id)
await chat.add_member(charlie_id)
# Multiple members can join
Direct Chat - 1-on-1 conversations:
# Create direct chat with Bob
dm = await alice.create_direct_chat(bob_id)
Message
Messages with rich metadata:
@client.on("message")
async def handle(msg):
print(f"From: {msg.sender.name}")
print(f"Content: {msg.content}")
print(f"Time: {msg.timestamp}")
# Reply to message
await msg.reply("Got it!")
# Get chat context
chat = await msg.get_chat()
members = await chat.get_members()
Common Patterns
Chat Management
# List all chats
chats = await client.list_chats()
# Filter by type
group_chats = [c for c in chats if c.is_group()]
direct_chats = [c for c in chats if c.is_direct()]
# Get chat details
chat = await client.get_chat(chat_id)
members = await chat.get_members()
messages = await chat.get_messages(limit=50)
# Join/leave
await client.join_chat(chat_id)
await client.leave_chat(chat_id)
API Reference
Client Methods
| Method | Description |
|---|---|
create_group_chat(name, members=[]) |
Create a group chat |
create_direct_chat(user_id) |
Create/get 1-on-1 chat |
list_chats() |
List all chats |
get_chat(chat_id) |
Get chat details |
join_chat(chat_id) |
Join a chat |
whois(username) |
Find users by name |
stop() |
Disconnect client |
Chat Methods
| Method | Description |
|---|---|
send(content) |
Send a message |
get_messages(limit=50) |
Get message history |
get_members() |
Get chat members |
is_group() |
Check if group chat |
is_direct() |
Check if direct chat |
Message Methods
| Method | Description |
|---|---|
reply(content) |
Reply to this message |
get_chat() |
Get the chat this message belongs to |
get_sender() |
Get sender details |
Examples
comming soon...
Architecture
┌─────────────────┐ ┌─────────────────┐
│ Agent/Human │ │ Agent/Human │
│ (Client SDK) │ │ (Client SDK) │
└────────┬────────┘ └────────┬────────┘
│ │
│ WebSocket + HTTP │
│ │
└───────────┬───────────────┘
│
┌───────────▼────────────┐
│ Chalk Server │
│ (FastAPI + WebSocket) │
└───────────┬────────────┘
│
┌───────────┴───────────┐
│ │
┌────▼─────┐ ┌─────▼────┐
│ Redis │ │ SQLite │
│ (Pub/Sub)│ │ (Data) │
└──────────┘ └──────────┘
Tech Stack:
- Server: FastAPI + Uvicorn
- Real-time: WebSocket + Redis Pub/Sub
- Storage: SQLite (Peewee ORM)
- Client: httpx + websockets
- Tasks: Huey (async task queue)
Is Chalk for You?
Use Chalk if you need:
- Real-time messaging infrastructure without the bloat
- WebSocket-based communication that's easy to integrate
- Self-hosted messaging (no third-party dependencies)
- Simple API that gets out of your way
- Group chats and DMs with message persistence
Chalk does one thing: messaging. It does it well.
License
MIT License - see LICENSE file for details.
Contributing
Contributions welcome! Please open an issue or PR.
Project details
Release history Release notifications | RSS feed
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 chalks-0.1.0.tar.gz.
File metadata
- Download URL: chalks-0.1.0.tar.gz
- Upload date:
- Size: 36.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ad4f6b65b6462fe6b8bed557fb475519afa6b16cf5ab05e5466772f4a8c90601
|
|
| MD5 |
bce86ca85f1b2a1cb9bdaa29f555a28a
|
|
| BLAKE2b-256 |
d2dcc89db9723be9fdd87226864a8267c90fedd9c4a75dc0ce4d09c5d9cf23a9
|
Provenance
The following attestation bundles were made for chalks-0.1.0.tar.gz:
Publisher:
publish.yml on zhixiangxue/chalk-ai
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chalks-0.1.0.tar.gz -
Subject digest:
ad4f6b65b6462fe6b8bed557fb475519afa6b16cf5ab05e5466772f4a8c90601 - Sigstore transparency entry: 728006304
- Sigstore integration time:
-
Permalink:
zhixiangxue/chalk-ai@4ee72b2fb1db9b39388160a835b211b87e0843ba -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/zhixiangxue
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4ee72b2fb1db9b39388160a835b211b87e0843ba -
Trigger Event:
release
-
Statement type:
File details
Details for the file chalks-0.1.0-py3-none-any.whl.
File metadata
- Download URL: chalks-0.1.0-py3-none-any.whl
- Upload date:
- Size: 41.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
495c3610811bafd236d0afa580049485344c2182f93f8af17c536a9b29abf360
|
|
| MD5 |
b7ad3acf7f0bf5bc949129bd2d7f8793
|
|
| BLAKE2b-256 |
5e85de8bbbce828b1986313fe634db4022fd0137a75ee7533eb56f04e9eab8e3
|
Provenance
The following attestation bundles were made for chalks-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on zhixiangxue/chalk-ai
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chalks-0.1.0-py3-none-any.whl -
Subject digest:
495c3610811bafd236d0afa580049485344c2182f93f8af17c536a9b29abf360 - Sigstore transparency entry: 728006305
- Sigstore integration time:
-
Permalink:
zhixiangxue/chalk-ai@4ee72b2fb1db9b39388160a835b211b87e0843ba -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/zhixiangxue
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4ee72b2fb1db9b39388160a835b211b87e0843ba -
Trigger Event:
release
-
Statement type: