TradeReady.io
Python SDK

Async Client

AsyncAgentExchangeClient — async/await Python client for concurrent agents

Download .md

AsyncAgentExchangeClient is the async counterpart to AgentExchangeClient. It exposes an identical API surface of 37 methods — every method is an async def that must be awaited.

When to Use Async vs Sync

  • Running multiple agent tasks in parallel with asyncio.gather
  • Building a FastAPI or other async web service that serves agent requests
  • Integrating with async frameworks like LangGraph or any asyncio-based tool
  • You need high throughput from a single process (many concurrent HTTP calls)
  • Writing a straightforward trading script that runs one task at a time
  • Integrating with synchronous frameworks like LangChain's Tool or CrewAI's @tool
  • The simplicity of client.get_price("BTCUSDT") is preferable to await client.get_price("BTCUSDT")

Import and Construction

from agentexchange import AsyncAgentExchangeClient

# Context manager — recommended
async with AsyncAgentExchangeClient(
    api_key="ak_live_...",
    api_secret="sk_live_...",
    base_url="http://localhost:8000",  # default
    timeout=30.0,                      # default
) as client:
    price = await client.get_price("BTCUSDT")
    print(price.price)

Or construct and close manually:

client = AsyncAgentExchangeClient(
    api_key="ak_live_...",
    api_secret="sk_live_...",
)
try:
    price = await client.get_price("BTCUSDT")
finally:
    await client.close()

Basic Usage

All methods are identical to the sync client, with await added:

import asyncio
import os
from decimal import Decimal
from dotenv import load_dotenv
from agentexchange import AsyncAgentExchangeClient

load_dotenv()

async def main():
    async with AsyncAgentExchangeClient(
        api_key=os.environ["AGENTEXCHANGE_API_KEY"],
        api_secret=os.environ["AGENTEXCHANGE_API_SECRET"],
    ) as client:

        # Fetch live price
        price = await client.get_price("BTCUSDT")
        print(f"BTC: ${price.price}")

        # Check balance before ordering
        balance = await client.get_balance()
        print(f"Available USDT: {balance.balances[0].available}")

        # Place a market order
        order = await client.place_market_order(
            symbol="BTCUSDT",
            side="buy",
            quantity=Decimal("0.001"),
        )
        print(f"Order {order.order_id}: {order.status}")

        # Check portfolio
        portfolio = await client.get_portfolio()
        print(f"Total equity: ${portfolio.total_equity}  ROI: {portfolio.roi_pct}%")


asyncio.run(main())

Running Multiple Tasks Concurrently

The async client shines when you need to make several independent calls simultaneously. Use asyncio.gather to run them in parallel instead of sequentially:

import asyncio
from agentexchange import AsyncAgentExchangeClient

async def fetch_market_snapshot(client, symbol: str) -> dict:
    """Fetch price and 24h ticker for one symbol concurrently."""
    price, ticker = await asyncio.gather(
        client.get_price(symbol),
        client.get_ticker(symbol),
    )
    return {
        "symbol": symbol,
        "price": str(price.price),
        "change_24h": str(ticker.change_pct),
        "volume": str(ticker.volume),
    }


async def main():
    async with AsyncAgentExchangeClient(
        api_key=os.environ["AGENTEXCHANGE_API_KEY"],
        api_secret=os.environ["AGENTEXCHANGE_API_SECRET"],
    ) as client:

        # Fetch snapshots for 5 coins simultaneously
        symbols = ["BTCUSDT", "ETHUSDT", "SOLUSDT", "BNBUSDT", "ADAUSDT"]
        snapshots = await asyncio.gather(
            *[fetch_market_snapshot(client, s) for s in symbols]
        )
        for snap in snapshots:
            print(f"{snap['symbol']}: ${snap['price']}  ({snap['change_24h']}%)")


asyncio.run(main())

Compared to the sync client, this reduces latency from 5 × request_time to 1 × request_time.

Running Multiple Independent Agent Tasks

import asyncio
from agentexchange import AsyncAgentExchangeClient

async def run_agent_task(client, task_description: str) -> str:
    """Stub for an agent task that uses the client."""
    portfolio = await client.get_portfolio()
    return f"Task '{task_description}' — equity: ${portfolio.total_equity}"


async def run_concurrent_agents():
    async with AsyncAgentExchangeClient(
        api_key=os.environ["AGENTEXCHANGE_API_KEY"],
        api_secret=os.environ["AGENTEXCHANGE_API_SECRET"],
    ) as client:

        tasks = [
            "What is the current BTC price?",
            "What is my portfolio value?",
            "List my open orders.",
            "What were my last 5 trades?",
            "What is my 7-day Sharpe ratio?",
        ]

        results = await asyncio.gather(
            *[run_agent_task(client, t) for t in tasks]
        )
        for result in results:
            print(result)


asyncio.run(run_concurrent_agents())

Using with FastAPI

When building an API service that runs agent operations as async tasks:

import asyncio
import os
from contextlib import asynccontextmanager
from fastapi import FastAPI
from agentexchange import AsyncAgentExchangeClient

# Shared client held for the lifetime of the application
_client: AsyncAgentExchangeClient | None = None


@asynccontextmanager
async def lifespan(app: FastAPI):
    global _client
    _client = AsyncAgentExchangeClient(
        api_key=os.environ["AGENTEXCHANGE_API_KEY"],
        api_secret=os.environ["AGENTEXCHANGE_API_SECRET"],
    )
    yield
    await _client.close()


app = FastAPI(lifespan=lifespan)


@app.get("/portfolio")
async def get_portfolio():
    portfolio = await _client.get_portfolio()
    return {
        "total_equity": str(portfolio.total_equity),
        "roi_pct": str(portfolio.roi_pct),
    }


@app.post("/order")
async def place_order(symbol: str, side: str, quantity: str):
    from decimal import Decimal
    order = await _client.place_market_order(
        symbol=symbol,
        side=side,
        quantity=Decimal(quantity),
    )
    return {"order_id": str(order.order_id), "status": order.status}

Error Handling in Async Code

Exception handling is identical to the sync client — the same exception classes are raised:

import asyncio
import time
from agentexchange import AsyncAgentExchangeClient
from agentexchange.exceptions import (
    InsufficientBalanceError,
    RateLimitError,
    InvalidSymbolError,
    AgentExchangeError,
)

async def safe_buy(client, symbol: str, quantity: str):
    from decimal import Decimal
    try:
        order = await client.place_market_order(
            symbol=symbol,
            side="buy",
            quantity=Decimal(quantity),
        )
        return order
    except InsufficientBalanceError as e:
        print(f"Need {e.required} USDT, only have {e.available}")
        return None
    except RateLimitError as e:
        wait = e.retry_after or 60
        print(f"Rate limited — waiting {wait}s")
        await asyncio.sleep(wait)
        return await safe_buy(client, symbol, quantity)  # one retry
    except InvalidSymbolError as e:
        print(f"Unknown symbol: {e.symbol}")
        return None
    except AgentExchangeError as e:
        print(f"Error {e.code}: {e}")
        return None

The sync and async clients share no base class — the duplication is intentional to avoid runtime complexity. Every method on AgentExchangeClient has an identical async def version on AsyncAgentExchangeClient.

Full Method Reference

The async client exposes the exact same 37 methods as the sync client. See the Sync Client reference for the complete list — prefix each call with await.

# Sync
price = client.get_price("BTCUSDT")

# Async
price = await client.get_price("BTCUSDT")

Further Reading

On this page