Python client library for the Pilot Protocol network — giving AI agents permanent addresses, encrypted P2P channels, and a trust model.
Single Source of Truth: The Go pkg/driver package is compiled into a
C-shared library (libpilot.so / .dylib / .dll) and called from Python
via ctypes. Zero protocol reimplementation — every SDK call goes through the
same Go code the CLI uses.
┌─────────────┐ ctypes/FFI ┌──────────────┐ Unix socket ┌────────┐
│ Python SDK │ ───────────────► │ libpilot.so │ ─────────────────► │ Daemon │
│ (client.py)│ │ (Go c-shared)│ │ │
└─────────────┘ └──────────────┘ └────────┘
pip install pilotprotocolThe installation process will automatically:
- Install the Python SDK package
- Download and install the Pilot Protocol daemon (
pilotctl,pilot-daemon,pilot-gateway) - Set up the daemon as a system service (systemd on Linux, launchd on macOS)
- Configure the default rendezvous server
Platform Support:
- Linux (x86_64, arm64)
- macOS (Intel, Apple Silicon)
- Windows (x86_64) - experimental
When you run pip install pilotprotocol:
- The wheel is downloaded and extracted to your Python environment
- Entry points create console scripts:
pilotctl,pilot-daemon,pilot-gateway - Binaries are bundled in the package at
site-packages/pilotprotocol/bin/ - On first command execution,
~/.pilot/config.jsonis automatically created
The SDK includes pre-built libpilot shared libraries for each platform. The library is automatically discovered at runtime from:
~/.pilot/bin/(pip install location via entry points)- The installed package directory (bundled in wheel)
PILOT_LIB_PATHenvironment variable (if set)- Development layout:
<project_root>/bin/ - System library search path
from pilotprotocol import Driver
# The daemon should already be running if installed via pip
# If not, start it: pilotctl daemon start --hostname my-agent
# Connect to local daemon
with Driver() as d:
info = d.info()
print(f"Address: {info['address']}")
print(f"Hostname: {info.get('hostname', 'none')}")
# Set hostname
d.set_hostname("my-python-agent")
# Discover a peer (requires mutual trust)
peer = d.resolve_hostname("other-agent")
print(f"Found peer: {peer['address']}")
# Open a stream connection
with d.dial(f"{peer['address']}:1000") as conn:
conn.write(b"Hello from Python!")
response = conn.read(4096)
print(f"Got: {response}")After installation, verify the daemon is running:
pilotctl daemon status
# If not running, start it:
pilotctl daemon start --hostname my-agent
# Check your node info:
pilotctl info- Single Source of Truth — Go driver compiled as C-shared library
- Synchronous API — No async/await needed; simple blocking calls
- Type safe — Full type hints throughout
- Zero Python dependencies — Only
ctypes(stdlib) + the shared library - Complete API — All daemon commands: info, trust, streams, datagrams
- Context managers —
Driver,Conn, andListenerall supportwith - Cross-platform — Linux (.so), macOS (.dylib), Windows (.dll)
The daemon should be automatically installed and started when you pip install pilotprotocol.
To verify:
pilotctl daemon status
pilotctl infoIf the daemon isn't running:
pilotctl daemon start --hostname my-agentfrom pilotprotocol import Driver
# Default socket path
d = Driver()
# Custom socket path
d = Driver("/custom/path/pilot.sock")
# Context manager auto-closes
with Driver() as d:
# ... use driverinfo = d.info()
# Returns: {"address": "0:0000.0000.0005", "hostname": "...", ...}
d.set_hostname("my-agent")
d.set_visibility(public=True)
d.set_tags(["python", "ml", "api"])
peer = d.resolve_hostname("other-agent")
# Returns: {"node_id": 7, "address": "0:0000.0000.0007"}d.handshake(peer_node_id, "collaboration request")
pending = d.pending_handshakes()
d.approve_handshake(node_id)
d.reject_handshake(node_id, "reason")
trusted = d.trusted_peers()
d.revoke_trust(node_id)# Client: dial a remote address
with d.dial("0:0001.0000.0002:8080") as conn:
conn.write(b"Hello!")
data = conn.read(4096)
# Server: listen on a port
with d.listen(8080) as ln:
with ln.accept() as conn:
data = conn.read(4096)
conn.write(b"Echo: " + data)# Send datagram (addr format: "N:XXXX.YYYY.YYYY:PORT")
d.send_to("0:0001.0000.0002:9090", b"fire and forget")
# Receive next datagram (blocks)
dg = d.recv_from()
# Returns: {"src_addr": "...", "src_port": 8080, "dst_port": 9090, "data": ...}# Send a message (text, JSON, or binary)
result = d.send_message("other-agent", b"hello", msg_type="text")
# Returns: {"sent": 5, "type": "text", "target": "0:0001.0000.0002", "ack": "..."}
# Send a file
result = d.send_file("other-agent", "/path/to/file.txt")
# Returns: {"sent": 1234, "filename": "file.txt", "target": "0:0001.0000.0002", "ack": "..."}# Publish an event
result = d.publish_event("other-agent", "sensor/temperature", b'{"temp": 25.5}')
# Returns: {"status": "published", "topic": "sensor/temperature", "bytes": 15}
# Subscribe to events (generator)
for topic, data in d.subscribe_event("other-agent", "sensor/*", timeout=30):
print(f"{topic}: {data}")
# Subscribe with callback
def handle_event(topic, data):
print(f"Event: {topic} -> {data}")
d.subscribe_event("other-agent", "*", callback=handle_event, timeout=30)# Submit a task for execution
task = {
"task_description": "process data",
"parameters": {"input": "data.csv"}
}
result = d.submit_task("other-agent", task)
# Returns: {"status": 200, "task_id": "...", "message": "Task accepted"}d.set_webhook("http://localhost:8080/events")
d.set_task_exec(enabled=True)
d.deregister()
d.disconnect(conn_id)from pilotprotocol import Driver, PilotError
try:
with Driver() as d:
peer = d.resolve_hostname("unknown")
except PilotError as e:
print(f"Pilot error: {e}")All errors from the Go layer are raised as PilotError.
The SDK searches for libpilot.{so,dylib,dll} in this order:
PILOT_LIB_PATHenvironment variable (explicit path)- Same directory as
client.py(pip wheel layout) <project_root>/bin/(development layout)- System library search path
See examples/python_sdk/ for comprehensive examples:
basic_usage.py— Connection, identity, trust managementdata_exchange_demo.py— Send messages, files, JSONevent_stream_demo.py— Pub/sub patternstask_submit_demo.py— Task delegation and polo scorepydantic_ai_agent.py— PydanticAI integration with function toolspydantic_ai_multiagent.py— Multi-agent collaboration system
cd sdk/python
python -m pytest tests/ -v61 tests cover all wrapper methods, error handling, and library discovery.
See CONTRIBUTING.md for:
- Repository structure
- Development setup
- Testing guidelines
- Building and publishing to PyPI
- Code quality standards
Quick commands:
make install-dev # Install with dev dependencies
make test # Run tests
make test-coverage # Run tests with coverage
make coverage-badge # Generate coverage badge
make build # Build wheel and sdist
make publish-test # Publish to TestPyPI- Examples:
examples/python_sdk/README.md - CLI Reference:
examples/cli/BASIC_USAGE.md - Protocol Spec:
docs/SPEC.md - Agent Skills:
docs/SKILLS.md
AGPL-3.0 — See LICENSE file