Python implementation of the Cap'n Web protocol
Project description
Cap'n Web Python
A complete Python implementation of the Cap'n Web protocol - a capability-based RPC system with promise pipelining, structured errors, and multiple transport support.
What's in the Box
Core Features:
- Capability-based security - Unforgeable object references with explicit disposal
- Promise pipelining - Batch multiple dependent calls into single round-trips
- Multiple transports - HTTP Batch, WebSocket, and WebTransport/HTTP/3
- Type-safe - Full type hints compatible with pyright/mypy
- Async/await - Built on Python's asyncio
- Bidirectional RPC - Peer-to-peer capability passing
- 100% Interoperable - Fully compatible with TypeScript reference implementation
Beta-Testing-Ready":
- 352 tests passing, 76% coverage
- 0 linting errors, 0 typing errors
- Hook-based architecture (clean, maintainable)
- ~99% protocol compliance
Why Use Cap'n Web?
Traditional RPC has problems:
- No security model (anyone can call anything)
- No resource management (memory leaks)
- Poor performance (round-trip per call)
Cap'n Web solves these:
- Security: Capabilities are unforgeable - you can only call what you have a reference to
- Resource Management: Explicit disposal with reference counting prevents leaks
- Performance: Promise pipelining batches dependent calls into one round-trip
- Flexibility: Pass capabilities as arguments - the server decides who gets access
Installation
pip install capnweb
# or
uv add capnweb
# For WebTransport support (optional):
pip install capnweb[webtransport]
Quick Start
Server:
from capnweb.server import Server, ServerConfig
from capnweb.types import RpcTarget
from capnweb.error import RpcError
class Calculator(RpcTarget):
async def call(self, method: str, args: list) -> any:
match method:
case "add": return args[0] + args[1]
case "multiply": return args[0] * args[1]
case _: raise RpcError.not_found(f"Unknown method: {method}")
async def get_property(self, property: str) -> any:
raise RpcError.not_found("No properties")
async def main():
server = Server(ServerConfig(host="127.0.0.1", port=8080))
server.register_capability(0, Calculator())
await server.start()
await asyncio.Event().wait() # Run forever
Client:
from capnweb.client import Client, ClientConfig
async with Client(ClientConfig(url="http://localhost:8080/rpc/batch")) as client:
result = await client.call(0, "add", [5, 3])
print(f"5 + 3 = {result}") # Output: 8
Promise Pipelining (advanced):
async with Client(config) as client:
batch = client.pipeline()
# These calls are batched into a single HTTP request!
user = batch.call(0, "getUser", ["alice"])
profile = batch.call(0, "getProfile", [user.id]) # Property access on promise!
posts = batch.call(0, "getPosts", [user.id])
u, p, posts_data = await asyncio.gather(user, profile, posts)
Current Status (v0.4.0)
Transports:
- ✅ HTTP Batch
- ⚠️ WebSocket (partial support - client→server RPC only, bidirectional RPC in progress)
- ✅ WebTransport/HTTP/3 (requires aioquic)
Protocol Features:
- ✅ Wire protocol (all message types)
- ✅ Promise pipelining
- ✅ Expression evaluation (including
.map()) - ⚠️ Bidirectional RPC (HTTP Batch only, WebSocket support in progress)
- ✅ Resume tokens
- ✅ Reference counting
- ✅ Structured errors
- ⚠️ IL plan execution (only remap supported, full IL is low priority)
Code Quality:
- ✅ 352 tests passing (100% success rate)
- ✅ 76% test coverage
- ✅ 0 linting errors (ruff)
- ✅ 0 typing errors (pyrefly)
- ✅ TypeScript interoperability verified
Documentation
- Quickstart Guide - Get started in 5 minutes
- API Reference - Complete API documentation
- Architecture Guide - Understand the internals
- Examples - Working code examples
Examples
Included examples:
examples/calculator/- Simple RPC calculatorexamples/batch-pipelining/- Promise pipelining demonstrationexamples/peer_to_peer/- Bidirectional RPC (Alice & Bob) - HTTP Batch onlyexamples/chat/- ⚠️ Real-time WebSocket chat (requires bidirectional WebSocket - in progress)examples/microservices/- Service mesh architectureexamples/actor-system/- Distributed actor system with supervisor/workerexamples/webtransport/- WebTransport/HTTP/3 standalone demoexamples/webtransport-integrated/- WebTransport with full RPC
Each example includes a README with running instructions.
Transport Limitations
Current WebSocket Support:
- ✅ Client can connect to server via
ws://orwss://URLs - ✅ Client can call server methods (request-response RPC)
- ✅ Server can respond to client requests
- ❌ Server cannot initiate calls to clients (no bidirectional RPC yet)
- ❌ Chat example currently non-functional due to this limitation
Workaround for bidirectional RPC: Use HTTP Batch transport instead - it supports full bidirectional RPC including:
- Passing client capabilities to server
- Server calling methods on client capabilities
- See
examples/peer_to_peer/for working bidirectional RPC example
WebTransport:
- Full bidirectional support
- Requires
aioquiclibrary:pip install capnweb[webtransport]
Development
# Clone and install
git clone https://github.com/abilian/py-capnweb.git
cd py-capnweb
uv sync
# Run tests
pytest
# or
make test
# Run linting & type checking
ruff check
pyrefly check
# or
make check
# Run with coverage
pytest --cov=capnweb --cov-report=term-missing
Protocol Compliance
This implementation follows the Cap'n Web protocol specification.
Interoperability Testing: Cross-implementation testing with TypeScript reference validates all combinations:
- Python Server ↔ Python Client ✅
- Python Server ↔ TypeScript Client ✅
- TypeScript Server ↔ Python Client ✅
- TypeScript Server ↔ TypeScript Client ✅
Run interop tests: cd interop && bash run_tests.sh
What's New
See CHANGES.md for detailed release notes.
v0.4.0 (latest):
- WebTransport/HTTP/3 support with certificate management
- Actor system example with distributed capabilities
- "Perfect" code quality (0 linting errors, 0 typing errors)
- 352 tests passing
v0.3.1:
- Comprehensive documentation (quickstart, architecture, API reference)
- 85% test coverage (up from 67%)
- Legacy code removed (clean hook-based architecture)
v0.3.0:
- Promise pipelining support
- 100% TypeScript interoperability
- Array escaping for compatibility
License
Dual-licensed under MIT or Apache-2.0, at your option.
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 py_capnweb-0.5.0.tar.gz.
File metadata
- Download URL: py_capnweb-0.5.0.tar.gz
- Upload date:
- Size: 55.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
57418b63b0f9d0885aa6da3d42a995a8bfa97188355f1fca37abc57deee73977
|
|
| MD5 |
3b188f0a3b2d5a7086c5fd23c690a1a2
|
|
| BLAKE2b-256 |
47844dabd64f3cec1fd33451c2c0095ba1ca6564760cfd83a8e1d2487dcf0bf5
|
File details
Details for the file py_capnweb-0.5.0-py3-none-any.whl.
File metadata
- Download URL: py_capnweb-0.5.0-py3-none-any.whl
- Upload date:
- Size: 65.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b5b03a2c4d9f92e1756e0f37d812659fae5a29431b4b1a41e9c52568aa6eafd0
|
|
| MD5 |
630a3d16d3e029ffc44d43e53ac2a0ee
|
|
| BLAKE2b-256 |
e544aecfb56b9eeb93e37c534884e9c771f81d50e4c6060674b5211cf85eed2a
|