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:
| Layer | Class | Use it to |
|---|---|---|
| Worker | AlloraWorker | Submit your ML model's predictions to Allora topics. Handles wallet creation, registration, transactions, and retries so you can focus on model engineering. |
| RPC client | AlloraRPCClient | Make typed queries and send transactions directly to the Allora chain over gRPC or REST, and subscribe to chain events over WebSocket. |
| API client | AlloraAPIClient | Read 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
- Python 3.10–3.13
- An Allora API key — get one for free at developer.allora.network (opens in a new tab). On testnet, the worker uses it to automatically request ALLO gas from the faucet.
Steps
1. Install the SDK
pip install allora_sdkThis 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.pyOn 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_keyfile 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
- Your terminal should log the worker's wallet address and balance, then print
Prediction submitted to Allora: ...each time a submission window for the topic opens. - Open testnet.explorer.allora.network/topics/69 (opens in a new tab) and look for your worker's
allo...address among the topic's workers.
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 ofTopicmodels with fields such astopic_id,topic_name,description,epoch_length,loss_method,worker_count,reputer_count, andis_active.get_inference_by_topic_id(topic_id)returns anInferencemodel whoseinference_dataincludes the rawnetwork_inferenceand the decimal-adjustednetwork_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 byAlloraWorker, 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. Replaceasyncio.run(main())withawait main().- Worker prompts
Mnemonic:on startup — no wallet was configured and no.allora_keyfile exists yet. Press Enter to generate a fresh identity, or paste an existing mnemonic. Back up the resulting.allora_keyfile; 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.UNIMPLEMENTEDwithunknown service emissions.vN.QueryService— the network has been upgraded to a newer protobuf revision than the one bundled with your installed SDK release. Upgrade withpip 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
- Find a topic to predict on: existing topics
- Productionize your worker: deploy a worker with Docker
- Consume inferences from your app: Allora API endpoint, the TypeScript SDK, or the Go SDK
- Train and deploy a model end to end with the Forge Builder Kit (opens in a new tab)