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.
Prerequisites
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.comBasic Examples
1. When Python Fits
Python 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"- On-chain code must compile to sBPF - Python cannot run in the Sealevel runtime
- Python shines where I/O, scheduling, and data tooling dominate
- Keep signing keys out of notebooks; use env vars or a secrets manager
Related: solders & solana-py - the core SDK pair
2. Connect to RPC
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 script- Prefer
AsyncClientfor bots that poll subscriptions or fan out reads - Pin RPC URL per environment - never hardcode mainnet in dev scripts
- Rate-limit public endpoints; use a paid provider for production bots
Related: Reading Chain Data - accounts and tokens
3. Read a Balance with solders Types
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}")- Balances are lamports (integers) - never use floats for token math
Pubkeyvalidates base58 at construction - catches typos earlysolderstypes interoperate withsolana-pyrequest builders
4. Load a Keypair from File
Match 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())- Default CLI path:
~/.config/solana/id.json(64-byte secret array JSON) - Never commit keypair files - use
.gitignoreand CI secrets - For bots, prefer a dedicated low-balance hot wallet per strategy
Related: Building Transactions in Python - signing flows
5. Build a Simple Transfer Instruction
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)- Always fetch a recent blockhash from RPC - the placeholder above is illustrative only
- System Program transfers are the simplest end-to-end send path
- Simulation should precede mainnet sends (see intermediate examples)
6. Simulate Before Send
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=Falseruns simulation inside the RPC node- Parse
logson failure to debug missing accounts or program errors - Bots should retry with a fresh blockhash when simulation reports expiry
Related: Trading & Bots - automation patterns
Intermediate Examples
7. Call an Anchor Program with AnchorPy
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"](...)- AnchorPy targets Anchor 0.32.x IDL shapes - regenerate IDL after program changes
Wallet.local()mirrors Anchor TS behavior for dev; use explicit keypaths in prod- Keep program ID and IDL version pinned per deployment
Related: AnchorPy - full client guide
8. Paginate Large Account Queries
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,
)- Add memcmp filters on discriminators to shrink payloads
- For analytics, prefer an indexer or BigTable export over brute RPC scans
- Respect provider pagination limits - batch by slot ranges when available
Related: Data Analysis - pandas/Polars pipelines
9. Structured Logging for Bots
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)- Log slot, blockhash age, priority fee, and simulation logs on failure
- Correlate with Agave 4.1.1 RPC
getSignatureStatusesfor confirmation tracking - Ship logs to your observability stack - stdout alone is fragile in production
Related: 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.