Async DexScreener API client with rate limiting, 429 retry, and response caching.
Project description
dexscreener-python
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.
🛡️ Why this library?
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.
📦 Install
pip install dexscreener-python
requires python 3.11+
⚡ Features
| 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.) |
🔧 Usage
💰 Token Pairs
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")
💵 Token Price
price = await client.get_token_price("solana", token_address)
print(f"${price}")
📦 Batch Fetch (up to 30 tokens)
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}")
🔍 Search
results = await client.search_pairs("BONK")
for pair in results:
print(f"{pair.base_token_symbol} on {pair.dex_id}: ${pair.price_usd}")
🚀 Boosted Tokens
boosted = await client.get_boosted_tokens("solana")
# boosted tokens are paid promotions — treat with caution
🎯 Specific Pair
pair = await client.get_pair_by_address("solana", pair_address)
print(f"{pair.dex_id}: ${pair.price_usd}")
📋 DexPairData
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 |
⚙️ Configuration
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
)
🆚 Comparison
| 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 |
License
MIT
📦 Also by JinUltimate1995
- 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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dexscreener_python-0.1.1.tar.gz.
File metadata
- Download URL: dexscreener_python-0.1.1.tar.gz
- Upload date:
- Size: 11.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f8e6363dc5a34b04f0d45a59d7569b2ec99260f667d7efa684df7748555d976a
|
|
| MD5 |
5c9bc5e4b746f3e522e2db0f55650671
|
|
| BLAKE2b-256 |
899fed6349b4ecddf18430e9855b5bcff3e9fe18a6496966cbaf7dcdcb03383d
|
File details
Details for the file dexscreener_python-0.1.1-py3-none-any.whl.
File metadata
- Download URL: dexscreener_python-0.1.1-py3-none-any.whl
- Upload date:
- Size: 9.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
679a3bb314498aeebefd6d3ad68f299a4468f3f34d4cf5a07b5bb7ba4d2facb5
|
|
| MD5 |
f24f6ba0352d95b1f2b9248dc4a607f5
|
|
| BLAKE2b-256 |
d2e10069d30becab8ccf38013f20f7cf56f9b59b142e05bd32fb0ed0438ac3b5
|