From 5075ab8ff4116ff1a563e4d02b089ceae9e90fdf Mon Sep 17 00:00:00 2001 From: Martin Kersner Date: Sat, 4 Jul 2026 20:49:03 +0900 Subject: [PATCH 1/5] docs: add async client section to README + ToC entry --- README.md | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/README.md b/README.md index cad71bb..87a5a6d 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ This package is compatible with Python v3.10+. - [Installation](#installation) - [Configuration](#configuration) - [Quickstart](#quickstart) +- [Async Client](#async-client) - [API Reference](#api-reference) - [CEX Candle Data](#cex-candle-data) - [CEX Ticker Data](#cex-ticker-data) @@ -114,6 +115,95 @@ premium = maxi.premium(asset="BTC") print(premium.head()) ``` +## Async Client + +For `asyncio` applications the SDK ships an async client, `AsyncDatamaxi`, built +on [httpx](https://www.python-httpx.org/). It mirrors the sync `Datamaxi` +resource tree — the same endpoints and arguments — but every request method is a +coroutine and must be `await`ed. + +Install the async extra (pulls in `httpx`): + +```shell +pip install "datamaxi[async]" +``` + +Use it as an async context manager so the underlying HTTP client is closed +cleanly (or call `await client.aclose()` yourself). The async client reads the +same `DATAMAXI_API_KEY` environment variable as the sync client: + +```python +import asyncio +from datamaxi.aio import AsyncDatamaxi + + +async def main(): + # Reads DATAMAXI_API_KEY from the environment, like the sync client. + # Alternatively, pass api_key="your_api_key" explicitly. + async with AsyncDatamaxi() as client: + # Fetch CEX candle data (returns pandas DataFrame) + df = await client.cex.candle( + exchange="binance", + symbol="BTC-USDT", + interval="1d", + market="spot", + ) + print(df.head()) + + # Fetch ticker data + ticker = await client.cex.ticker.get( + exchange="binance", + symbol="BTC-USDT", + market="spot", + ) + print(ticker) + + # Fetch premium data + premium = await client.premium(asset="BTC") + print(premium.head()) + + +asyncio.run(main()) +``` + +If you do not use `async with`, close the client explicitly: + +```python +client = AsyncDatamaxi() +try: + df = await client.cex.candle( + exchange="binance", symbol="BTC-USDT", interval="1d", market="spot" + ) +finally: + await client.aclose() +``` + +Notes on the async client: + +- Every data method is a coroutine — `await` it (e.g. `await client.cex.candle(...)`). +- `AsyncDatamaxi` mirrors the sync resource tree: `cex.*` (candle, ticker, fee, + wallet_status, announcement, token, symbol), `funding_rate`, `forex`, + `premium`, `liquidation`, `open_interest`, `margin_borrow`, and `index_price`. +- Paginated endpoints return an **async** `next_request` callable — `await` it too: + +```python +data, next_request = await client.cex.announcement(page=1, limit=100) +data2, next_request2 = await next_request() +``` + +- Telegram and Naver have standalone async clients, `AsyncTelegram` and + `AsyncNaver` (also async context managers): + +```python +from datamaxi.aio import AsyncTelegram, AsyncNaver + +async with AsyncTelegram() as telegram: + channels, next_request = await telegram.channels(page=1, limit=100) + +async with AsyncNaver() as naver: + trend = await naver.trend(symbol="BTC") +``` + ## API Reference > **Discovery helpers.** Most endpoints expose helpers to list valid argument From df454285469f1768f2f8f42a68b6c9b217f3bc5f Mon Sep 17 00:00:00 2001 From: Martin Kersner Date: Sat, 4 Jul 2026 20:49:03 +0900 Subject: [PATCH 2/5] docs: add async client page to mkdocs site + nav --- docs/async.md | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++ mkdocs.yml | 1 + 2 files changed, 96 insertions(+) create mode 100644 docs/async.md diff --git a/docs/async.md b/docs/async.md new file mode 100644 index 0000000..bed09ba --- /dev/null +++ b/docs/async.md @@ -0,0 +1,95 @@ +# Async Client + +For `asyncio` applications the SDK ships an async client, `AsyncDatamaxi`, built +on [httpx](https://www.python-httpx.org/). It mirrors the sync +[`Datamaxi`](api.md) resource tree — the same endpoints and arguments — but every +request method is a coroutine and must be `await`ed. + +## Installation + +The async client requires the `async` extra, which pulls in `httpx`: + +```shell +pip install "datamaxi[async]" +``` + +## Usage + +Use `AsyncDatamaxi` as an async context manager so the underlying HTTP client is +closed cleanly (or call `await client.aclose()` yourself). It reads the same +`DATAMAXI_API_KEY` environment variable as the sync client. + +```python +import asyncio +from datamaxi.aio import AsyncDatamaxi + + +async def main(): + # Reads DATAMAXI_API_KEY from the environment, or pass api_key=... explicitly. + async with AsyncDatamaxi() as client: + df = await client.cex.candle( + exchange="binance", + symbol="BTC-USDT", + interval="1d", + market="spot", + ) + print(df.head()) + + ticker = await client.cex.ticker.get( + exchange="binance", + symbol="BTC-USDT", + market="spot", + ) + print(ticker) + + premium = await client.premium(asset="BTC") + print(premium.head()) + + +asyncio.run(main()) +``` + +Without a context manager, close the client explicitly: + +```python +client = AsyncDatamaxi() +try: + df = await client.cex.candle( + exchange="binance", symbol="BTC-USDT", interval="1d", market="spot" + ) +finally: + await client.aclose() +``` + +## Notes + +- Every data method is a coroutine — `await` it (e.g. `await client.cex.candle(...)`). +- `AsyncDatamaxi` mirrors the sync resource tree: `cex.*` (candle, ticker, fee, + `wallet_status`, announcement, token, symbol), `funding_rate`, `forex`, + `premium`, `liquidation`, `open_interest`, `margin_borrow`, and `index_price`. +- Paginated endpoints return an **async** `next_request` callable — `await` it too: + +```python +data, next_request = await client.cex.announcement(page=1, limit=100) +data2, next_request2 = await next_request() +``` + +- Telegram and Naver have standalone async clients, `AsyncTelegram` and + `AsyncNaver` (also async context managers): + +```python +from datamaxi.aio import AsyncTelegram, AsyncNaver + +async with AsyncTelegram() as telegram: + channels, next_request = await telegram.channels(page=1, limit=100) + +async with AsyncNaver() as naver: + trend = await naver.trend(symbol="BTC") +``` + +## Reference + +::: datamaxi.aio.AsyncDatamaxi + options: + show_submodules: false + show_source: false diff --git a/mkdocs.yml b/mkdocs.yml index d0ea8b6..88bbf7e 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -31,6 +31,7 @@ markdown_extensions: nav: - Main: index.md - API: api.md + - Async Client: async.md - CEX: - Candle: cex-candle.md - Ticker: cex-ticker.md From 727262758e30806481b69fdfa544458a6568888b Mon Sep 17 00:00:00 2001 From: Martin Kersner Date: Sat, 4 Jul 2026 21:09:02 +0900 Subject: [PATCH 3/5] docs: sync/async tabs on endpoint pages + slim async concept page - enable pymdownx.tabbed in mkdocs.yml - convert every endpoint page example into Sync/Async content tabs (17 pages) - slim docs/async.md to a concept page (install, lifecycle, pagination, ref) - drop invalid kwargs that neither sync nor async accept (cex.token.updates sort; cex.symbol cautions/delistings base; cex.symbol.volume exchange) --- docs/async.md | 62 +++++++++----------------- docs/cex-announcement.md | 49 +++++++++++++++----- docs/cex-candle.md | 64 ++++++++++++++++++-------- docs/cex-fee.md | 34 +++++++++++--- docs/cex-symbol.md | 81 ++++++++++++++++++++++++--------- docs/cex-ticker.md | 49 +++++++++++++++----- docs/cex-token.md | 44 +++++++++++++----- docs/cex-wallet-status.md | 34 +++++++++++--- docs/forex.md | 30 ++++++++++--- docs/funding-rate.md | 56 +++++++++++++++++------ docs/index-price.md | 46 ++++++++++++++----- docs/liquidation.md | 83 +++++++++++++++++++++++++--------- docs/margin-borrow.md | 27 ++++++++--- docs/naver-trend.md | 30 ++++++++++--- docs/open-interest.md | 94 +++++++++++++++++++++++++++------------ docs/premium.md | 64 ++++++++++++++++++-------- docs/telegram.md | 36 ++++++++++++--- mkdocs.yml | 2 + 18 files changed, 639 insertions(+), 246 deletions(-) diff --git a/docs/async.md b/docs/async.md index bed09ba..ec63717 100644 --- a/docs/async.md +++ b/docs/async.md @@ -1,9 +1,12 @@ -# Async Client +# Async client -For `asyncio` applications the SDK ships an async client, `AsyncDatamaxi`, built -on [httpx](https://www.python-httpx.org/). It mirrors the sync -[`Datamaxi`](api.md) resource tree — the same endpoints and arguments — but every -request method is a coroutine and must be `await`ed. +The SDK ships an async client, `AsyncDatamaxi`, built on +[httpx](https://www.python-httpx.org/). It mirrors the sync +[`Datamaxi`](api.md) resource tree — the same endpoints and arguments — with one +rule: every method is a coroutine and must be `await`ed. + +Every endpoint page in this documentation carries a **Sync** / **Async** tab — +switch to the *Async* tab to see the awaited twin of that page's example. ## Installation @@ -13,10 +16,10 @@ The async client requires the `async` extra, which pulls in `httpx`: pip install "datamaxi[async]" ``` -## Usage +## Lifecycle -Use `AsyncDatamaxi` as an async context manager so the underlying HTTP client is -closed cleanly (or call `await client.aclose()` yourself). It reads the same +Use `AsyncDatamaxi` as an async context manager so the underlying `httpx` client +is closed cleanly, or call `await client.aclose()` yourself. It reads the same `DATAMAXI_API_KEY` environment variable as the sync client. ```python @@ -28,23 +31,10 @@ async def main(): # Reads DATAMAXI_API_KEY from the environment, or pass api_key=... explicitly. async with AsyncDatamaxi() as client: df = await client.cex.candle( - exchange="binance", - symbol="BTC-USDT", - interval="1d", - market="spot", + exchange="binance", symbol="BTC-USDT", interval="1d", market="spot" ) print(df.head()) - ticker = await client.cex.ticker.get( - exchange="binance", - symbol="BTC-USDT", - market="spot", - ) - print(ticker) - - premium = await client.premium(asset="BTC") - print(premium.head()) - asyncio.run(main()) ``` @@ -63,28 +53,20 @@ finally: ## Notes -- Every data method is a coroutine — `await` it (e.g. `await client.cex.candle(...)`). -- `AsyncDatamaxi` mirrors the sync resource tree: `cex.*` (candle, ticker, fee, - `wallet_status`, announcement, token, symbol), `funding_rate`, `forex`, - `premium`, `liquidation`, `open_interest`, `margin_borrow`, and `index_price`. -- Paginated endpoints return an **async** `next_request` callable — `await` it too: - -```python -data, next_request = await client.cex.announcement(page=1, limit=100) -data2, next_request2 = await next_request() -``` - +- Every data and discovery method is a coroutine — `await` it (e.g. + `await client.cex.candle.exchanges(market="spot")`). - Telegram and Naver have standalone async clients, `AsyncTelegram` and - `AsyncNaver` (also async context managers): + `AsyncNaver`, also imported from `datamaxi.aio` and used the same way (async + context managers, awaited methods). See the [Telegram](telegram.md) and + [Naver Trend](naver-trend.md) pages for tabbed examples. -```python -from datamaxi.aio import AsyncTelegram, AsyncNaver +## Pagination -async with AsyncTelegram() as telegram: - channels, next_request = await telegram.channels(page=1, limit=100) +Paginated endpoints return an **async** `next_request` callable — `await` it too: -async with AsyncNaver() as naver: - trend = await naver.trend(symbol="BTC") +```python +data, next_request = await client.cex.announcement(page=1, limit=100) +data2, _ = await next_request() ``` ## Reference diff --git a/docs/cex-announcement.md b/docs/cex-announcement.md index ec18e2e..d4caf4d 100644 --- a/docs/cex-announcement.md +++ b/docs/cex-announcement.md @@ -4,21 +4,46 @@ Exchange announcements such as listings and delistings. ## Usage -```python -from datamaxi import Datamaxi +=== "Sync" -maxi = Datamaxi(api_key="YOUR_API_KEY") + ```python + from datamaxi import Datamaxi -data, next_request = maxi.cex.announcement( - exchange="binance", - category="listing", - page=1, - limit=50, - sort="desc", -) + maxi = Datamaxi(api_key="YOUR_API_KEY") -more_data, _ = next_request() -``` + data, next_request = maxi.cex.announcement( + exchange="binance", + category="listing", + page=1, + limit=50, + sort="desc", + ) + + more_data, _ = next_request() + ``` + +=== "Async" + + ```python + import asyncio + from datamaxi.aio import AsyncDatamaxi + + + async def main(): + async with AsyncDatamaxi(api_key="YOUR_API_KEY") as client: + data, next_request = await client.cex.announcement( + exchange="binance", + category="listing", + page=1, + limit=50, + sort="desc", + ) + + more_data, _ = await next_request() + + + asyncio.run(main()) + ``` ## Notes diff --git a/docs/cex-candle.md b/docs/cex-candle.md index 50192ba..006072b 100644 --- a/docs/cex-candle.md +++ b/docs/cex-candle.md @@ -4,24 +4,52 @@ Historical OHLCV candle data for centralized exchanges. ## Usage -```python -from datamaxi import Datamaxi - -maxi = Datamaxi(api_key="YOUR_API_KEY") - -exchanges = maxi.cex.candle.exchanges(market="spot") -symbols = maxi.cex.candle.symbols(exchange="binance", market="spot") -intervals = maxi.cex.candle.intervals() - -df = maxi.cex.candle( - exchange="binance", - symbol="BTC-USDT", - interval="1d", - market="spot", - from_unix=1704067200, - to_unix=1706745600, -) -``` +=== "Sync" + + ```python + from datamaxi import Datamaxi + + maxi = Datamaxi(api_key="YOUR_API_KEY") + + exchanges = maxi.cex.candle.exchanges(market="spot") + symbols = maxi.cex.candle.symbols(exchange="binance", market="spot") + intervals = maxi.cex.candle.intervals() + + df = maxi.cex.candle( + exchange="binance", + symbol="BTC-USDT", + interval="1d", + market="spot", + from_unix=1704067200, + to_unix=1706745600, + ) + ``` + +=== "Async" + + ```python + import asyncio + from datamaxi.aio import AsyncDatamaxi + + + async def main(): + async with AsyncDatamaxi(api_key="YOUR_API_KEY") as client: + exchanges = await client.cex.candle.exchanges(market="spot") + symbols = await client.cex.candle.symbols(exchange="binance", market="spot") + intervals = await client.cex.candle.intervals() + + df = await client.cex.candle( + exchange="binance", + symbol="BTC-USDT", + interval="1d", + market="spot", + from_unix=1704067200, + to_unix=1706745600, + ) + + + asyncio.run(main()) + ``` ## Notes diff --git a/docs/cex-fee.md b/docs/cex-fee.md index b5f7f96..2f09104 100644 --- a/docs/cex-fee.md +++ b/docs/cex-fee.md @@ -4,16 +4,36 @@ Trading fee schedules for centralized exchanges. ## Usage -```python -from datamaxi import Datamaxi +=== "Sync" -maxi = Datamaxi(api_key="YOUR_API_KEY") + ```python + from datamaxi import Datamaxi -exchanges = maxi.cex.fee.exchanges() -symbols = maxi.cex.fee.symbols(exchange="binance") + maxi = Datamaxi(api_key="YOUR_API_KEY") -fees = maxi.cex.fee(exchange="binance", symbol="BTC-USDT") -``` + exchanges = maxi.cex.fee.exchanges() + symbols = maxi.cex.fee.symbols(exchange="binance") + + fees = maxi.cex.fee(exchange="binance", symbol="BTC-USDT") + ``` + +=== "Async" + + ```python + import asyncio + from datamaxi.aio import AsyncDatamaxi + + + async def main(): + async with AsyncDatamaxi(api_key="YOUR_API_KEY") as client: + exchanges = await client.cex.fee.exchanges() + symbols = await client.cex.fee.symbols(exchange="binance") + + fees = await client.cex.fee(exchange="binance", symbol="BTC-USDT") + + + asyncio.run(main()) + ``` ## Notes diff --git a/docs/cex-symbol.md b/docs/cex-symbol.md index beb6019..4fa2895 100644 --- a/docs/cex-symbol.md +++ b/docs/cex-symbol.md @@ -4,39 +4,78 @@ Per-base / per-symbol CEX metadata and aggregates: trading status, tags, caution ## Usage -```python -from datamaxi import Datamaxi +=== "Sync" -maxi = Datamaxi(api_key="YOUR_API_KEY") + ```python + from datamaxi import Datamaxi -# Trading status + caution + tags + delisting metadata -metadata = maxi.cex.symbol.metadata(exchange="binance", base="BTC") + maxi = Datamaxi(api_key="YOUR_API_KEY") -# Exchange-assigned tags (e.g. seed, alpha) -tags = maxi.cex.symbol.tags(exchange="binance", base="BTC") + # Trading status + caution + tags + delisting metadata + metadata = maxi.cex.symbol.metadata(exchange="binance", base="BTC") -# Active caution / investment-warning flags -cautions = maxi.cex.symbol.cautions(exchange="binance", base="BTC") + # Exchange-assigned tags (e.g. seed, alpha) + tags = maxi.cex.symbol.tags(exchange="binance", base="BTC") -# Scheduled delistings with timestamps -delistings = maxi.cex.symbol.delistings(exchange="binance", base="BTC") + # Active caution / investment-warning flags + cautions = maxi.cex.symbol.cautions(exchange="binance") -# Per-exchange 24h volume for a single base asset -volume = maxi.cex.symbol.volume(base="BTC", exchange="binance") + # Scheduled delistings with timestamps + delistings = maxi.cex.symbol.delistings(exchange="binance") -# Per-exchange Open Interest for a single base asset -oi = maxi.cex.symbol.oi(base="BTC", exchange="binance") + # Per-exchange 24h volume for a single base asset + volume = maxi.cex.symbol.volume(base="BTC") -# Per-exchange OI snapshot with 1h / 4h / 24h deltas -oi_stats = maxi.cex.symbol.oi_stats(base="BTC", exchange="binance", currency="USD") + # Per-exchange Open Interest for a single base asset + oi = maxi.cex.symbol.oi(base="BTC", exchange="binance") -# Per-exchange long / short liquidation aggregates over a window -liquidation = maxi.cex.symbol.liquidation(base="BTC", window="24h") -``` + # Per-exchange OI snapshot with 1h / 4h / 24h deltas + oi_stats = maxi.cex.symbol.oi_stats(base="BTC", exchange="binance", currency="USD") + + # Per-exchange long / short liquidation aggregates over a window + liquidation = maxi.cex.symbol.liquidation(base="BTC", window="24h") + ``` + +=== "Async" + + ```python + import asyncio + from datamaxi.aio import AsyncDatamaxi + + + async def main(): + async with AsyncDatamaxi(api_key="YOUR_API_KEY") as client: + # Trading status + caution + tags + delisting metadata + metadata = await client.cex.symbol.metadata(exchange="binance", base="BTC") + + # Exchange-assigned tags (e.g. seed, alpha) + tags = await client.cex.symbol.tags(exchange="binance", base="BTC") + + # Active caution / investment-warning flags + cautions = await client.cex.symbol.cautions(exchange="binance") + + # Scheduled delistings with timestamps + delistings = await client.cex.symbol.delistings(exchange="binance") + + # Per-exchange 24h volume for a single base asset + volume = await client.cex.symbol.volume(base="BTC") + + # Per-exchange Open Interest for a single base asset + oi = await client.cex.symbol.oi(base="BTC", exchange="binance") + + # Per-exchange OI snapshot with 1h / 4h / 24h deltas + oi_stats = await client.cex.symbol.oi_stats(base="BTC", exchange="binance", currency="USD") + + # Per-exchange long / short liquidation aggregates over a window + liquidation = await client.cex.symbol.liquidation(base="BTC", window="24h") + + + asyncio.run(main()) + ``` ## Notes -- `metadata`, `tags`, `cautions`, and `delistings` take optional `exchange` / `base` filters; omit both to fetch across all symbols. +- `metadata` and `tags` take optional `exchange` / `base` filters; `cautions` and `delistings` filter by `exchange` (and `market`). Omit filters to fetch across all symbols. - `oi_stats` accepts `currency` of `USD` or `KRW`. ::: datamaxi.resources.CexSymbol diff --git a/docs/cex-ticker.md b/docs/cex-ticker.md index 9c85fd4..79267b3 100644 --- a/docs/cex-ticker.md +++ b/docs/cex-ticker.md @@ -4,21 +4,46 @@ Real-time ticker snapshots for centralized exchanges. ## Usage -```python -from datamaxi import Datamaxi +=== "Sync" -maxi = Datamaxi(api_key="YOUR_API_KEY") + ```python + from datamaxi import Datamaxi -exchanges = maxi.cex.ticker.exchanges(market="spot") -symbols = maxi.cex.ticker.symbols(exchange="binance", market="spot") + maxi = Datamaxi(api_key="YOUR_API_KEY") -ticker = maxi.cex.ticker.get( - exchange="binance", - symbol="BTC-USDT", - market="spot", - currency="USD", -) -``` + exchanges = maxi.cex.ticker.exchanges(market="spot") + symbols = maxi.cex.ticker.symbols(exchange="binance", market="spot") + + ticker = maxi.cex.ticker.get( + exchange="binance", + symbol="BTC-USDT", + market="spot", + currency="USD", + ) + ``` + +=== "Async" + + ```python + import asyncio + from datamaxi.aio import AsyncDatamaxi + + + async def main(): + async with AsyncDatamaxi(api_key="YOUR_API_KEY") as client: + exchanges = await client.cex.ticker.exchanges(market="spot") + symbols = await client.cex.ticker.symbols(exchange="binance", market="spot") + + ticker = await client.cex.ticker.get( + exchange="binance", + symbol="BTC-USDT", + market="spot", + currency="USD", + ) + + + asyncio.run(main()) + ``` ## Notes diff --git a/docs/cex-token.md b/docs/cex-token.md index 6b5dc05..b2ecfd6 100644 --- a/docs/cex-token.md +++ b/docs/cex-token.md @@ -4,20 +4,42 @@ Token listing and delisting updates from centralized exchanges. ## Usage -```python -from datamaxi import Datamaxi +=== "Sync" -maxi = Datamaxi(api_key="YOUR_API_KEY") + ```python + from datamaxi import Datamaxi -data, next_request = maxi.cex.token.updates( - type="listed", - page=1, - limit=100, - sort="desc", -) + maxi = Datamaxi(api_key="YOUR_API_KEY") -more_data, _ = next_request() -``` + data, next_request = maxi.cex.token.updates( + type="listed", + page=1, + limit=100, + ) + + more_data, _ = next_request() + ``` + +=== "Async" + + ```python + import asyncio + from datamaxi.aio import AsyncDatamaxi + + + async def main(): + async with AsyncDatamaxi(api_key="YOUR_API_KEY") as client: + data, next_request = await client.cex.token.updates( + type="listed", + page=1, + limit=100, + ) + + more_data, _ = await next_request() + + + asyncio.run(main()) + ``` ## Notes diff --git a/docs/cex-wallet-status.md b/docs/cex-wallet-status.md index 8fde333..04937c2 100644 --- a/docs/cex-wallet-status.md +++ b/docs/cex-wallet-status.md @@ -4,16 +4,36 @@ Deposit and withdrawal availability for centralized exchange assets. ## Usage -```python -from datamaxi import Datamaxi +=== "Sync" -maxi = Datamaxi(api_key="YOUR_API_KEY") + ```python + from datamaxi import Datamaxi -exchanges = maxi.cex.wallet_status.exchanges() -assets = maxi.cex.wallet_status.assets(exchange="binance") + maxi = Datamaxi(api_key="YOUR_API_KEY") -status = maxi.cex.wallet_status(exchange="binance", asset="BTC") -``` + exchanges = maxi.cex.wallet_status.exchanges() + assets = maxi.cex.wallet_status.assets(exchange="binance") + + status = maxi.cex.wallet_status(exchange="binance", asset="BTC") + ``` + +=== "Async" + + ```python + import asyncio + from datamaxi.aio import AsyncDatamaxi + + + async def main(): + async with AsyncDatamaxi(api_key="YOUR_API_KEY") as client: + exchanges = await client.cex.wallet_status.exchanges() + assets = await client.cex.wallet_status.assets(exchange="binance") + + status = await client.cex.wallet_status(exchange="binance", asset="BTC") + + + asyncio.run(main()) + ``` ## Notes diff --git a/docs/forex.md b/docs/forex.md index b0602cb..9b46c49 100644 --- a/docs/forex.md +++ b/docs/forex.md @@ -4,14 +4,32 @@ Foreign exchange spot rates. ## Usage -```python -from datamaxi import Datamaxi +=== "Sync" -maxi = Datamaxi(api_key="YOUR_API_KEY") + ```python + from datamaxi import Datamaxi -symbols = maxi.forex.symbols() -data = maxi.forex(symbol="USD-KRW") -``` + maxi = Datamaxi(api_key="YOUR_API_KEY") + + symbols = maxi.forex.symbols() + data = maxi.forex(symbol="USD-KRW") + ``` + +=== "Async" + + ```python + import asyncio + from datamaxi.aio import AsyncDatamaxi + + + async def main(): + async with AsyncDatamaxi(api_key="YOUR_API_KEY") as client: + symbols = await client.forex.symbols() + data = await client.forex(symbol="USD-KRW") + + + asyncio.run(main()) + ``` ## Notes diff --git a/docs/funding-rate.md b/docs/funding-rate.md index fc4b027..7a22eb7 100644 --- a/docs/funding-rate.md +++ b/docs/funding-rate.md @@ -4,24 +4,52 @@ Historical and latest funding rates for perpetual futures. ## Usage -```python -from datamaxi import Datamaxi +=== "Sync" -maxi = Datamaxi(api_key="YOUR_API_KEY") + ```python + from datamaxi import Datamaxi -exchanges = maxi.funding_rate.exchanges() -symbols = maxi.funding_rate.symbols(exchange="binance") + maxi = Datamaxi(api_key="YOUR_API_KEY") -history, next_request = maxi.funding_rate.history( - exchange="binance", - symbol="BTC-USDT", - page=1, - limit=100, - sort="desc", -) + exchanges = maxi.funding_rate.exchanges() + symbols = maxi.funding_rate.symbols(exchange="binance") -latest = maxi.funding_rate.latest(exchange="binance", symbol="BTC-USDT") -``` + history, next_request = maxi.funding_rate.history( + exchange="binance", + symbol="BTC-USDT", + page=1, + limit=100, + sort="desc", + ) + + latest = maxi.funding_rate.latest(exchange="binance", symbol="BTC-USDT") + ``` + +=== "Async" + + ```python + import asyncio + from datamaxi.aio import AsyncDatamaxi + + + async def main(): + async with AsyncDatamaxi(api_key="YOUR_API_KEY") as client: + exchanges = await client.funding_rate.exchanges() + symbols = await client.funding_rate.symbols(exchange="binance") + + history, next_request = await client.funding_rate.history( + exchange="binance", + symbol="BTC-USDT", + page=1, + limit=100, + sort="desc", + ) + + latest = await client.funding_rate.latest(exchange="binance", symbol="BTC-USDT") + + + asyncio.run(main()) + ``` ## Notes diff --git a/docs/index-price.md b/docs/index-price.md index b3a711d..a904ff8 100644 --- a/docs/index-price.md +++ b/docs/index-price.md @@ -4,18 +4,40 @@ Historical index price time series for a single asset. ## Usage -```python -from datamaxi import Datamaxi - -maxi = Datamaxi(api_key="YOUR_API_KEY") - -data = maxi.index_price( - asset="BTC", - from_="now - 1 month", - to="now", - interval="5m", -) -``` +=== "Sync" + + ```python + from datamaxi import Datamaxi + + maxi = Datamaxi(api_key="YOUR_API_KEY") + + data = maxi.index_price( + asset="BTC", + from_="now - 1 month", + to="now", + interval="5m", + ) + ``` + +=== "Async" + + ```python + import asyncio + from datamaxi.aio import AsyncDatamaxi + + + async def main(): + async with AsyncDatamaxi(api_key="YOUR_API_KEY") as client: + data = await client.index_price( + asset="BTC", + from_="now - 1 month", + to="now", + interval="5m", + ) + + + asyncio.run(main()) + ``` ## Notes diff --git a/docs/liquidation.md b/docs/liquidation.md index dbed476..eea32b6 100644 --- a/docs/liquidation.md +++ b/docs/liquidation.md @@ -4,35 +4,74 @@ CEX futures liquidation data: recent events, firehose feed, heatmaps, maps, and ## Usage -```python -from datamaxi import Datamaxi +=== "Sync" -maxi = Datamaxi(api_key="YOUR_API_KEY") + ```python + from datamaxi import Datamaxi -# Recent liquidation events for a single futures symbol -events = maxi.liquidation(exchange="binance", symbol="BTC-USDT", limit=100) + maxi = Datamaxi(api_key="YOUR_API_KEY") -# Firehose: most recent events across every symbol -feed = maxi.liquidation.feed(limit=100) + # Recent liquidation events for a single futures symbol + events = maxi.liquidation(exchange="binance", symbol="BTC-USDT", limit=100) -# Token x exchange liquidation heatmap over a rolling window -heatmap = maxi.liquidation.heatmap(window="1h", topN=10) + # Firehose: most recent events across every symbol + feed = maxi.liquidation.feed(limit=100) -# Liquidation KPI stats over a rolling window -stats = maxi.liquidation.stats(window="1h") + # Token x exchange liquidation heatmap over a rolling window + heatmap = maxi.liquidation.heatmap(window="1h", topN=10) -# Coinglass-style liquidation map (price x leverage tier) -liq_map = maxi.liquidation.map(base="BTC", exchange="binance", quote="USDT") + # Liquidation KPI stats over a rolling window + stats = maxi.liquidation.stats(window="1h") -# Bucketed long / short liquidation USD time series + price line -history = maxi.liquidation.symbol_history( - symbol="BTC", - quote="USDT", - exchange="binance", - interval="5m", - window="24h", -) -``` + # Coinglass-style liquidation map (price x leverage tier) + liq_map = maxi.liquidation.map(base="BTC", exchange="binance", quote="USDT") + + # Bucketed long / short liquidation USD time series + price line + history = maxi.liquidation.symbol_history( + symbol="BTC", + quote="USDT", + exchange="binance", + interval="5m", + window="24h", + ) + ``` + +=== "Async" + + ```python + import asyncio + from datamaxi.aio import AsyncDatamaxi + + + async def main(): + async with AsyncDatamaxi(api_key="YOUR_API_KEY") as client: + # Recent liquidation events for a single futures symbol + events = await client.liquidation(exchange="binance", symbol="BTC-USDT", limit=100) + + # Firehose: most recent events across every symbol + feed = await client.liquidation.feed(limit=100) + + # Token x exchange liquidation heatmap over a rolling window + heatmap = await client.liquidation.heatmap(window="1h", topN=10) + + # Liquidation KPI stats over a rolling window + stats = await client.liquidation.stats(window="1h") + + # Coinglass-style liquidation map (price x leverage tier) + liq_map = await client.liquidation.map(base="BTC", exchange="binance", quote="USDT") + + # Bucketed long / short liquidation USD time series + price line + history = await client.liquidation.symbol_history( + symbol="BTC", + quote="USDT", + exchange="binance", + interval="5m", + window="24h", + ) + + + asyncio.run(main()) + ``` ## Notes diff --git a/docs/margin-borrow.md b/docs/margin-borrow.md index 3f59432..a419b36 100644 --- a/docs/margin-borrow.md +++ b/docs/margin-borrow.md @@ -4,13 +4,30 @@ Margin borrow data for a single asset. ## Usage -```python -from datamaxi import Datamaxi +=== "Sync" -maxi = Datamaxi(api_key="YOUR_API_KEY") + ```python + from datamaxi import Datamaxi -data = maxi.margin_borrow(asset="BTC") -``` + maxi = Datamaxi(api_key="YOUR_API_KEY") + + data = maxi.margin_borrow(asset="BTC") + ``` + +=== "Async" + + ```python + import asyncio + from datamaxi.aio import AsyncDatamaxi + + + async def main(): + async with AsyncDatamaxi(api_key="YOUR_API_KEY") as client: + data = await client.margin_borrow(asset="BTC") + + + asyncio.run(main()) + ``` ::: datamaxi.resources.MarginBorrow options: diff --git a/docs/naver-trend.md b/docs/naver-trend.md index b287269..a66f1a2 100644 --- a/docs/naver-trend.md +++ b/docs/naver-trend.md @@ -4,14 +4,32 @@ Search trend data for South Korea via Naver. ## Usage -```python -from datamaxi import Naver +=== "Sync" -naver = Naver(api_key="YOUR_API_KEY") + ```python + from datamaxi import Naver -symbols = naver.symbols() -trend = naver.trend(symbol="BTC") -``` + naver = Naver(api_key="YOUR_API_KEY") + + symbols = naver.symbols() + trend = naver.trend(symbol="BTC") + ``` + +=== "Async" + + ```python + import asyncio + from datamaxi.aio import AsyncNaver + + + async def main(): + async with AsyncNaver(api_key="YOUR_API_KEY") as naver: + symbols = await naver.symbols() + trend = await naver.trend(symbol="BTC") + + + asyncio.run(main()) + ``` ## Notes diff --git a/docs/open-interest.md b/docs/open-interest.md index 00d659e..1aaebab 100644 --- a/docs/open-interest.md +++ b/docs/open-interest.md @@ -4,34 +4,72 @@ CEX futures Open Interest: latest snapshots, reporting pairs, the token x exchan ## Usage -```python -from datamaxi import Datamaxi - -maxi = Datamaxi(api_key="YOUR_API_KEY") - -# Latest OI snapshot for a single futures symbol -snapshot = maxi.open_interest(exchange="binance", symbol="BTC-USDT") - -# List all (exchange, symbol) pairs currently reporting OI -pairs = maxi.open_interest.list(exchange="binance") - -# Paginated token x exchange OI matrix -overview = maxi.open_interest.overview( - page=1, - limit=20, - key="binance", - sort="desc", -) - -# Top-line OI aggregates (total USD, top tokens, top exchanges) -summary = maxi.open_interest.summary(topN=10) - -# Per-exchange aggregated OI history for a single token -history = maxi.open_interest.history_aggregated( - token_id="bitcoin", - interval="1h", -) -``` +=== "Sync" + + ```python + from datamaxi import Datamaxi + + maxi = Datamaxi(api_key="YOUR_API_KEY") + + # Latest OI snapshot for a single futures symbol + snapshot = maxi.open_interest(exchange="binance", symbol="BTC-USDT") + + # List all (exchange, symbol) pairs currently reporting OI + pairs = maxi.open_interest.list(exchange="binance") + + # Paginated token x exchange OI matrix + overview = maxi.open_interest.overview( + page=1, + limit=20, + key="binance", + sort="desc", + ) + + # Top-line OI aggregates (total USD, top tokens, top exchanges) + summary = maxi.open_interest.summary(topN=10) + + # Per-exchange aggregated OI history for a single token + history = maxi.open_interest.history_aggregated( + token_id="bitcoin", + interval="1h", + ) + ``` + +=== "Async" + + ```python + import asyncio + from datamaxi.aio import AsyncDatamaxi + + + async def main(): + async with AsyncDatamaxi(api_key="YOUR_API_KEY") as client: + # Latest OI snapshot for a single futures symbol + snapshot = await client.open_interest(exchange="binance", symbol="BTC-USDT") + + # List all (exchange, symbol) pairs currently reporting OI + pairs = await client.open_interest.list(exchange="binance") + + # Paginated token x exchange OI matrix + overview = await client.open_interest.overview( + page=1, + limit=20, + key="binance", + sort="desc", + ) + + # Top-line OI aggregates (total USD, top tokens, top exchanges) + summary = await client.open_interest.summary(topN=10) + + # Per-exchange aggregated OI history for a single token + history = await client.open_interest.history_aggregated( + token_id="bitcoin", + interval="1h", + ) + + + asyncio.run(main()) + ``` ## Notes diff --git a/docs/premium.md b/docs/premium.md index 346e584..4431a85 100644 --- a/docs/premium.md +++ b/docs/premium.md @@ -4,24 +4,52 @@ Cross-exchange premium data for arbitrage and market dislocation analysis. ## Usage -```python -from datamaxi import Datamaxi - -maxi = Datamaxi(api_key="YOUR_API_KEY") - -exchanges = maxi.premium.exchanges() - -data = maxi.premium( - source_exchange="binance", - target_exchange="upbit", - asset="BTC", - source_market="spot", - target_market="spot", - sort="desc", - key="pdp", - limit=100, -) -``` +=== "Sync" + + ```python + from datamaxi import Datamaxi + + maxi = Datamaxi(api_key="YOUR_API_KEY") + + exchanges = maxi.premium.exchanges() + + data = maxi.premium( + source_exchange="binance", + target_exchange="upbit", + asset="BTC", + source_market="spot", + target_market="spot", + sort="desc", + key="pdp", + limit=100, + ) + ``` + +=== "Async" + + ```python + import asyncio + from datamaxi.aio import AsyncDatamaxi + + + async def main(): + async with AsyncDatamaxi(api_key="YOUR_API_KEY") as client: + exchanges = await client.premium.exchanges() + + data = await client.premium( + source_exchange="binance", + target_exchange="upbit", + asset="BTC", + source_market="spot", + target_market="spot", + sort="desc", + key="pdp", + limit=100, + ) + + + asyncio.run(main()) + ``` ## Notes diff --git a/docs/telegram.md b/docs/telegram.md index a7e9921..c8313ef 100644 --- a/docs/telegram.md +++ b/docs/telegram.md @@ -4,16 +4,38 @@ Telegram channel metadata and message history. ## Usage -```python -from datamaxi import Telegram +=== "Sync" -telegram = Telegram(api_key="YOUR_API_KEY") + ```python + from datamaxi import Telegram -channels, _ = telegram.channels(category="korean", limit=50) -messages, next_request = telegram.messages(channel_name="yunlog_announcement", limit=50) + telegram = Telegram(api_key="YOUR_API_KEY") -more_messages, _ = next_request() -``` + channels, _ = telegram.channels(category="korean", limit=50) + messages, next_request = telegram.messages(channel_name="yunlog_announcement", limit=50) + + more_messages, _ = next_request() + ``` + +=== "Async" + + ```python + import asyncio + from datamaxi.aio import AsyncTelegram + + + async def main(): + async with AsyncTelegram(api_key="YOUR_API_KEY") as telegram: + channels, _ = await telegram.channels(category="korean", limit=50) + messages, next_request = await telegram.messages( + channel_name="yunlog_announcement", limit=50 + ) + + more_messages, _ = await next_request() + + + asyncio.run(main()) + ``` ## Notes diff --git a/mkdocs.yml b/mkdocs.yml index 88bbf7e..da4c111 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -27,6 +27,8 @@ markdown_extensions: - pymdownx.highlight: use_pygments: true - pymdownx.superfences + - pymdownx.tabbed: + alternate_style: true nav: - Main: index.md From 5f6f679ab366b8228884cc20c03b27fb32292cb5 Mon Sep 17 00:00:00 2001 From: Martin Kersner Date: Sat, 4 Jul 2026 21:09:02 +0900 Subject: [PATCH 4/5] docs(readme): slim async section to a co-equal subsection --- README.md | 169 +++++++++++++++++++++++++----------------------------- 1 file changed, 78 insertions(+), 91 deletions(-) diff --git a/README.md b/README.md index 87a5a6d..a79f313 100644 --- a/README.md +++ b/README.md @@ -84,125 +84,112 @@ the key stays out of source code): export DATAMAXI_API_KEY="your_api_key" ``` -```python -from datamaxi import Datamaxi, Telegram, Naver +=== "Sync" + + ```python + from datamaxi import Datamaxi, Telegram, Naver + + # Clients read DATAMAXI_API_KEY from the environment automatically. + # Alternatively, pass api_key="your_api_key" explicitly to each client. + maxi = Datamaxi() + telegram = Telegram() + naver = Naver() + + # Fetch CEX candle data (returns pandas DataFrame) + df = maxi.cex.candle( + exchange="binance", + symbol="BTC-USDT", + interval="1d", + market="spot" + ) + print(df.head()) -# Clients read DATAMAXI_API_KEY from the environment automatically. -# Alternatively, pass api_key="your_api_key" explicitly to each client. -maxi = Datamaxi() -telegram = Telegram() -naver = Naver() + # Fetch ticker data + ticker = maxi.cex.ticker.get( + exchange="binance", + symbol="BTC-USDT", + market="spot" + ) + print(ticker) -# Fetch CEX candle data (returns pandas DataFrame) -df = maxi.cex.candle( - exchange="binance", - symbol="BTC-USDT", - interval="1d", - market="spot" -) -print(df.head()) + # Fetch premium data + premium = maxi.premium(asset="BTC") + print(premium.head()) + ``` -# Fetch ticker data -ticker = maxi.cex.ticker.get( - exchange="binance", - symbol="BTC-USDT", - market="spot" -) -print(ticker) +=== "Async" -# Fetch premium data -premium = maxi.premium(asset="BTC") -print(premium.head()) -``` + ```python + import asyncio + from datamaxi.aio import AsyncDatamaxi -## Async Client -For `asyncio` applications the SDK ships an async client, `AsyncDatamaxi`, built -on [httpx](https://www.python-httpx.org/). It mirrors the sync `Datamaxi` -resource tree — the same endpoints and arguments — but every request method is a -coroutine and must be `await`ed. + async def main(): + # Reads DATAMAXI_API_KEY from the environment automatically. + # Alternatively, pass api_key="your_api_key" explicitly. + async with AsyncDatamaxi() as client: + # Fetch CEX candle data (returns pandas DataFrame) + df = await client.cex.candle( + exchange="binance", + symbol="BTC-USDT", + interval="1d", + market="spot", + ) + print(df.head()) + + # Fetch ticker data + ticker = await client.cex.ticker.get( + exchange="binance", + symbol="BTC-USDT", + market="spot", + ) + print(ticker) + + # Fetch premium data + premium = await client.premium(asset="BTC") + print(premium.head()) + -Install the async extra (pulls in `httpx`): + asyncio.run(main()) + ``` + +## Async Client + +The SDK also ships an async client, `AsyncDatamaxi` (built on +[httpx](https://www.python-httpx.org/)). It mirrors the same resource tree and +arguments as `Datamaxi`, with one rule: every method is a coroutine and must be +`await`ed. Install the async extra: ```shell pip install "datamaxi[async]" ``` -Use it as an async context manager so the underlying HTTP client is closed -cleanly (or call `await client.aclose()` yourself). The async client reads the -same `DATAMAXI_API_KEY` environment variable as the sync client: - ```python import asyncio from datamaxi.aio import AsyncDatamaxi async def main(): - # Reads DATAMAXI_API_KEY from the environment, like the sync client. - # Alternatively, pass api_key="your_api_key" explicitly. + # Reads DATAMAXI_API_KEY from the environment, or pass api_key=... explicitly. async with AsyncDatamaxi() as client: - # Fetch CEX candle data (returns pandas DataFrame) df = await client.cex.candle( - exchange="binance", - symbol="BTC-USDT", - interval="1d", - market="spot", + exchange="binance", symbol="BTC-USDT", interval="1d", market="spot" ) print(df.head()) - # Fetch ticker data - ticker = await client.cex.ticker.get( - exchange="binance", - symbol="BTC-USDT", - market="spot", - ) - print(ticker) - - # Fetch premium data - premium = await client.premium(asset="BTC") - print(premium.head()) - asyncio.run(main()) ``` -If you do not use `async with`, close the client explicitly: - -```python -client = AsyncDatamaxi() -try: - df = await client.cex.candle( - exchange="binance", symbol="BTC-USDT", interval="1d", market="spot" - ) -finally: - await client.aclose() -``` - -Notes on the async client: +Use `AsyncDatamaxi` as an async context manager (shown above) or call +`await client.aclose()` yourself. Paginated endpoints return an async +`next_request` — `await` it too +(`data, next_request = await client.cex.announcement(...)`). Telegram and Naver +have standalone `AsyncTelegram` / `AsyncNaver` clients. -- Every data method is a coroutine — `await` it (e.g. `await client.cex.candle(...)`). -- `AsyncDatamaxi` mirrors the sync resource tree: `cex.*` (candle, ticker, fee, - wallet_status, announcement, token, symbol), `funding_rate`, `forex`, - `premium`, `liquidation`, `open_interest`, `margin_borrow`, and `index_price`. -- Paginated endpoints return an **async** `next_request` callable — `await` it too: - -```python -data, next_request = await client.cex.announcement(page=1, limit=100) -data2, next_request2 = await next_request() -``` - -- Telegram and Naver have standalone async clients, `AsyncTelegram` and - `AsyncNaver` (also async context managers): - -```python -from datamaxi.aio import AsyncTelegram, AsyncNaver - -async with AsyncTelegram() as telegram: - channels, next_request = await telegram.channels(page=1, limit=100) - -async with AsyncNaver() as naver: - trend = await naver.trend(symbol="BTC") -``` +Every endpoint in the [API Reference](#api-reference) works the same under the +async client — see the [docs](https://datamaxi.readthedocs.io/) where each +example has a Sync/Async tab. ## API Reference From 5e7885b0bf3fde51bd185c7f0d35d524165e89da Mon Sep 17 00:00:00 2001 From: Martin Kersner Date: Sat, 4 Jul 2026 21:26:50 +0900 Subject: [PATCH 5/5] docs: drop invalid sort= kwarg from CEX token updates example cex.token.updates accepts only page/limit/type; sort= would raise TypeError. Fixes the last instance (README API Reference, mirrored to docs/index.md via symlink). Closes #165. --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index a79f313..91b9494 100644 --- a/README.md +++ b/README.md @@ -313,7 +313,6 @@ data, next_request = maxi.cex.token.updates( page=1, # Optional: page number limit=1000, # Optional: items per page type=None, # Optional: "listed" or "delisted" - sort="desc" # Optional: "asc" or "desc" ) ```