← Back to guides
April 15, 2026·10 min read

Solana gRPC Python Tutorial — Stream Blockchain Data with Yellowstone (2026)

Solana gRPC Python Tutorial — Stream Blockchain Data with Yellowstone (2026)
PythongRPCYellowstoneSolanaTutorial

Python is the most popular language for data analysis, trading bots, and automation. This tutorial shows you how to connect to Yellowstone gRPC from Python, subscribe to real-time Solana data, and handle events — or skip the complexity entirely with Subglow's pre-parsed JSON output.

Why Python for Solana Streaming

Python's strength isn't raw speed — it's the ecosystem. Pandas for data analysis, NumPy for computation, scikit-learn and TensorFlow for ML-based trading strategies. The bottleneck for Solana bots isn't Python's processing speed; it's data delivery latency. Yellowstone gRPC delivers data in ~5ms. Even in Python, processing each event takes microseconds.

Install Dependencies

pip install grpcio grpcio-tools protobuf

Clone the Yellowstone proto files:

git clone https://github.com/rpcpool/yellowstone-grpc.git
cd yellowstone-grpc/yellowstone-grpc-proto/proto

Generate Python stubs:

python -m grpc_tools.protoc \
  --proto_path=. \
  --python_out=./generated \
  --grpc_python_out=./generated \
  geyser.proto

This generates geyser_pb2.py and geyser_pb2_grpc.py — the Python bindings for Yellowstone's protobuf API.

Connect and Subscribe

import grpc
from generated import geyser_pb2, geyser_pb2_grpc

# Create secure channel
channel = grpc.secure_channel(
    "grpc.subglow.io:443",
    grpc.ssl_channel_credentials(),
)
stub = geyser_pb2_grpc.GeyserStub(channel)

# Build subscription request
def build_request():
    request = geyser_pb2.SubscribeRequest()
    # Subscribe to Pump.fun transactions
    tx_filter = geyser_pb2.SubscribeRequestFilterTransactions()
    tx_filter.account_include.append("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P")
    tx_filter.vote.value = False
    tx_filter.failed.value = False
    request.transactions["pump_fun"].CopyFrom(tx_filter)
    request.commitment = geyser_pb2.CommitmentLevel.CONFIRMED
    yield request

# Stream events
metadata = [("x-api-key", "YOUR_SUBGLOW_KEY")]
stream = stub.Subscribe(build_request(), metadata=metadata)

for update in stream:
    if update.HasField("transaction"):
        slot = update.transaction.slot
        sig = update.transaction.transaction.signature.hex()[:16]
        print(f"Pump.fun tx: {sig}... | Slot: {slot}")

Filter by Multiple Programs

Add Raydium alongside Pump.fun for comprehensive DEX coverage:

raydium_filter = geyser_pb2.SubscribeRequestFilterTransactions()
raydium_filter.account_include.append("675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8")
raydium_filter.vote.value = False
raydium_filter.failed.value = False
request.transactions["raydium_amm"].CopyFrom(raydium_filter)

Handle Disconnection

import time

def stream_with_retry():
    delay = 1
    while True:
        try:
            channel = grpc.secure_channel("grpc.subglow.io:443", grpc.ssl_channel_credentials())
            stub = geyser_pb2_grpc.GeyserStub(channel)
            stream = stub.Subscribe(build_request(), metadata=metadata)
            for update in stream:
                delay = 1  # Reset on success
                process_update(update)
        except grpc.RpcError as e:
            print(f"Stream error: {e.code()}. Reconnecting in {delay}s...")
            time.sleep(delay)
            delay = min(delay * 2, 30)

Skip the Complexity with Subglow

Raw Yellowstone gRPC requires protobuf compilation, Borsh decoding, and instruction parsing. Subglow delivers the same data as pre-parsed JSON over gRPC. Your Python code gets clean dictionaries with human-readable field names — no protobuf stubs needed.

Further Reading

Ready to try it?

Get your API key and start receiving filtered data in under 5 minutes. Free tier available.

Get started