odos-py
A modern, fully-typed Python client for the Odos DEX Aggregator API.
- Sync (
OdosClient) and async (AsyncOdosClient) clients built onhttpx pydanticv2 models for all requests and responses- Automatic HTTP 429 handling with exponential backoff
- Configurable base URL and API-key header
mypy --strictclean, ships apy.typedmarker
Install
pip install odos-py
Optional extra for signing/sending the assembled transaction with web3.py:
pip install "odos-py[exec]"
Quickstart
Odos works in two steps: quote returns a pathId, then assemble turns that
pathId into ready-to-sign transaction calldata. The swap() helper chains
both:
from odos_py import OdosClient, QuoteRequest, InputToken, OutputToken
client = OdosClient(api_key="YOUR_KEY") # api_key optional but recommended
quote, assembled = client.swap(QuoteRequest(
chain_id=1,
input_tokens=[InputToken(token_address="0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", # WETH
amount="1000000000000000000")], # 1 WETH (wei)
output_tokens=[OutputToken(token_address="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", # USDC
proportion=1)],
user_addr="0x47E2D28169738039755586743E2dfCF3bd643f86",
slippage_limit_percent=0.3,
))
print(quote.path_id, assembled.transaction.to)
Async is identical with await:
import asyncio
from odos_py import AsyncOdosClient
async def main(request):
async with AsyncOdosClient() as client:
quote = await client.quote(request)
print(quote.path_id)
Auth & rate limits
There is a free, keyless tier, but it is heavily rate limited — POST /sor/quote/v2 returns HTTP 429 quickly without a key. Pass an api_key to
raise limits. The exact API-key header name is not publicly documented, so it
is configurable:
OdosClient(api_key="YOUR_KEY", api_key_header="x-api-key") # default header name
The client retries 429 responses with exponential backoff (honouring any
Retry-After header) and raises OdosRateLimitError once retries are
exhausted. Tune with max_retries and backoff_base.
Endpoints
| Method | Endpoint |
|---|---|
quote(request) |
POST /sor/quote/v2 |
assemble(user_addr=, path_id=) |
POST /sor/assemble |
execute(user_addr=, path_id=) |
POST /sor/execute |
swap(request) / quote_and_assemble(request) |
quote then assemble |
get_chains() |
GET /info/chains |
get_tokens(chain_id) |
GET /info/tokens/{chainId} |
get_router(chain_id) |
GET /info/router/v2/{chainId} |
get_contract_info(chain_id) |
GET /info/contract-info/v2/{chainId} |
get_token_price(chain_id, token_address) |
GET /pricing/token/{chainId}/{tokenAddress} |
Multi-chain is handled per call via chain_id on QuoteRequest and the info
endpoints.
Configuration
OdosClient(
base_url="https://api.odos.xyz", # configurable / proxyable
api_key=None,
api_key_header="x-api-key",
max_retries=3,
backoff_base=0.5,
timeout=30.0,
)
Development
pip install -e ".[dev,exec]"
pytest # unit tests (HTTP mocked, no network)
pytest -m integration # live smoke test against /info/chains
ruff check .
mypy
License
MIT
Metadata
Release files for odos-py 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 | |
|---|---|---|---|
| odos_py-0.1.1.tar.gz | 19.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| odos_py-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 36.4 kB
Release files / odos_py-0.1.1.tar.gz
| Download URL | odos_py-0.1.1.tar.gz |
|---|---|
| Size | 19.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
05e4a6be9a728963bb02607c4eee6cb167151a94da34b11d71c8cd6cc8c07519
|
|
BLAKE2b-256 checksum How to use checksums |
2c3de0abddf851f7ba42efd81d4a382a7095a2de285c3821d3b91cc5110bb3e5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.9
|
Release files / odos_py-0.1.1-py3-none-any.whl
| Download URL | odos_py-0.1.1-py3-none-any.whl |
|---|---|
| Size | 16.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
728cc066b9adbfdcaec7395d745f3b9443790588989138475d3993a08fa63985
|
|
BLAKE2b-256 checksum How to use checksums |
f38dc2ff6ab605a5cc7aea6ce439f284f3cd58bad4c4d00501e73d636c24a6c9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.9
|