Consume Inference
Python SDK

Allora Python SDK

The Allora Python SDK (allora_sdk (opens in a new tab)) lets you submit machine learning predictions, query blockchain data, and access network inference results. It is organized in three layers:

LayerClassUse it to
WorkerAlloraWorkerSubmit your ML model's predictions to Allora topics. Handles wallet creation, registration, transactions, and retries so you can focus on model engineering.
RPC clientAlloraRPCClientMake typed queries and send transactions directly to the Allora chain over gRPC or REST, and subscribe to chain events over WebSocket.
API clientAlloraAPIClientRead topics and network inference results over HTTPS from the Allora API. No wallet required.

Goal

Run a minimal inference worker that submits predictions to Allora's testnet sandbox topic (topic ID 69), then use the RPC and API clients to read data back from the network.

Prerequisites

Steps

1. Install the SDK

pip install allora_sdk

This also installs the SDK's command-line tools.

2. Write the worker

Save this as worker.py, replacing the body of run_model with your model's prediction logic:

import asyncio
import os
 
from allora_sdk import AlloraNetworkConfig, AlloraWorker
 
async def run_model(nonce: int) -> float:
    # Your ML model's prediction logic goes here
    return 123.45
 
async def main():
    worker = AlloraWorker.inferer(
        run=run_model,
        topic_id=69,
        network=AlloraNetworkConfig.testnet(),
        api_key=os.environ["ALLORA_API_KEY"],
    )
    async for result in worker.run():
        if isinstance(result, Exception):
            print(f"Inference worker error: {result}")
        else:
            print(f"Prediction submitted to Allora: {result.submission}")
 
asyncio.run(main())

In a Jupyter or Colab notebook, an event loop is already running: call await main() instead of asyncio.run(main()).

3. Run it

export ALLORA_API_KEY="<your key from developer.allora.network>"
python worker.py

On the first run, the worker walks you through network onboarding automatically:

  • It connects to Allora's testnet, where no real funds are exchanged.
  • It asks for a wallet mnemonic — press Enter to have one generated for you. Your identity (an allo... address) is saved to a .allora_key file in the working directory and reused on later runs.
  • If the wallet's balance is low, it requests a small amount of ALLO — the network's gas currency — from the testnet faucet, using your API key.
  • It registers the worker on Allora's sandbox topic (ID 69) (opens in a new tab), a topic for newcomers to verify their setup. There are no penalties for submitting inaccurate inferences to this topic.

The worker then listens for the topic's submission windows and calls your run_model function each time one opens, submitting the returned value on-chain. Press Ctrl-C once for a graceful shutdown.

Advanced configuration

AlloraWorker.inferer() accepts more options when you need finer control:

import os
 
from allora_sdk import AlloraNetworkConfig, AlloraWorker, FeeTier
from allora_sdk.rpc_client.config import AlloraWalletConfig
 
def my_model(nonce: int) -> float:
    # Your ML model's prediction logic goes here
    return 123.45
 
worker = AlloraWorker.inferer(
    # Prediction function: sync or async, returning a float or str
    run=my_model,
 
    # Bring your own wallet instead of the auto-generated `.allora_key` identity
    wallet=AlloraWalletConfig(mnemonic=os.environ["ALLORA_WALLET_MNEMONIC"]),
 
    # Network helpers: AlloraNetworkConfig.testnet(), .mainnet(), .local() --
    # or specify the options directly:
    network=AlloraNetworkConfig(
        chain_id="allora-testnet-1",
        url="grpc+https://allora-grpc.testnet.allora.network:443",
        websocket_url="wss://allora-rpc.testnet.allora.network/websocket",
        fee_denom="uallo",
    ),
 
    # Topic to submit predictions to
    topic_id=69,
 
    # Used to fetch ALLO for gas fees from the faucet on testnet
    api_key=os.environ["ALLORA_API_KEY"],
 
    # How much to pay to prioritize inclusion within an epoch:
    # FeeTier.ECO, FeeTier.STANDARD (default), or FeeTier.PRIORITY
    fee_tier=FeeTier.PRIORITY,
 
    # Seconds between polls for open submission windows (default 120)
    polling_interval=120,
 
    # Verbose logging
    debug=True,
)

Verify

AlloraRPCClient: typed chain queries and transactions

AlloraRPCClient is the low-level blockchain client the worker is built on. It exposes typed query clients for the chain's modules (emissions, mint, auth, bank, tendermint, tx), transaction submission with fee estimation and signing, and WebSocket event subscriptions via client.events.

The wire protocol is chosen by the URL scheme in the network config: grpc+http(s):// uses gRPC, rest+http(s):// uses the Cosmos-LCD REST API.

