Skip to main content

Python SDK providing high-level bindings to the Northroot Engine. Record work, verify receipts, and manage proof storage with simple async/sync APIs.

Project description

Northroot Python SDK

Python SDK for the Northroot proof algebra system, providing high-level Python bindings to the Rust engine.

Features

  • Minimal API (v0.1): Simple record_work and verify_receipt functions for verifiable proofs
  • Receipt Storage: Filesystem-based storage with querying and filtering
  • Async/Sync Support: Both synchronous and asynchronous APIs available
  • OpenTelemetry Integration: Optional OTEL span → receipt conversion
  • Delta Compute: Reuse decision logic, Jaccard similarity, economic delta computation
  • Data Shapes: Compute data and method shape hashes from files, bytes, or signatures

Installation

From PyPI (Recommended)

pip install northroot

From Source (Development)

# Quick setup (recommended)
cd sdk/python/northroot
./setup-dev.sh

# Or manual setup
pip install maturin
cd sdk/python/northroot
maturin develop

Quick Start

Minimal API (v0.1)

from northroot import Client

# Create a client (storage is optional)
client = Client()
# client = Client(storage_path="./receipts")  # With filesystem storage

# Record a unit of work and get a verifiable receipt
receipt = client.record_work(
    workload_id="normalize-prices",
    payload={"input_hash": "sha256:abc...", "output_hash": "sha256:def..."},
    tags=["etl", "batch"],
    trace_id="trace-2025-01-17",
)

print(f"Receipt ID: {receipt.get_rid()}")
print(f"Hash: {receipt.get_hash()}")

# Verify receipt integrity
is_valid = client.verify_receipt(receipt)
print(f"Receipt is valid: {is_valid}")

# Store receipt (if storage_path was provided)
client.store_receipt(receipt)

# List receipts with filtering
receipts = client.list_receipts(
    workload_id="normalize-prices",
    trace_id="trace-2025-01-17",
    limit=10
)

# Async versions are also available
receipt_async = await client.record_work_async(...)
is_valid_async = await client.verify_receipt_async(receipt_async)

See examples/quickstart.py for a complete example.

Usage Examples

Receipt Storage and Querying

from northroot import Client

client = Client(storage_path="./receipts")

# Record and store receipts
receipt1 = client.record_work("workload-1", {"data": "value1"})
client.store_receipt(receipt1)

receipt2 = client.record_work("workload-1", {"data": "value2"}, trace_id="trace-123")
client.store_receipt(receipt2)

# Query receipts
all_receipts = client.list_receipts()
workload_receipts = client.list_receipts(workload_id="workload-1")
trace_receipts = client.list_receipts(trace_id="trace-123")

OpenTelemetry Integration

from northroot import Client
from northroot.otel import trace_work, span_to_receipt
from opentelemetry import trace

client = Client()

# Option 1: Decorator
@trace_work(client, workload_id="my-workload")
def my_function():
    # Your code here
    return {"result": "data"}

# Option 2: Manual conversion
tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span("my-operation") as span:
    # Your code here
    receipt = span_to_receipt(span, client, "my-workload", {"data": "value"})

See examples/otel_integration.py for more examples.

Delta Compute

import northroot as nr

# Decide whether to reuse based on overlap
cost_model = {
    "c_id": 10.0,  # Identity cost
    "c_comp": 100.0,  # Compute cost
    "alpha": 0.9,  # Incrementality factor
}
overlap_j = 0.15  # 15% Jaccard overlap

result = nr.delta.decide_reuse(overlap_j, cost_model)
print(f"Decision: {result['decision']}")  # "reuse" or "recompute"

# Compute economic delta (savings estimate)
delta = nr.delta.economic_delta(overlap_j, cost_model)
print(f"Economic delta: {delta}")  # Positive = savings

# Compute Jaccard similarity between two sets
set1 = ["chunk1", "chunk2", "chunk3"]
set2 = ["chunk2", "chunk3", "chunk4"]
jaccard = nr.delta.jaccard_similarity(set1, set2)
print(f"Jaccard similarity: {jaccard}")  # 0.5 (2/4)

Data Shapes

import northroot as nr

# Compute data shape hash from file
hash1 = nr.shapes.compute_data_shape_hash_from_file(
    "data.csv",
    chunk_scheme={"type": "cdc", "avg_size": 65536}
)

# Compute data shape hash from bytes
data = b"some binary data"
hash2 = nr.shapes.compute_data_shape_hash_from_bytes(
    data,
    chunk_scheme={"type": "fixed", "size": 1024}
)

# Compute method shape hash from code hash
code_hash = "sha256:abc123..."
method_hash = nr.shapes.compute_method_shape_hash_from_code(
    code_hash,
    params={"batch_size": 1000}
)

Development

Prerequisites

  • Rust toolchain (latest stable)
  • Python 3.10+ (3.12 recommended)
  • maturin

Quick Setup

cd sdk/python/northroot
./setup-dev.sh

This creates a virtual environment, installs dependencies, and builds the package.

Manual Setup

cd sdk/python/northroot

# Create virtual environment
python3 -m venv venv
source venv/bin/activate

# Install development dependencies
pip install -e ".[dev]"

# Build in development mode
maturin develop

Development Workflow

# Activate environment
cd sdk/python/northroot
source venv/bin/activate

# Rebuild after code changes
maturin develop
# Or use make
make develop

# Run examples
./run-example.sh
# Or manually
python examples/quickstart.py

# Build release wheels
maturin build --release

# Run tests
pytest tests/

# Format code
black .

# Type check
mypy .

Helper Scripts

  • setup-dev.sh - One-command development environment setup
  • run-example.sh - Run examples with proper environment activation
  • Makefile - Convenience targets for common tasks

