# Python SDK

### Overview

Official Python SDK for the Infoway real-time financial data API, providing REST API and WebSocket streaming interfaces across stocks, crypto, forex, and more.

| Item    | Details                                                                             |
| ------- | ----------------------------------------------------------------------------------- |
| PyPI    | [`infoway-sdk`](https://pypi.org/project/infoway-sdk/)                              |
| Python  | 3.9+                                                                                |
| License | MIT                                                                                 |
| GitHub  | [infoway-api/infoway-sdk-python](https://github.com/infoway-api/infoway-sdk-python) |

### Installation

```bash
pip install infoway-sdk
```

### Quick Start

```python
from infoway import InfowayClient, KlineType

client = InfowayClient(api_key="YOUR_API_KEY")

# Real-time trades
trades = client.stock.get_trade("AAPL.US")

# Crypto daily K-lines
klines = client.crypto.get_kline("BTCUSDT", kline_type=KlineType.DAY, count=30)

# Market temperature
temp = client.market.get_temperature(market="HK,US")

# Industry sector ranking
plates = client.plate.get_industry("HK", limit=10)
```

### Configuration

Pass `api_key` directly or set it via environment variable:

```bash
export INFOWAY_API_KEY="YOUR_API_KEY"
```

```python
# Reads INFOWAY_API_KEY from environment automatically
client = InfowayClient()
```

#### Client Options

```python
client = InfowayClient(
    api_key="YOUR_API_KEY",
    base_url="https://data.infoway.io",  # default
    timeout=15.0,                         # request timeout in seconds
    max_retries=3,                        # retry count for failed requests
)
```

### REST API Modules

| Module     | Accessor            | Description                                           |
| ---------- | ------------------- | ----------------------------------------------------- |
| Stock      | `client.stock`      | HK, US, CN equities — trade, depth, K-line            |
| Crypto     | `client.crypto`     | Cryptocurrency — trade, depth, K-line                 |
| Japan      | `client.japan`      | Japan market — trade, depth, K-line                   |
| India      | `client.india`      | India market — trade, depth, K-line                   |
| Common     | `client.common`     | Cross-market — trade, depth, K-line                   |
| Basic      | `client.basic`      | Symbol lists, trading days, hours, adjustment factors |
| Market     | `client.market`     | Temperature, breadth, indexes, leaders, rank config   |
| Plate      | `client.plate`      | Industry/concept sectors, members, heatmap            |
| Stock Info | `client.stock_info` | Fundamentals — valuation, ratings, company, panorama  |

#### Market Data Methods (stock / crypto / japan / india / common)

| Method                                | Description              |
| ------------------------------------- | ------------------------ |
| `get_trade(codes)`                    | Get real-time trade data |
| `get_depth(codes)`                    | Get order book depth     |
| `get_kline(codes, kline_type, count)` | Get K-line (OHLCV) data  |

#### Basic Info Methods

```python
client.basic.get_symbols("US")             # Symbol list
client.basic.get_symbol_info("AAPL.US")    # Symbol details
client.basic.get_trading_days("US")        # Trading calendar
client.basic.get_trading_hours("US")       # Trading hours
client.basic.get_adjustment_factors("AAPL.US")  # Adjustment factors
```

#### Market Overview Methods

```python
client.market.get_temperature("HK,US")    # Market temperature / sentiment
client.market.get_breadth("US")            # Advance / decline stats
client.market.get_indexes()                # Major global indexes
client.market.get_leaders("US", limit=10)  # Leading industries
client.market.get_rank_config("US")        # Ranking configuration
```

#### Plate / Sector Methods

```python
client.plate.get_industry("HK", limit=200)         # Industry sector list
client.plate.get_concept("HK", limit=100)           # Concept sector list
client.plate.get_members("IN20293.HK")              # Sector constituents
client.plate.get_intro("IN20293.HK")                # Industry introduction
client.plate.get_chart("HK", limit=50)              # Sector heatmap
```

#### Stock Fundamental Methods

```python
client.stock_info.get_valuation("AAPL.US")   # Valuation data
client.stock_info.get_ratings("AAPL.US")     # Institutional ratings
client.stock_info.get_company("AAPL.US")     # Company overview
client.stock_info.get_panorama("AAPL.US")    # Stock panorama
client.stock_info.get_concepts("AAPL.US")    # Concept tags
client.stock_info.get_events("AAPL.US", limit=20)  # Corporate events
client.stock_info.get_drivers("AAPL.US")     # Key drivers analysis
```

### WebSocket Streaming

```python
import asyncio
from infoway.ws import InfowayWebSocket

async def main():
    ws = InfowayWebSocket(api_key="YOUR_API_KEY", business="stock")

    async def on_trade(msg):
        print(f"Trade: {msg}")

    ws.on_trade = on_trade
    await ws.subscribe_trade("AAPL.US,TSLA.US")
    await ws.connect()

asyncio.run(main())
```

#### WebSocket Features

* **Auto-reconnect** with exponential backoff (1s to 30s cap)
* **Heartbeat keepalive** at 30-second intervals
* **Auto-resubscribe** on reconnect — no manual re-subscription needed
* Event callbacks: `on_trade`, `on_depth`, `on_kline`, `on_error`, `on_reconnect`, `on_disconnect`

#### WebSocket Message Codes

Client → server (subscribe / heartbeat):

| Code  | Name         | Description                                                                                                    |
| ----- | ------------ | -------------------------------------------------------------------------------------------------------------- |
| 10000 | SUB\_TRADE   | Subscribe to trade data                                                                                        |
| 10003 | SUB\_DEPTH   | Subscribe to depth data                                                                                        |
| 10006 | SUB\_KLINE   | Subscribe to K-line data (payload `data.arr=[{codes, type}]`, where `type` is the K-line interval — see below) |
| 10010 | HEARTBEAT    | Heartbeat keepalive                                                                                            |
| 11000 | UNSUB\_TRADE | Unsubscribe trade data                                                                                         |
| 11001 | UNSUB\_DEPTH | Unsubscribe depth data                                                                                         |
| 11002 | UNSUB\_KLINE | Unsubscribe K-line data                                                                                        |

Server → client (acks / pushes):

| Code  | Name            | Description                      |
| ----- | --------------- | -------------------------------- |
| 10001 | SUB\_TRADE\_ACK | Trade subscribe acknowledgement  |
| 10002 | PUSH\_TRADE     | **Real-time trade push**         |
| 10004 | SUB\_DEPTH\_ACK | Depth subscribe acknowledgement  |
| 10005 | PUSH\_DEPTH     | **Real-time depth push**         |
| 10007 | SUB\_KLINE\_ACK | K-line subscribe acknowledgement |
| 10008 | PUSH\_KLINE     | **Real-time K-line push**        |
| 11010 | UNSUB\_ACK      | Unsubscribe acknowledgement      |

#### K-line Types

| Enum                     | Interval   |
| ------------------------ | ---------- |
| `KlineType.MIN_1` (1)    | 1 minute   |
| `KlineType.MIN_5` (2)    | 5 minutes  |
| `KlineType.MIN_15` (3)   | 15 minutes |
| `KlineType.MIN_30` (4)   | 30 minutes |
| `KlineType.HOUR_1` (5)   | 1 hour     |
| `KlineType.HOUR_2` (6)   | 2 hours    |
| `KlineType.HOUR_4` (7)   | 4 hours    |
| `KlineType.DAY` (8)      | 1 day      |
| `KlineType.WEEK` (9)     | 1 week     |
| `KlineType.MONTH` (10)   | 1 month    |
| `KlineType.QUARTER` (11) | 1 quarter  |
| `KlineType.YEAR` (12)    | 1 year     |

### Error Handling

```python
from infoway import InfowayClient, InfowayAPIError, InfowayAuthError, InfowayTimeoutError

client = InfowayClient(api_key="YOUR_API_KEY")

try:
    trades = client.stock.get_trade("AAPL.US")
except InfowayAuthError:
    print("Invalid API key")
except InfowayTimeoutError:
    print("Request timed out")
except InfowayAPIError as e:
    print(f"API error [{e.ret}]: {e.msg}")
```

***


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.infoway.io/en-docs/sdk-and-tools/python-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