Initialize

import os
 
from allora_sdk import AlloraRPCClient
from allora_sdk.rpc_client.config import AlloraWalletConfig
 
# Presets for common networks
client = AlloraRPCClient.testnet()
# client = AlloraRPCClient.mainnet()
# client = AlloraRPCClient.local()
 
# A wallet is only needed to send transactions -- queries work without one
client = AlloraRPCClient.testnet(
    wallet=AlloraWalletConfig(mnemonic=os.environ["ALLORA_WALLET_MNEMONIC"]),
)
 
# Or configure entirely from environment variables:
#   CHAIN_ID, RPC_ENDPOINT, WEBSOCKET_ENDPOINT, FAUCET_URL, FEE_DENOM,
#   FEE_MIN_GAS_PRICE, and PRIVATE_KEY / MNEMONIC / MNEMONIC_FILE / ADDRESS_PREFIX
client = AlloraRPCClient.from_env()

Query the chain

Queries take typed protobuf request objects and return typed responses:

from allora_sdk import AlloraRPCClient
from allora_sdk.protos.cosmos.base.tendermint.v1beta1 import GetLatestBlockRequest
 
client = AlloraRPCClient.testnet()
 
response = client.tendermint.get_latest_block(GetLatestBlockRequest())
print(f"Current block height: {response.sdk_block.header.height}")

Allora-specific queries live under client.emissions.query (topics, registrations, nonces, network inferences), with matching request/response types in the SDK's protos modules. When a wallet is configured, client.emissions.tx submits transactions such as worker registration (register) and inference submission (insert_worker_payload) — these are the same calls AlloraWorker makes for you.

AlloraAPIClient: topics and inferences over REST

AlloraAPIClient is a slim, fully asynchronous HTTP client for the Allora API (https://api.allora.network/v2). Use it to browse all topics and their metadata and to fetch the latest network inference for a topic — including the price prediction topics (BTC, ETH, and more across multiple timeframes) — without touching the chain directly.

You will need an Allora API key: get one for free at developer.allora.network (opens in a new tab).

import asyncio
import os
 
from allora_sdk.api_client import AlloraAPIClient, ChainID
 
client = AlloraAPIClient(api_key=os.environ["ALLORA_API_KEY"])
 
async def main():
    # List every topic on the network (pagination is handled automatically)
    topics = await client.get_all_topics()
    print(f"Found {len(topics)} topics")
 
    # Latest network inference for a topic (13 is an ETH price prediction topic)
    inference = await client.get_inference_by_topic_id(13)
    print(f"Latest network inference: {inference.inference_data.network_inference_normalized}")
 
asyncio.run(main())
  • get_all_topics() returns a list of Topic models with fields such as topic_id, topic_name, description, epoch_length, loss_method, worker_count, reputer_count, and is_active.
  • get_inference_by_topic_id(topic_id) returns an Inference model whose inference_data includes the raw network_inference and the decimal-adjusted network_inference_normalized.
  • The client defaults to testnet topics; pass chain_id=ChainID.MAINNET (imported above) to read mainnet topics.

Command-line tools

Installing allora_sdk also puts two utilities on your PATH:

  • allora-export-txs — exports a worker's inference transactions to a CSV file:

    allora-export-txs --address <allo1...> --output_file transactions.csv
  • allora-topic-lifecycle-visualizer — given a log file produced by AlloraWorker, plots the phases of a topic's lifecycle over the logged block range:

    allora-topic-lifecycle-visualizer --log_file worker.log

Run either tool with -h for all options.

Troubleshoot

  • RuntimeError: asyncio.run() cannot be called from a running event loop — you are in a notebook (Jupyter/Colab), where an event loop is already running. Replace asyncio.run(main()) with await main().
  • Worker prompts Mnemonic: on startup — no wallet was configured and no .allora_key file exists yet. Press Enter to generate a fresh identity, or paste an existing mnemonic. Back up the resulting .allora_key file; delete it to start over with a new identity.
  • Too many faucet requests — the testnet faucet is rate-limited. Send ALLO to your worker's address from another wallet, or request funds manually at faucet.testnet.allora.network (opens in a new tab).
  • gRPC StatusCode.UNIMPLEMENTED with unknown service emissions.vN.QueryService — the network has been upgraded to a newer protobuf revision than the one bundled with your installed SDK release. Upgrade with pip install --upgrade allora_sdk; if the newest release still fails, the deployed network is ahead of the latest SDK release — check the SDK issue tracker (opens in a new tab).
  • HTTP errors from api.allora.network — check that your API key is set and valid. Free keys are available at developer.allora.network (opens in a new tab).

Next