async dexscreener api client for python.
rate limiting. 429 retry. response caching. request dedup. works on any chain.
extracted from a production trading system. handles rate limits gracefully.
dexscreener's api is free and powerful, but:
- 429s kill your app if you don't handle them
- no python client exists that handles rate limits properly
- concurrent requests for the same token waste your quota
this library solves all three:
from dexscreener import DexScreenerClient
async with DexScreenerClient() as client:
# get all trading pairs for a token
pairs = await client.get_token_pairs("solana", "So11111111111111111111111111111111111111112")
for pair in pairs:
print(f"{pair.base_token_symbol}: ${pair.price_usd} | liq: ${pair.liquidity_usd}")429s β automatic exponential backoff (3s β 6s β 12s). duplicate requests β deduplicated into one HTTP call. results β cached with configurable TTL.
pip install dexscreener-pythonrequires python 3.11+
| feature | description |
|---|---|
| any chain | solana, ethereum, base, bsc, arbitrum β anything dexscreener supports |
| adaptive rate limiting | token bucket that backs off on 429 and recovers after success |
| global 429 cooldown | one 429 pauses ALL requests briefly (prevents request storms) |
| response cache | configurable TTL per endpoint. concurrent calls share one request. |
| batch support | fetch up to 30 tokens in a single request |
| typed data | DexPairData dataclass with computed properties (buy/sell ratio, age, etc.) |
pairs = await client.get_token_pairs("solana", token_address)
best_pair = pairs[0] # sorted by liquidity (highest first)
print(f"Price: ${best_pair.price_usd}")
print(f"Liquidity: ${best_pair.liquidity_usd}")
print(f"24h Volume: ${best_pair.volume_24h}")
print(f"Buy/Sell 5m: {best_pair.buy_sell_ratio_5m:.2f}")
print(f"Age: {best_pair.pair_age_seconds // 3600}h")price = await client.get_token_price("solana", token_address)
print(f"${price}")data = await client.get_tokens_batch("solana", [addr1, addr2, addr3])
for addr, pair in data.items():
print(f"{pair.base_token_symbol}: ${pair.price_usd}")results = await client.search_pairs("BONK")
for pair in results:
print(f"{pair.base_token_symbol} on {pair.dex_id}: ${pair.price_usd}")boosted = await client.get_boosted_tokens("solana")
# boosted tokens are paid promotions β treat with cautionpair = await client.get_pair_by_address("solana", pair_address)
print(f"{pair.dex_id}: ${pair.price_usd}")all methods return DexPairData objects with these fields:
| field | type | description |
|---|---|---|
chain_id |
str | chain identifier |
dex_id |
str | dex identifier (raydium, uniswap_v3, etc.) |
pair_address |
str | pair contract address |
base_token_address |
str | base token mint/address |
base_token_symbol |
str | token symbol |
price_usd |
Decimal | current price in USD |
price_native |
Decimal | price in native token (SOL, ETH, etc.) |
liquidity_usd |
Decimal | total liquidity in USD |
volume_5m / 1h / 6h / 24h |
Decimal | volume by timeframe |
price_change_5m / 1h / 6h / 24h |
Decimal | price change % |
buys_5m / 1h / 24h |
int | buy transactions |
sells_5m / 1h / 24h |
int | sell transactions |
pair_created_at |
int | unix timestamp (ms) |
computed properties:
| property | description |
|---|---|
buy_sell_ratio_5m |
buy/sell ratio over 5 minutes (>1 = more buying) |
buy_sell_ratio_1h |
buy/sell ratio over 1 hour |
has_liquidity |
True if liquidity > $1000 |
pair_age_seconds |
pair age in seconds |
client = DexScreenerClient(
rate_limit=5.0, # requests/second (default: 5.0, dexscreener limit is ~300/min)
cache_ttl=8.0, # default cache TTL in seconds
)| dexscreener-python | raw httpx / requests |
|
|---|---|---|
| Rate limiting | β adaptive token bucket | β manual |
| 429 retry | β exponential backoff | β crash |
| Global cooldown | β one 429 pauses all | β per-request only |
| Response cache | β TTL + dedup | β manual |
| Typed data | β
DexPairData dataclass |
β raw dicts |
| Batch support | β up to 30 tokens | β manual loop |
| Async | β native | depends |
MIT
- jupiter-swap-python β Jupiter swap client for Python. Async. Typed.
- pumpfun-python β PumpFun bonding curve + PumpSwap AMM. Direct swaps from Python.
- solana-rpc-resilient β Fault-tolerant Solana RPC with automatic failover.
If this saved you time, a tip is appreciated β it funds maintenance.
Tip jar (SOL): Evot66rHqu6WyiBF948YipgArHSMeJ5D4GeNJXPTpV6q
You can also sponsor via the GitHub Sponsor button.