Troubleshooting

Build fails with "missing field package":

  • Make sure you're in sdk/python/northroot directory
  • The Cargo.toml should have [package] section, not [workspace]

Import errors:

  • Activate venv: source venv/bin/activate
  • Rebuild: maturin develop
  • Check that northroot/__init__.py exists

Rust compilation errors:

  • Make sure Rust toolchain is installed: rustc --version
  • Update Rust: rustup update
  • Clean and rebuild: cargo clean && maturin develop

API Reference

Client Class

  • Client(storage_path: Optional[str] = None) - Create a new client
  • record_work(workload_id: str, payload: Dict, tags: Optional[List[str]] = None, trace_id: Optional[str] = None, parent_id: Optional[str] = None) -> PyReceipt
  • verify_receipt(receipt: PyReceipt) -> bool
  • store_receipt(receipt: PyReceipt) -> None
  • list_receipts(workload_id: Optional[str] = None, trace_id: Optional[str] = None, limit: Optional[int] = None) -> List[PyReceipt]
  • record_work_async(...) - Async version of record_work
  • verify_receipt_async(...) - Async version of verify_receipt
  • list_receipts_async(...) - Async version of list_receipts

Delta Module

  • decide_reuse(overlap_j: float, cost_model: dict, row_count: int | None = None) -> dict
  • economic_delta(overlap_j: float, cost_model: dict, row_count: int | None = None) -> float
  • jaccard_similarity(set1: list[str], set2: list[str]) -> float

Shapes Module

  • compute_data_shape_hash_from_file(path: str, chunk_scheme: dict | None = None) -> str
  • compute_data_shape_hash_from_bytes(data: bytes, chunk_scheme: dict | None = None) -> str
  • compute_method_shape_hash_from_code(code_hash: str, params: dict | None = None) -> str
  • compute_method_shape_hash_from_signature(function_name: str, input_types: list[str], output_type: str) -> str

Receipts Module

  • receipt_from_json(json_str: str) -> PyReceipt

PyReceipt Class

  • validate() -> None - Validate receipt (raises ValueError if invalid)
  • compute_hash() -> str - Compute hash from canonical body
  • to_json() -> str - Serialize receipt to JSON string
  • get_rid() -> str - Get receipt ID (RID)
  • get_kind() -> str - Get receipt kind
  • get_version() -> str - Get receipt version
  • get_hash() -> str - Get receipt hash

Architecture

This SDK provides Python bindings to the Rust northroot-engine crate via PyO3.

  • SDK Location: sdk/python/northroot/ (not crates/)
  • Core Engine: crates/northroot-engine/ (Rust)
  • Clear Boundaries: SDK = language bindings, Engine = core logic

Status

v0.1.0 (Alpha) - This SDK is in early development. API may change.

What's New in v0.1.0

  • ✅ Minimal API: record_work() and verify_receipt() for verifiable proofs
  • ✅ Receipt storage and listing with filtering (workload_id, trace_id)
  • ✅ Async/sync support for all operations
  • ✅ OpenTelemetry integration (optional)
  • ✅ Filesystem-based receipt storage

License

Apache 2.0

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

northroot-0.1.1.tar.gz (182.7 kB view details)

Uploaded Source

Built Distributions

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

northroot-0.1.1-cp38-abi3-win_amd64.whl (492.2 kB view details)

Uploaded CPython 3.8+Windows x86-64

northroot-0.1.1-cp38-abi3-manylinux_2_34_x86_64.whl (614.9 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.34+ x86-64

northroot-0.1.1-cp38-abi3-macosx_11_0_arm64.whl (555.4 kB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

File details

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

File metadata

  • Download URL: northroot-0.1.1.tar.gz
  • Upload date:
  • Size: 182.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for northroot-0.1.1.tar.gz
Algorithm Hash digest
SHA256 4c93508cfb3ced27d0a75246e55ef2e6bf79d78bc6df4fea65d553193d3c1aa2
MD5 69dbf47533a1695f31c1350d8714f940
BLAKE2b-256 02d413e8950f016664942140cd82728810c698867ca520a1d78714f4492c366d

See more details on using hashes here.

File details

Details for the file northroot-0.1.1-cp38-abi3-win_amd64.whl.

File metadata

  • Download URL: northroot-0.1.1-cp38-abi3-win_amd64.whl
  • Upload date:
  • Size: 492.2 kB
  • Tags: CPython 3.8+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for northroot-0.1.1-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 e5be2c3317afa0b64900e38242d31a1cf706847ae46d78b413cedc732c856dc0
MD5 8921fa62aa39d794257f3577765ecccb
BLAKE2b-256 c39c098aba68cc845e3256d9fbe06e3521f672ce82f0fde7fa0f13f7073030be

See more details on using hashes here.

File details

Details for the file northroot-0.1.1-cp38-abi3-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for northroot-0.1.1-cp38-abi3-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 589eb6f3717805867d01136a33631ca4b284dc93a294d92470243e40d99ca905
MD5 7ad14f2d71f740d3237af07ab767bc62
BLAKE2b-256 e1ccb94f7d296cd9368510de428a2c0b25ce644703f0e9fcbc439932ea2c9267

See more details on using hashes here.

File details

Details for the file northroot-0.1.1-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for northroot-0.1.1-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ef6a586b28b182473aa8c45c55796c67efc08ddbc44e78fb8324e17d38ebc1f1
MD5 be0731d618c2c39dadbf8f2cc7f41e0f
BLAKE2b-256 0c09a8067c05362cb9dd0705b4e09242974eee561b3dc81ce002fa421b21e89d

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