Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

robonomics-interface

Python client for the Robonomics parachain on Polkadot: ED25519 accounts, the multi-recipient report envelope, and (in progress) storage queries, Datalog and RWS subscriptions.

Status

Part State
Keys, SS58, BIP39, message encryption, envelope ready
Metadata and storage queries ready
Async client, local node with public fallback ready
Extrinsics with events and readable errors ready
Datalog, RWS, System, Balances helpers ready
Synchronous wrapper ready
sr25519 ([sr25519] extra) next release

Installation

pip install --pre robonomics-interface

Python 3.12 or newer. Core dependencies: pynacl, scalecodec, websockets, xxhash.

Keys

Only ED25519 accounts are supported in 3.0. The same mnemonic gives the same address as polkadot.js and substrate-interface.

from robonomicsinterface import Keypair, generate_mnemonic

mnemonic = generate_mnemonic()
site = Keypair.from_mnemonic(mnemonic)
print(site.address)  # 4..., SS58 format 32

Keypair.from_secret("0x<32-byte hex seed>")  # what a person pastes: mnemonic or seed
Keypair.from_uri("//Alice")  # development keys and hard paths
integrator = Keypair.from_address("4F...")  # public only: verify and encrypt to

A keypair never exposes its secret: repr() shows the address only, exceptions never contain the input, and pickling is refused.

Report envelope

One symmetric key encrypts the payload; that key is wrapped for every recipient. The format is the one Robonomics Report Service already publishes.

from robonomicsinterface import decrypt_package, encrypt_for_recipients, parse_decrypted

package = encrypt_for_recipients(log_text, site, [integrator_address], {"orig_file_name": "ha.log"})
payload, meta = parse_decrypted(decrypt_package(package, integrator_keypair, site.address))

Connecting

from robonomicsinterface import DEFAULT_ENDPOINT, RobonomicsClient

async with RobonomicsClient(["ws://192.168.1.10:9944", DEFAULT_ENDPOINT]) as client:
    window = await client.constant("Datalog", "WindowSize")
    ledger = await client.query("RWS", "Ledger", owner_address)
    async for (owner,), devices in client.query_map("RWS", "Devices"):
        ...

Endpoints are used in the order given. A node is accepted only if it is on Robonomics Polkadot (checked by genesis hash) and is neither syncing nor without peers; otherwise the next endpoint is tried. While on a fallback, the client periodically tries to return to a preferred endpoint. client.endpoint tells which node is in use.

Every request has a timeout. Reads are retried on another endpoint after a network failure; network failures raise TransportError subclasses (worth retrying), while RpcError, DecodeError and the like mean retrying will not help.

Datalog, RWS and accounts

async with RobonomicsClient() as client:
    # Datalog: slot numbers mean what they say — item(address, 0) is slot 0
    latest = await client.datalog.latest(site_address)
    for item in await client.datalog.items(site_address):  # oldest first, one request
        print(item.index, item.timestamp, item.data)  # bytes; item.text for UTF-8
    await client.datalog.record(site, b"QmReport...", subscription_owner=integrator_address)

    # RWS subscriptions
    ledger = await client.rws.ledger(integrator_address)  # None without a subscription
    if ledger and not ledger.is_active():
        print("expired on", ledger.expires_at)
    await client.rws.add_devices(integrator, site_address)  # read, extend, write back
    await client.rws.set_devices(integrator, [a, b, c])  # a plain list, max 32

    # Accounts
    if not await client.system.exists(site_address):
        print("send it the existential deposit first")

Everything else is reachable through client.query, client.query_map, client.constant, client.compose_call and client.submit.

Without asyncio

RobonomicsSync is the same client for scripts, cron jobs and tools: every method blocks until the result is there. It runs the async client on an event loop in a background thread, so behaviour, errors and timeouts are identical.

from robonomicsinterface import RobonomicsSync

with RobonomicsSync() as client:
    for item in client.datalog.items(site_address):
        ...
    client.rws.set_devices(integrator, devices)

Inside an event loop (Home Assistant, any asyncio application) use RobonomicsClient: a blocking call there would stall the loop, so RobonomicsSync raises RuntimeError instead.

Sending extrinsics

from robonomicsinterface import ExtrinsicFailed, InvalidTransaction

record = await client.compose_call("Datalog", "record", {"record": b"QmReport..."})
call = await client.compose_call("RWS", "call", {"subscription_id": owner, "call": record})
try:
    result = await client.submit(call, site)  # waits until the block
except InvalidTransaction as e:  # refused before sending
    print(e.kind, e.explanation)  # "Payment: ... send it the existential deposit"
