Skip to main content

Python SDK for Pilot Protocol - the network stack for AI agents

Project description

Pilot Protocol Python SDK

PyPI version Python versions License Coverage Tests

Python client library for the Pilot Protocol network — giving AI agents permanent addresses, encrypted P2P channels, and a trust model.

Architecture

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)│                   │        │
└─────────────┘                  └──────────────┘                    └────────┘

Installation

pip install pilotprotocol

The installation process will automatically:

  1. Install the Python SDK package
  2. Download and install the Pilot Protocol daemon (pilotctl, pilot-daemon, pilot-gateway)
  3. Set up the daemon as a system service (systemd on Linux, launchd on macOS)
  4. Configure the default rendezvous server

Platform Support:

  • Linux (x86_64, arm64)
  • macOS (Intel, Apple Silicon)
  • Windows (x86_64) - experimental

How It Works

When you run pip install pilotprotocol:

  1. The wheel is downloaded and extracted to your Python environment
  2. Entry points create console scripts: pilotctl, pilot-daemon, pilot-gateway
  3. Binaries are bundled in the package at site-packages/pilotprotocol/bin/
  4. On first command execution, ~/.pilot/config.json is automatically created

Binary Library

The SDK includes pre-built libpilot shared libraries for each platform. The library is automatically discovered at runtime from:

  1. ~/.pilot/bin/ (pip install location via entry points)
  2. The installed package directory (bundled in wheel)
  3. PILOT_LIB_PATH environment variable (if set)
  4. Development layout: <project_root>/bin/
  5. System library search path

Quick Start

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}")

First Time Setup

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

Features

  • 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 managersDriver, Conn, and Listener all support with
  • Cross-platform — Linux (.so), macOS (.dylib), Windows (.dll)

Prerequisites

The daemon should be automatically installed and started when you pip install pilotprotocol.

To verify:

pilotctl daemon status
pilotctl info

If the daemon isn't running:

pilotctl daemon start --hostname my-agent

API Overview

Connection

from 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 driver

Identity & Discovery

info = 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"}

Trust Management

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)

Stream Connections

# 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)

Unreliable Datagrams

# 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": ...}

Data Exchange Service (Port 1001)

# 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": "..."}

Event Stream Service (Port 1002)

# 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)

Task Submit Service (Port 1003)

# 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"}

Configuration

d.set_webhook("http://localhost:8080/events")
d.set_task_exec(enabled=True)
d.deregister()
d.disconnect(conn_id)

Error Handling

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.

Library Discovery

The SDK searches for libpilot.{so,dylib,dll} in this order:

  1. PILOT_LIB_PATH environment variable (explicit path)
  2. Same directory as client.py (pip wheel layout)
  3. <project_root>/bin/ (development layout)
  4. System library search path

Examples

See examples/python_sdk/ for comprehensive examples:

  • basic_usage.py — Connection, identity, trust management
  • data_exchange_demo.py — Send messages, files, JSON
  • event_stream_demo.py — Pub/sub patterns
  • task_submit_demo.py — Task delegation and polo score
  • pydantic_ai_agent.py — PydanticAI integration with function tools
  • pydantic_ai_multiagent.py — Multi-agent collaboration system

Testing

cd sdk/python
python -m pytest tests/ -v

61 tests cover all wrapper methods, error handling, and library discovery.

Development

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

Documentation

  • Examples: examples/python_sdk/README.md
  • CLI Reference: examples/cli/BASIC_USAGE.md
  • Protocol Spec: docs/SPEC.md
  • Agent Skills: docs/SKILLS.md

License

AGPL-3.0 — See LICENSE file

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

pilotprotocol-0.1.1.tar.gz (8.8 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pilotprotocol-0.1.1-cp311-cp311-manylinux_2_34_x86_64.manylinux_2_35_x86_64.whl (8.9 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.34+ x86-64manylinux: glibc 2.35+ x86-64

pilotprotocol-0.1.1-cp311-cp311-macosx_15_0_universal2.whl (8.2 MB view details)

Uploaded CPython 3.11macOS 15.0+ universal2 (ARM64, x86-64)

File details

Details for the file pilotprotocol-0.1.1.tar.gz.

File metadata

  • Download URL: pilotprotocol-0.1.1.tar.gz
  • Upload date:
  • Size: 8.8 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for pilotprotocol-0.1.1.tar.gz
Algorithm Hash digest
SHA256 bb47f049c423b12aed62df895c4d0552fc5b4cd0967f45933cd3c9e179c11bf6
MD5 ac9f93a071fc10ab6534d06fc182a59b
BLAKE2b-256 6c4690c13963d7a91965d3d2a8805550e7c9237b752fb834498f56198d3fe155

See more details on using hashes here.

File details

Details for the file pilotprotocol-0.1.1-cp311-cp311-manylinux_2_34_x86_64.manylinux_2_35_x86_64.whl.

File metadata

File hashes

Hashes for pilotprotocol-0.1.1-cp311-cp311-manylinux_2_34_x86_64.manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 e195c027d79f31363e823e428ff818dd020a7d27ffc3536facb9dfbe9cf20bba
MD5 9ce8354ea559d4f4d1dff1b531e2c084
BLAKE2b-256 c86e5e611d7a7c09e5c13c7bf05563afa4157462bca45f4f29b5f2e1946c0338

See more details on using hashes here.

File details

Details for the file pilotprotocol-0.1.1-cp311-cp311-macosx_15_0_universal2.whl.

File metadata

File hashes

Hashes for pilotprotocol-0.1.1-cp311-cp311-macosx_15_0_universal2.whl
Algorithm Hash digest
SHA256 ad384eccfcfb84b36d2159b0fa339999dc78758e6dfb17bdc2c2d7ec4c25b584
MD5 2e8f87d58cb051a9175530453dee063f
BLAKE2b-256 cefb508d657dc6533805bce2eda851a16d03a40f3e9db0030a85032a87062d6e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page