Metadata-Version: 2.4
Name: typed-mexc
Version: 0.1.4
Summary: A fully typed, validated async client for the MEXC API.
Author-email: Marcel Claramunt <marcel@tribulnation.com>
Project-URL: repo, https://github.com/tribulnation/mexc.git
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: lazy-loader
Requires-Dist: httpx
Requires-Dist: pydantic
Requires-Dist: websockets
Requires-Dist: orjson
Requires-Dist: protobuf

# Typed MEXC

> A fully typed, validated async client for the MEXC API

**Use autocomplete instead of documentation.**

```python
from mexc import MEXC

async with MEXC.new() as client:
    account = await client.spot.account()
    for balance in account['balances']:
        if float(balance['free']) > 0:
            print(f"{balance['asset']}: {balance['free']}")
```

## Why Typed MEXC?

- **🎯 Precise Types**: Literal types, not strings. Your IDE knows exactly what's valid.
- **✅ Automatic Validation**: Pydantic-powered response validation catches API changes instantly.
- **⚡ Async First**: Built on `httpx` for high-performance async operations.
- **🔒 Type Safety**: Full type hints throughout. Catch errors before runtime.
- **🎨 Beautiful DX**: No unnecessary imports, sensible defaults, optional complexity.
- **📦 Batteries Included**: Pagination helpers, WebSocket streams for real-time data.

## Installation

```bash
pip install typed-mexc
```

## Quick Start

### 1. Set up API credentials

```bash
export MEXC_ACCESS_KEY="your_access_key"
export MEXC_SECRET_KEY="your_secret_key"
```

### 2. Start trading

```python
from mexc import MEXC

async with MEXC.new() as client:
    # Get spot account info
    account = await client.spot.account()
    
    # Get futures positions
    positions = await client.futures.positions()
    
    # Get funding rate
    rate = await client.futures.funding_rate(symbol='BTC_USDT')
```

## Features

### No Unnecessary Imports

Notice something? **You never imported `Literal` types.** Just use strings:

```python
# ❌ Other libraries
from some_sdk import Interval
candles = await client.get_candles(symbol='BTCUSDT', interval=Interval.M1)

# ✅ Typed MEXC
candles = await client.spot.candles(
    'BTCUSDT', interval='1m'  # Your IDE autocompletes this!
)
```

### Precise Type Annotations

Every field is precisely typed. Prices are strings (for precision), timestamps are `datetime` where applicable:

```python
from datetime import datetime

account = await client.spot.account()
for balance in account['balances']:
    asset: str = balance['asset']
    free: str = balance['free']  # String for decimal precision
```

### Automatic Validation

Response validation is **on by default** but can be disabled:

```python
# Validated (default) - throws ValidationError if API response changes
account = await client.spot.account()

# Skip validation for maximum performance
account = await client.spot.account(validate=False)
```

### Built-in Pagination

```python
# Manual pagination
candles = await client.spot.candles(
    'BTCUSDT', interval='1m', limit=500
)

# Automatic pagination - yields chunks as they arrive
async for chunk in client.spot.candles_paged(
    'BTCUSDT', interval='1m', start=start, end=end
):
    for candle in chunk:
        print(f"Candle: {candle['open']} -> {candle['close']}")
```

### WebSocket Streams

Real-time market and user data via WebSockets:

```python
async with MEXC.new() as client:
    # Spot: subscribe to candles (public stream)
    async for candle in client.spot.streams.candles('BTCUSDT', interval='Min1'):
        print(candle)
    
    # Futures: subscribe to tickers
    async for tickers in client.futures.streams.tickers():
        print(tickers)
```

## API Coverage

This library covers **Spot** and **Futures** with market data, trading, user data, and WebSocket streams.

- **Spot**: Account, candles, depth, trades, orders (place/cancel), wallet (deposits, withdrawals)
- **Futures**: Positions, assets, funding rates, contracts, candles, depth, user streams

📋 **See [API Overview](docs/api-overview.md) for complete coverage details.**

## Documentation

- [**Quickstart Guide**](docs/quickstart.md) - Get up and running in 5 minutes
- [**Authentication**](docs/authentication.md) - API credentials setup
- [**API Overview**](docs/api-overview.md) - Available endpoints and modules
- [**Examples**](docs/examples.md) - Common use cases and patterns
- [**Design Philosophy**](docs/design-philosophy.md) - Why we built it this way

## Design Philosophy

Typed MEXC follows the principles outlined in [**this blog post**](https://tribulnation.com/blog/clients):

1. **Inputs shouldn't require custom imports** - Use string literals, not enums
2. **Annotate types precisely** - `TypedDict`, strings for prices, `Literal` for enums
3. **Avoid unnecessary complication** - Sensible defaults, optional complexity
4. **Provide extra behavior optionally** - Pagination and validation are opt-in

**Details matter. Developer experience matters.**

## Examples

### Portfolio Tracking

```python
async with MEXC.new() as client:
    account = await client.spot.account()
    
    total_held = sum(
        float(b['free']) + float(b['locked'])
        for b in account['balances']
        if float(b['free']) > 0 or float(b['locked']) > 0
    )
    print(f"Spot Balance: {total_held}")
```

### Trading Bot

```python
async with MEXC.new() as client:
    # Get open orders
    orders = await client.spot.open_orders(symbol='BTCUSDT')
    
    # Place limit order
    result = await client.spot.place_order(
        'BTCUSDT',
        {'side': 'BUY', 'type': 'LIMIT', 'price': '50000', 'quantity': '0.001'}
    )
```

### Funding Rate Monitor

```python
async with MEXC.new() as client:
    rate = await client.futures.funding_rate(symbol='BTC_USDT')
    print(f"Funding rate: {rate['fundingRate']}")
```

## Error Handling

```python
from mexc import MEXC
from mexc.core import ApiError, ValidationError, NetworkError

async with MEXC.new() as client:
    try:
        account = await client.spot.account()
    except ValidationError:
        # API response doesn't match expected schema
        pass
    except ApiError as e:
        # MEXC API returned an error
        print(f"API Error: {e}")
    except NetworkError:
        # Network/connection issue
        pass
```

## Contributing

This is a work in progress! Contributions are welcome. The codebase is designed to be:

- **Consistent**: All endpoints follow the same patterns
- **Type-safe**: Everything is fully typed
- **Validated**: Pydantic models for all responses

---

Inspired by [this blog post](https://tribulnation.com/blog/clients) on building better API clients.

Built with ❤️ by [Tribulnation](https://tribulnation.com)
