Skip to main content

maicoin 🪙

Python client for the MaiCoin MAX exchange. Provides a typed REST v3 client and a WebSocket stream client built on httpx, websockets, and pydantic.

📦 Installation

uv add maicoin
# or
pip install maicoin

Requires Python 3.12+.

🚀 Quick start

Set credentials in your environment (or a .env file):

MAX_API_KEY=your_key
MAX_API_SECRET=your_secret

🌐 REST

from maicoin.v3 import Client

async with Client() as client:  # public endpoints
    ticker = await client.ticker("btctwd")

async with Client(api_key=..., api_secret=...) as client:  # private endpoints (signed)
    accounts = await client.accounts()
    raw = await client.request("GET", "/api/v3/...", auth=True)  # raw escape hatch

Client owns an underlying httpx.AsyncClient by default. Prefer async with Client(...) so the HTTP session is closed automatically, or call await client.aclose() when managing the lifecycle manually.

For small synchronous scripts, use the explicit _sync wrappers:

from maicoin.v3 import Client

ticker = Client().ticker_sync("btctwd")

Do not call _sync wrappers from code that already runs inside an event loop, such as FastAPI handlers, Jupyter notebooks, or async trading bots. Await the async methods there instead:

from collections.abc import AsyncIterator

from maicoin.v3 import Client


async def max_client() -> AsyncIterator[Client]:
    async with Client(api_key="...", api_secret="...") as client:
        yield client


async def handler(client: Client) -> dict[str, str]:
    ticker = await client.ticker("btctwd")
    return {"last": ticker.last}

Use async iterators for cursor-paginated history endpoints:

async with Client(api_key=..., api_secret=...) as client:
    async for order in client.iter_order_history("btctwd", page_limit=100):
        print(order.id, order.state)

[!WARNING] ⚠️ Private methods can place orders, transfer funds, take loans, and trigger withdrawals. Double-check arguments before calling state-changing methods against a live account.

📡 WebSocket

from maicoin.ws import Channel, Stream, Subscription

stream = Stream()                  # or Stream.from_env() for private channels
stream.subscribe([Subscription(channel=Channel.TICKER, market="btcusdt")])
stream.add_handler(lambda r: print(r.model_dump(exclude_none=True)))
stream.run()

Full runnable scripts: examples/rest.py, examples/websocket.py.

🛠️ Development

This repo uses uv and just:

uv sync
just         # format, lint, type-check, test
just test    # pytest with coverage

Live integration tests

Live tests call the real MAX API and are skipped unless explicitly enabled:

RUN_LIVE_TESTS=1 uv run pytest -v -s -m live tests/live
# or
just live-test

Private read-only live tests also require MAX_API_KEY and MAX_API_SECRET; just loads these from .env automatically. Set MAX_LIVE_MARKET to override the default public test market (btctwd). Destructive live tests are intentionally not implemented yet.

📚 References

📄 License

MIT

Metadata

Release files for maicoin 0.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for maicoin 0.7.0
File Size Uploaded
maicoin-0.7.0.tar.gz 29.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for maicoin 0.7.0
File Interpreter ABI Platform
maicoin-0.7.0-py3-none-any.whl Python 3 none any Details

Total release size: 73.4 kB

Release files / maicoin-0.7.0.tar.gz

Download URL maicoin-0.7.0.tar.gz
Size 29.4 kB
Tags Source
SHA-256 checksum
How to use checksums
091a1e128b1585ecfd4bbb9e7df563fdccf75db38d226023a4cfcf543b640d7d
BLAKE2b-256 checksum
How to use checksums
f9ed8e8987aa2d50609ecc6b43fc79f0be14ae51f3152e79981f6378b0d9ee02
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / maicoin-0.7.0-py3-none-any.whl

Download URL maicoin-0.7.0-py3-none-any.whl
Size 43.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b90cd7af47c9bcafb053e8da161053f6e75854051622e73511483a1624a388df
BLAKE2b-256 checksum
How to use checksums
674805c7940c2a7ab139107894b17bfdbeeb2705be9fa65e898645195cca65d9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.7.0 This release

2 release files

0.6.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page