except ExtrinsicFailed as e:  # in a block, but the call failed
    print(e.pallet, e.error)  # "RWS", "NotLinkedDevice"
else:
    print(result.block_number, result.find("Datalog", "NewRecord"))

Arguments take natural Python values: bytes are sent as bytes (a str starting with 0x would be read as hex), a Keypair stands for its account, a Call nests, and a BoundedVec takes a plain list ({"devices": [a, b]}).

submit signs with a nonce from the node and a mortal era (64 blocks from the finalized head), asks the runtime to validate the extrinsic first, sends it once and reads the block's events: inclusion alone is not success. Signed extensions are taken from the runtime metadata. A lost connection after sending raises ExtrinsicOutcomeUnknown with the extrinsic hash, never a silent resend.

Your own node on the local network

A fully synced node at home makes a good first endpoint for Home Assistant. Expose its RPC to the LAN only with safe methods, e.g. --rpc-external --rpc-methods=safe --rpc-cors=all, and keep it off the internet. The library uses safe methods only. Prefer a separate RPC node to opening a collator's RPC: a collator's unsafe methods (author_rotateKeys, author_insertKey) must stay closed. Plain ws:// is fine inside the LAN; for wss:// with a private CA pass ssl=ssl.create_default_context(cafile=...).

Development

uv sync
uv run pytest                                  # offline: recorded mainnet data, local fake nodes
uv run ruff check . && uv run ruff format --check . && uv run mypy

Integration tests run against a development node with the runtime that runs on mainnet. scripts/devchain.sh downloads pinned, checksum-verified polkadot-omni-node and chain-spec-builder (Parity) and the Robonomics runtime, builds a development chain spec with funded ED25519 dev accounts, and starts the node:

scripts/devchain.sh &                          # ws://127.0.0.1:9944
ROBONOMICS_DEV_URL=ws://127.0.0.1:9944 uv run pytest -m integration
ROBONOMICS_MAINNET_SMOKE=1 uv run pytest -m mainnet   # read-only, sends nothing

tests/fixtures/compat_vectors.json pins what the 2.x stack produced (addresses, ciphertexts, signatures); tests/fixtures/generate_compat_vectors.py regenerates it. scripts/fetch_chain_fixtures.py re-records mainnet metadata and storage samples after a runtime upgrade. CI also installs the wheel in python:3.13-alpine on aarch64 without a compiler.

Releasing

  1. ROBONOMICS_MAINNET_SMOKE=1 uv run pytest -m mainnet against the live runtime.
  2. Set version in pyproject.toml, date the section in CHANGELOG.md.
  3. Tag vX.Y.Z and push the tag: CI builds the package and uploads it with the maintainer's token in the PYPI_API_TOKEN repository secret (after approval, if the pypi environment has required reviewers).

License

Apache-2.0.

Metadata

Release files for robonomics-interface 3.0.0rc1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for robonomics-interface 3.0.0rc1
File Size Uploaded
robonomics_interface-3.0.0rc1.tar.gz 242.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for robonomics-interface 3.0.0rc1
File Interpreter ABI Platform
robonomics_interface-3.0.0rc1-py3-none-any.whl Python 3 none any Details

Total release size: 307.6 kB

Release files / robonomics_interface-3.0.0rc1.tar.gz

Download URL robonomics_interface-3.0.0rc1.tar.gz
Size 242.2 kB
Tags Source
SHA-256 checksum
How to use checksums
d1aca73029b8d04ef57037320dd20828795aa8b342a122e16df9aeb3d8df1259
BLAKE2b-256 checksum
How to use checksums
826ba1820de387e2af1c6e4c40878498add96d0bc079b0dda7f773ad50afdd90
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / robonomics_interface-3.0.0rc1-py3-none-any.whl

Download URL robonomics_interface-3.0.0rc1-py3-none-any.whl
Size 65.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
711736395616bb64464391b8c18763676f8121b3756e7cbf4ce129bafe75f8bb
BLAKE2b-256 checksum
How to use checksums
40dd957d73ed2ce097f96f430f063e8e344ed2f5acb052ed1218c7fd7eded757
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

3.0.0rc1 This release

2 release files

2.0.0

2 release files

1.6.3

2 release files

1.6.2

2 release files

1.6.1

2 release files

1.6.0

2 release files

1.5.0

2 release files

1.4.0

2 release files

1.3.6

2 release files

1.3.5

2 release files

1.3.4

2 release files

1.3.3

2 release files

1.3.2

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.2

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.5

2 release files

1.0.4

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.11.1

2 release files

0.10.1

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.5

2 release files

0.6.4

2 release files

0.5.5

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.4

2 release files

0.1.3

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page