Python for Solana Basics
9 examples to get you started with Python for Solana - 6 basic and 3 intermediate. Covers when Python fits, RPC reads, transaction building, AnchorPy, and data workflows against Agave 4.1.1 clusters.
Search across all documentation pages
9 examples to get you started with Python for Solana - 6 basic and 3 intermediate. Covers when Python fits, RPC reads, transaction building, AnchorPy, and data workflows against Agave 4.1.1 clusters.
Create a virtual environment and install the core Python stack:
python3 -m venv .venv
source .venv/bin/activate
pip install solders solana anchorpy httpx pandas polarsPoint at devnet (matches Solana CLI 3.0.10 defaults):
export SOLANA_RPC_URL=https://api.devnet.solana.comPython is the right tool for off-chain automation, not on-chain programs.
# Good fits
USE_CASES = [
"market-making and arbitrage bots",
"backend APIs that build and relay transactions",
"indexing, ETL, and analytics into pandas/Polars",
"research notebooks and one-off ops scripts",
]
# Poor fit
ON_CHAIN = "Use Rust + Anchor 0.32.1 for programs deployed via cargo build-sbf"Related: solders & solana-py - the core SDK pair
solana-py exposes an async HTTP client for JSON-RPC.
from solana.rpc.async_api import AsyncClient
RPC = "https://api.devnet.solana.com"
async def main():
async with AsyncClient(RPC) as client:
slot = (await client.get_slot()).value
print(f"Current slot: {slot}")
# asyncio.run(main()) # uncomment in a scriptAsyncClient for bots that poll subscriptions or fan out readsRelated: Reading Chain Data - accounts and tokens
solders mirrors Solana primitives in Python with Rust performance.
from solders.pubkey import Pubkey
from solana.rpc.api import Client
SYSTEM_PROGRAM = Pubkey.from_string("11111111111111111111111111111111")
client = Client("https://api.devnet.solana.com")
resp = client.get_balance(SYSTEM_PROGRAM)
print(f"Lamports: {resp.value}")Pubkey validates base58 at construction - catches typos earlysolders types interoperate with solana-py request buildersMatch the keypair format Solana CLI 3.0.10 writes.
from solders.keypair import Keypair
kp = Keypair.from_bytes(bytes(open("/path/to/id.json", "rb").read()))
print(kp.pubkey())~/.config/solana/id.json (64-byte secret array JSON).gitignore and CI secretsRelated: Building Transactions in Python - signing flows
Compose instructions with solders, then wrap in a transaction.
from solders.pubkey import Pubkey
from solders.system_program import TransferParams, transfer
from solders.hash import Hash
from solders.message import Message
from solders.transaction import Transaction
payer = Keypair() # replace with your keypair
dest = Pubkey.from_string("Recipient1111111111111111111111111111111")
ix = transfer(TransferParams(from_pubkey=payer.pubkey(), to_pubkey=dest, lamports=1_000_000))
blockhash = Hash.from_string("11111111111111111111111111111111") # fetch fresh via RPC
msg = Message.new_with_blockhash([ix], payer.pubkey(), blockhash)
tx = Transaction.new_unsigned(msg)
tx.sign([payer], blockhash)Catch account and CU errors without spending fees.
from solana.rpc.types import TxOpts
sig = client.send_transaction(tx, opts=TxOpts(skip_preflight=False, preflight_commitment="confirmed"))
print(sig.value)skip_preflight=False runs simulation inside the RPC nodelogs on failure to debug missing accounts or program errorsRelated: Trading & Bots - automation patterns
Load an IDL and invoke instructions with typed clients.
from anchorpy import Program, Provider, Wallet
from solana.rpc.async_api import AsyncClient
async def call_anchor():
client = AsyncClient("https://api.devnet.solana.com")
wallet = Wallet.local() # uses ANCHOR_WALLET or default path
provider = Provider(client, wallet)
program = await Program.at("<PROGRAM_ID>", provider)
# await program.rpc["initialize"](...)Wallet.local() mirrors Anchor TS behavior for dev; use explicit keypaths in prodRelated: AnchorPy - full client guide
Avoid single giant getProgramAccounts responses.
from solana.rpc.types import MemcmpOpts
filters = [MemcmpOpts(offset=0, bytes="...")] # program-specific discriminator
resp = client.get_program_accounts(
Pubkey.from_string("<PROGRAM_ID>"),
encoding="base64",
filters=filters,
)Related: Data Analysis - pandas/Polars pipelines
Make incident response tractable when transactions fail to land.
import logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
log = logging.getLogger("solana-bot")
def on_send_failure(signature: str, err: Exception):
log.error("send_failed sig=%s err=%s", signature, err)getSignatureStatuses for confirmation trackingRelated: Python for Solana Best Practices - production checklist
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.
Reviewed by Chris St. John·Last updated Jul 16, 2026