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.
Metadata
Release files for dexscreener-python 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dexscreener_python-0.1.1.tar.gz | 11.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dexscreener_python-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 21.8 kB
Release files / dexscreener_python-0.1.1.tar.gz
| Download URL | dexscreener_python-0.1.1.tar.gz |
|---|---|
| Size | 11.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f8e6363dc5a34b04f0d45a59d7569b2ec99260f667d7efa684df7748555d976a
|
|
BLAKE2b-256 checksum How to use checksums |
899fed6349b4ecddf18430e9855b5bcff3e9fe18a6496966cbaf7dcdcb03383d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|
Release files / dexscreener_python-0.1.1-py3-none-any.whl
| Download URL | dexscreener_python-0.1.1-py3-none-any.whl |
|---|---|
| Size | 9.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
679a3bb314498aeebefd6d3ad68f299a4468f3f34d4cf5a07b5bb7ba4d2facb5
|
|
BLAKE2b-256 checksum How to use checksums |
d2e10069d30becab8ccf38013f20f7cf56f9b59b142e05bd32fb0ed0438ac3b5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|