infoway-sdk 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. infoway_sdk-0.1.0/.gitignore +9 -0
  2. infoway_sdk-0.1.0/PKG-INFO +150 -0
  3. infoway_sdk-0.1.0/README.md +125 -0
  4. infoway_sdk-0.1.0/README_CN.md +122 -0
  5. infoway_sdk-0.1.0/pyproject.toml +46 -0
  6. infoway_sdk-0.1.0/src/infoway/__init__.py +17 -0
  7. infoway_sdk-0.1.0/src/infoway/_http.py +84 -0
  8. infoway_sdk-0.1.0/src/infoway/_types.py +39 -0
  9. infoway_sdk-0.1.0/src/infoway/_version.py +1 -0
  10. infoway_sdk-0.1.0/src/infoway/client.py +57 -0
  11. infoway_sdk-0.1.0/src/infoway/exceptions.py +22 -0
  12. infoway_sdk-0.1.0/src/infoway/rest/__init__.py +0 -0
  13. infoway_sdk-0.1.0/src/infoway/rest/_market_data.py +44 -0
  14. infoway_sdk-0.1.0/src/infoway/rest/basic.py +29 -0
  15. infoway_sdk-0.1.0/src/infoway/rest/common.py +15 -0
  16. infoway_sdk-0.1.0/src/infoway/rest/crypto.py +15 -0
  17. infoway_sdk-0.1.0/src/infoway/rest/india.py +15 -0
  18. infoway_sdk-0.1.0/src/infoway/rest/japan.py +15 -0
  19. infoway_sdk-0.1.0/src/infoway/rest/market.py +27 -0
  20. infoway_sdk-0.1.0/src/infoway/rest/plate.py +27 -0
  21. infoway_sdk-0.1.0/src/infoway/rest/stock.py +15 -0
  22. infoway_sdk-0.1.0/src/infoway/rest/stock_info.py +33 -0
  23. infoway_sdk-0.1.0/src/infoway/ws/__init__.py +3 -0
  24. infoway_sdk-0.1.0/src/infoway/ws/client.py +195 -0
  25. infoway_sdk-0.1.0/tests/__init__.py +0 -0
  26. infoway_sdk-0.1.0/tests/conftest.py +7 -0
  27. infoway_sdk-0.1.0/tests/test_basic.py +38 -0
  28. infoway_sdk-0.1.0/tests/test_client.py +29 -0
  29. infoway_sdk-0.1.0/tests/test_crypto.py +33 -0
  30. infoway_sdk-0.1.0/tests/test_exceptions.py +27 -0
  31. infoway_sdk-0.1.0/tests/test_http.py +78 -0
  32. infoway_sdk-0.1.0/tests/test_market.py +37 -0
  33. infoway_sdk-0.1.0/tests/test_plate.py +37 -0
  34. infoway_sdk-0.1.0/tests/test_stock.py +74 -0
  35. infoway_sdk-0.1.0/tests/test_stock_info.py +49 -0
  36. infoway_sdk-0.1.0/tests/test_ws.py +54 -0
@@ -0,0 +1,9 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ dist/
5
+ build/
6
+ .env
7
+ *.log
8
+ .venv/
9
+ .pytest_cache/
@@ -0,0 +1,150 @@
1
+ Metadata-Version: 2.4
2
+ Name: infoway-sdk
3
+ Version: 0.1.0
4
+ Summary: Official Python SDK for Infoway real-time financial data API
5
+ Project-URL: Homepage, https://infoway.io
6
+ Project-URL: Documentation, https://docs.infoway.io
7
+ Project-URL: Repository, https://github.com/infoway-io/infoway-sdk-python
8
+ Author-email: Infoway <dev@infoway.io>
9
+ License-Expression: MIT
10
+ Keywords: crypto,finance,forex,market-data,real-time,stock,websocket
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Financial and Insurance Industry
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Topic :: Office/Business :: Financial :: Investment
17
+ Requires-Python: >=3.9
18
+ Requires-Dist: httpx>=0.27
19
+ Requires-Dist: websockets>=12.0
20
+ Provides-Extra: dev
21
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
22
+ Requires-Dist: pytest>=8.0; extra == 'dev'
23
+ Requires-Dist: respx>=0.21; extra == 'dev'
24
+ Description-Content-Type: text/markdown
25
+
26
+ # Infoway SDK
27
+
28
+ [![PyPI version](https://img.shields.io/pypi/v/infoway-sdk.svg)](https://pypi.org/project/infoway-sdk/)
29
+ [![Python](https://img.shields.io/pypi/pyversions/infoway-sdk.svg)](https://pypi.org/project/infoway-sdk/)
30
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
31
+
32
+ **English** | [中文](README_CN.md)
33
+
34
+ Official Python SDK for [Infoway](https://infoway.io) real-time financial data API. Full documentation at [docs.infoway.io](https://docs.infoway.io).
35
+
36
+ ## Installation
37
+
38
+ ```bash
39
+ pip install infoway-sdk
40
+ ```
41
+
42
+ ## Quick Start
43
+
44
+ ```python
45
+ from infoway import InfowayClient, KlineType
46
+
47
+ client = InfowayClient(api_key="YOUR_API_KEY")
48
+
49
+ # Real-time trades
50
+ trades = client.stock.get_trade("AAPL.US")
51
+
52
+ # Daily K-lines for crypto
53
+ klines = client.crypto.get_kline("BTCUSDT", kline_type=KlineType.DAY, count=30)
54
+
55
+ # Market temperature
56
+ temp = client.market.get_temperature(market="HK,US")
57
+
58
+ # Sector/plate rankings
59
+ plates = client.plate.get_industry("HK", limit=10)
60
+ ```
61
+
62
+ ## WebSocket Streaming
63
+
64
+ ```python
65
+ import asyncio
66
+ from infoway.ws import InfowayWebSocket
67
+
68
+ async def main():
69
+ ws = InfowayWebSocket(api_key="YOUR_API_KEY", business="stock")
70
+
71
+ async def on_trade(msg):
72
+ print(f"Trade: {msg}")
73
+
74
+ ws.on_trade = on_trade
75
+ await ws.subscribe_trade("AAPL.US,TSLA.US")
76
+ await ws.connect()
77
+
78
+ asyncio.run(main())
79
+ ```
80
+
81
+ ### WebSocket Features
82
+
83
+ - **Auto-reconnect** with exponential backoff (1s to 30s cap)
84
+ - **Heartbeat keepalive** at 30-second intervals
85
+ - **Auto-resubscribe** on reconnect -- no manual re-subscription needed
86
+ - Event callbacks: `on_trade`, `on_depth`, `on_kline`, `on_error`, `on_reconnect`, `on_disconnect`
87
+
88
+ ## REST API Modules
89
+
90
+ | Module | Accessor | Description |
91
+ |--------|----------|-------------|
92
+ | Stock | `client.stock` | HK, US, CN equities -- trade, depth, K-line |
93
+ | Crypto | `client.crypto` | Cryptocurrency pairs -- trade, depth, K-line |
94
+ | Japan | `client.japan` | Japan market data -- trade, depth, K-line |
95
+ | India | `client.india` | India market data -- trade, depth, K-line |
96
+ | Common | `client.common` | Cross-market data -- trade, depth, K-line |
97
+ | Basic | `client.basic` | Symbol lists, trading days, trading hours, adjustment factors |
98
+ | Market | `client.market` | Market temperature, breadth, indexes, leaders, rank config |
99
+ | Plate | `client.plate` | Sector/industry/concept plates, members, charts |
100
+ | Stock Info | `client.stock_info` | Fundamentals -- valuation, ratings, company, panorama, events |
101
+
102
+ ## Configuration
103
+
104
+ You can pass `api_key` directly or set it via environment variable:
105
+
106
+ ```bash
107
+ export INFOWAY_API_KEY="YOUR_API_KEY"
108
+ ```
109
+
110
+ ```python
111
+ # Reads INFOWAY_API_KEY from environment automatically
112
+ client = InfowayClient()
113
+ ```
114
+
115
+ ### Client Options
116
+
117
+ ```python
118
+ client = InfowayClient(
119
+ api_key="YOUR_API_KEY",
120
+ base_url="https://data.infoway.io", # default
121
+ timeout=15.0, # request timeout in seconds
122
+ max_retries=3, # retry count for failed requests
123
+ )
124
+ ```
125
+
126
+ ## Error Handling
127
+
128
+ ```python
129
+ from infoway import InfowayClient, InfowayAPIError, InfowayAuthError, InfowayTimeoutError
130
+
131
+ client = InfowayClient(api_key="YOUR_API_KEY")
132
+
133
+ try:
134
+ trades = client.stock.get_trade("AAPL.US")
135
+ except InfowayAuthError:
136
+ print("Invalid API key")
137
+ except InfowayTimeoutError:
138
+ print("Request timed out")
139
+ except InfowayAPIError as e:
140
+ print(f"API error [{e.ret}]: {e.msg}")
141
+ ```
142
+
143
+ ## License
144
+
145
+ MIT
146
+
147
+ ---
148
+
149
+ Get your free API key at [infoway.io](https://infoway.io) -- 7-day free trial, no credit card required.
150
+
@@ -0,0 +1,125 @@
1
+ # Infoway SDK
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/infoway-sdk.svg)](https://pypi.org/project/infoway-sdk/)
4
+ [![Python](https://img.shields.io/pypi/pyversions/infoway-sdk.svg)](https://pypi.org/project/infoway-sdk/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ **English** | [中文](README_CN.md)
8
+
9
+ Official Python SDK for [Infoway](https://infoway.io) real-time financial data API. Full documentation at [docs.infoway.io](https://docs.infoway.io).
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ pip install infoway-sdk
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ ```python
20
+ from infoway import InfowayClient, KlineType
21
+
22
+ client = InfowayClient(api_key="YOUR_API_KEY")
23
+
24
+ # Real-time trades
25
+ trades = client.stock.get_trade("AAPL.US")
26
+
27
+ # Daily K-lines for crypto
28
+ klines = client.crypto.get_kline("BTCUSDT", kline_type=KlineType.DAY, count=30)
29
+
30
+ # Market temperature
31
+ temp = client.market.get_temperature(market="HK,US")
32
+
33
+ # Sector/plate rankings
34
+ plates = client.plate.get_industry("HK", limit=10)
35
+ ```
36
+
37
+ ## WebSocket Streaming
38
+
39
+ ```python
40
+ import asyncio
41
+ from infoway.ws import InfowayWebSocket
42
+
43
+ async def main():
44
+ ws = InfowayWebSocket(api_key="YOUR_API_KEY", business="stock")
45
+
46
+ async def on_trade(msg):
47
+ print(f"Trade: {msg}")
48
+
49
+ ws.on_trade = on_trade
50
+ await ws.subscribe_trade("AAPL.US,TSLA.US")
51
+ await ws.connect()
52
+
53
+ asyncio.run(main())
54
+ ```
55
+
56
+ ### WebSocket Features
57
+
58
+ - **Auto-reconnect** with exponential backoff (1s to 30s cap)
59
+ - **Heartbeat keepalive** at 30-second intervals
60
+ - **Auto-resubscribe** on reconnect -- no manual re-subscription needed
61
+ - Event callbacks: `on_trade`, `on_depth`, `on_kline`, `on_error`, `on_reconnect`, `on_disconnect`
62
+
63
+ ## REST API Modules
64
+
65
+ | Module | Accessor | Description |
66
+ |--------|----------|-------------|
67
+ | Stock | `client.stock` | HK, US, CN equities -- trade, depth, K-line |
68
+ | Crypto | `client.crypto` | Cryptocurrency pairs -- trade, depth, K-line |
69
+ | Japan | `client.japan` | Japan market data -- trade, depth, K-line |
70
+ | India | `client.india` | India market data -- trade, depth, K-line |
71
+ | Common | `client.common` | Cross-market data -- trade, depth, K-line |
72
+ | Basic | `client.basic` | Symbol lists, trading days, trading hours, adjustment factors |
73
+ | Market | `client.market` | Market temperature, breadth, indexes, leaders, rank config |
74
+ | Plate | `client.plate` | Sector/industry/concept plates, members, charts |
75
+ | Stock Info | `client.stock_info` | Fundamentals -- valuation, ratings, company, panorama, events |
76
+
77
+ ## Configuration
78
+
79
+ You can pass `api_key` directly or set it via environment variable:
80
+
81
+ ```bash
82
+ export INFOWAY_API_KEY="YOUR_API_KEY"
83
+ ```
84
+
85
+ ```python
86
+ # Reads INFOWAY_API_KEY from environment automatically
87
+ client = InfowayClient()
88
+ ```
89
+
90
+ ### Client Options
91
+
92
+ ```python
93
+ client = InfowayClient(
94
+ api_key="YOUR_API_KEY",
95
+ base_url="https://data.infoway.io", # default
96
+ timeout=15.0, # request timeout in seconds
97
+ max_retries=3, # retry count for failed requests
98
+ )
99
+ ```
100
+
101
+ ## Error Handling
102
+
103
+ ```python
104
+ from infoway import InfowayClient, InfowayAPIError, InfowayAuthError, InfowayTimeoutError
105
+
106
+ client = InfowayClient(api_key="YOUR_API_KEY")
107
+
108
+ try:
109
+ trades = client.stock.get_trade("AAPL.US")
110
+ except InfowayAuthError:
111
+ print("Invalid API key")
112
+ except InfowayTimeoutError:
113
+ print("Request timed out")
114
+ except InfowayAPIError as e:
115
+ print(f"API error [{e.ret}]: {e.msg}")
116
+ ```
117
+
118
+ ## License
119
+
120
+ MIT
121
+
122
+ ---
123
+
124
+ Get your free API key at [infoway.io](https://infoway.io) -- 7-day free trial, no credit card required.
125
+
@@ -0,0 +1,122 @@
1
+ # Infoway SDK (中文)
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/infoway-sdk.svg)](https://pypi.org/project/infoway-sdk/)
4
+ [![Python](https://img.shields.io/pypi/pyversions/infoway-sdk.svg)](https://pypi.org/project/infoway-sdk/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ [English](README.md) | **中文**
8
+
9
+ [Infoway](https://infoway.io) 实时金融数据 API 的官方 Python SDK。完整文档请访问 [docs.infoway.io](https://docs.infoway.io)。
10
+
11
+ ## 安装
12
+
13
+ ```bash
14
+ pip install infoway-sdk
15
+ ```
16
+
17
+ ## 快速开始
18
+
19
+ ```python
20
+ from infoway import InfowayClient, KlineType
21
+
22
+ client = InfowayClient(api_key="YOUR_API_KEY")
23
+
24
+ # 实时成交数据
25
+ trades = client.stock.get_trade("AAPL.US")
26
+
27
+ # 加密货币日K线
28
+ klines = client.crypto.get_kline("BTCUSDT", kline_type=KlineType.DAY, count=30)
29
+
30
+ # 市场温度
31
+ temp = client.market.get_temperature(market="HK,US")
32
+
33
+ # 板块排行
34
+ plates = client.plate.get_industry("HK", limit=10)
35
+ ```
36
+
37
+ ## WebSocket 实时推送
38
+
39
+ ```python
40
+ import asyncio
41
+ from infoway.ws import InfowayWebSocket
42
+
43
+ async def main():
44
+ ws = InfowayWebSocket(api_key="YOUR_API_KEY", business="stock")
45
+
46
+ async def on_trade(msg):
47
+ print(f"成交: {msg}")
48
+
49
+ ws.on_trade = on_trade
50
+ await ws.subscribe_trade("AAPL.US,TSLA.US")
51
+ await ws.connect()
52
+
53
+ asyncio.run(main())
54
+ ```
55
+
56
+ ### 特性
57
+
58
+ - **自动重连** -- 指数退避策略(1秒至30秒上限)
59
+ - **心跳保活** -- 每30秒自动发送心跳
60
+ - **自动重新订阅** -- 重连后自动恢复所有订阅,无需手动处理
61
+ - 事件回调:`on_trade`、`on_depth`、`on_kline`、`on_error`、`on_reconnect`、`on_disconnect`
62
+
63
+ ## REST API 模块
64
+
65
+ | 模块 | 访问方式 | 说明 |
66
+ |------|----------|------|
67
+ | Stock | `client.stock` | 港股、美股、A股 -- 成交、深度、K线 |
68
+ | Crypto | `client.crypto` | 加密货币 -- 成交、深度、K线 |
69
+ | Japan | `client.japan` | 日本市场 -- 成交、深度、K线 |
70
+ | India | `client.india` | 印度市场 -- 成交、深度、K线 |
71
+ | Common | `client.common` | 跨市场数据 -- 成交、深度、K线 |
72
+ | Basic | `client.basic` | 标的列表、交易日、交易时间、复权因子 |
73
+ | Market | `client.market` | 市场温度、市场宽度、指数、龙头股、排行配置 |
74
+ | Plate | `client.plate` | 行业/概念板块、成分股、板块图表 |
75
+ | Stock Info | `client.stock_info` | 基本面 -- 估值、评级、公司概况、全景、事件 |
76
+
77
+ ## 环境变量
78
+
79
+ ```bash
80
+ export INFOWAY_API_KEY="YOUR_API_KEY"
81
+ ```
82
+
83
+ ```python
84
+ # 自动从环境变量读取 INFOWAY_API_KEY
85
+ client = InfowayClient()
86
+ ```
87
+
88
+ ### 客户端配置
89
+
90
+ ```python
91
+ client = InfowayClient(
92
+ api_key="YOUR_API_KEY",
93
+ base_url="https://data.infoway.io", # 默认值
94
+ timeout=15.0, # 请求超时(秒)
95
+ max_retries=3, # 失败重试次数
96
+ )
97
+ ```
98
+
99
+ ## 错误处理
100
+
101
+ ```python
102
+ from infoway import InfowayClient, InfowayAPIError, InfowayAuthError, InfowayTimeoutError
103
+
104
+ client = InfowayClient(api_key="YOUR_API_KEY")
105
+
106
+ try:
107
+ trades = client.stock.get_trade("AAPL.US")
108
+ except InfowayAuthError:
109
+ print("API Key 无效")
110
+ except InfowayTimeoutError:
111
+ print("请求超时")
112
+ except InfowayAPIError as e:
113
+ print(f"API 错误 [{e.ret}]: {e.msg}")
114
+ ```
115
+
116
+ ## 许可证
117
+
118
+ MIT
119
+
120
+ ---
121
+
122
+ 在 [infoway.io](https://infoway.io) 获取免费 API Key -- 7天免费试用,无需信用卡。
@@ -0,0 +1,46 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "infoway-sdk"
7
+ dynamic = ["version"]
8
+ description = "Official Python SDK for Infoway real-time financial data API"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.9"
12
+ authors = [{ name = "Infoway", email = "dev@infoway.io" }]
13
+ keywords = ["finance", "stock", "crypto", "forex", "market-data", "websocket", "real-time"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Developers",
17
+ "Intended Audience :: Financial and Insurance Industry",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Programming Language :: Python :: 3",
20
+ "Topic :: Office/Business :: Financial :: Investment",
21
+ ]
22
+ dependencies = [
23
+ "httpx>=0.27",
24
+ "websockets>=12.0",
25
+ ]
26
+
27
+ [project.optional-dependencies]
28
+ dev = [
29
+ "pytest>=8.0",
30
+ "pytest-asyncio>=0.23",
31
+ "respx>=0.21",
32
+ ]
33
+
34
+ [project.urls]
35
+ Homepage = "https://infoway.io"
36
+ Documentation = "https://docs.infoway.io"
37
+ Repository = "https://github.com/infoway-io/infoway-sdk-python"
38
+
39
+ [tool.hatch.version]
40
+ path = "src/infoway/_version.py"
41
+
42
+ [tool.hatch.build.targets.wheel]
43
+ packages = ["src/infoway"]
44
+
45
+ [tool.pytest.ini_options]
46
+ asyncio_mode = "auto"
@@ -0,0 +1,17 @@
1
+ """Infoway SDK — Official Python client for Infoway real-time financial data API."""
2
+
3
+ from infoway._version import __version__
4
+ from infoway.client import InfowayClient
5
+ from infoway.exceptions import InfowayAPIError, InfowayAuthError, InfowayTimeoutError
6
+ from infoway._types import KlineType, Business, WsCode
7
+
8
+ __all__ = [
9
+ "__version__",
10
+ "InfowayClient",
11
+ "InfowayAPIError",
12
+ "InfowayAuthError",
13
+ "InfowayTimeoutError",
14
+ "KlineType",
15
+ "Business",
16
+ "WsCode",
17
+ ]
@@ -0,0 +1,84 @@
1
+ """Low-level HTTP client with retry and error handling."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import logging
6
+ import os
7
+ import time
8
+ from typing import Any
9
+
10
+ import httpx
11
+
12
+ from infoway.exceptions import InfowayAPIError, InfowayAuthError, InfowayTimeoutError
13
+
14
+ logger = logging.getLogger("infoway")
15
+
16
+ _DEFAULT_BASE_URL = "https://data.infoway.io"
17
+ _DEFAULT_TIMEOUT = 15.0
18
+ _DEFAULT_RETRIES = 3
19
+
20
+
21
+ class HttpClient:
22
+ """HTTP client wrapping httpx with auth, retry, and Infoway error handling."""
23
+
24
+ def __init__(
25
+ self,
26
+ api_key: str | None = None,
27
+ base_url: str = _DEFAULT_BASE_URL,
28
+ timeout: float = _DEFAULT_TIMEOUT,
29
+ max_retries: int = _DEFAULT_RETRIES,
30
+ ):
31
+ self._api_key = api_key or os.getenv("INFOWAY_API_KEY", "")
32
+ self._base_url = base_url.rstrip("/")
33
+ self._timeout = timeout
34
+ self._max_retries = max_retries
35
+ self._client = httpx.Client(
36
+ base_url=self._base_url,
37
+ headers={"apiKey": self._api_key},
38
+ timeout=self._timeout,
39
+ )
40
+
41
+ def get(self, path: str, params: dict[str, Any] | None = None) -> Any:
42
+ return self._request("GET", path, params=params)
43
+
44
+ def post(self, path: str, json: dict[str, Any] | None = None) -> Any:
45
+ return self._request("POST", path, json=json)
46
+
47
+ def _request(self, method: str, path: str, **kwargs: Any) -> Any:
48
+ last_exc: Exception | None = None
49
+ for attempt in range(self._max_retries):
50
+ try:
51
+ resp = self._client.request(method, path, **kwargs)
52
+ return self._handle_response(resp)
53
+ except (InfowayAPIError, InfowayAuthError):
54
+ raise
55
+ except httpx.TimeoutException as e:
56
+ last_exc = InfowayTimeoutError(str(e))
57
+ except httpx.HTTPError as e:
58
+ last_exc = e
59
+ logger.debug("Request failed (attempt %d/%d): %s", attempt + 1, self._max_retries, e)
60
+ if attempt < self._max_retries - 1:
61
+ time.sleep(min(2 ** attempt, 8))
62
+ raise last_exc
63
+
64
+ def _handle_response(self, resp: httpx.Response) -> Any:
65
+ if resp.status_code == 401:
66
+ raise InfowayAuthError()
67
+ data = resp.json()
68
+ ret = data.get("ret") or data.get("code", 200)
69
+ msg = data.get("msg", "")
70
+ trace_id = data.get("traceId")
71
+ if ret == 401:
72
+ raise InfowayAuthError(msg)
73
+ if ret != 200:
74
+ raise InfowayAPIError(ret=ret, msg=msg, trace_id=trace_id)
75
+ return data.get("data")
76
+
77
+ def close(self):
78
+ self._client.close()
79
+
80
+ def __enter__(self):
81
+ return self
82
+
83
+ def __exit__(self, *args: Any):
84
+ self.close()
@@ -0,0 +1,39 @@
1
+ """Shared type definitions and enums."""
2
+
3
+ from enum import IntEnum
4
+
5
+
6
+ class KlineType(IntEnum):
7
+ MIN_1 = 1
8
+ MIN_5 = 2
9
+ MIN_15 = 3
10
+ MIN_30 = 4
11
+ HOUR_1 = 5
12
+ HOUR_2 = 6
13
+ HOUR_4 = 7
14
+ DAY = 8
15
+ WEEK = 9
16
+ MONTH = 10
17
+ QUARTER = 11
18
+ YEAR = 12
19
+
20
+
21
+ class Business(str):
22
+ STOCK = "stock"
23
+ JAPAN = "japan"
24
+ INDIA = "india"
25
+ CRYPTO = "crypto"
26
+ COMMON = "common"
27
+
28
+
29
+ class WsCode(IntEnum):
30
+ SUB_TRADE = 10000
31
+ PUSH_TRADE = 10001
32
+ UNSUB_TRADE = 10002
33
+ SUB_DEPTH = 10003
34
+ PUSH_DEPTH = 10004
35
+ UNSUB_DEPTH = 10005
36
+ SUB_KLINE = 10006
37
+ PUSH_KLINE = 10007
38
+ UNSUB_KLINE = 10008
39
+ HEARTBEAT = 10010
@@ -0,0 +1 @@
1
+ __version__ = "0.1.0"
@@ -0,0 +1,57 @@
1
+ """Main entry point for the Infoway SDK."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from infoway._http import HttpClient
6
+ from infoway.rest.stock import StockClient
7
+ from infoway.rest.crypto import CryptoClient
8
+ from infoway.rest.japan import JapanClient
9
+ from infoway.rest.india import IndiaClient
10
+ from infoway.rest.common import CommonClient
11
+ from infoway.rest.basic import BasicClient
12
+ from infoway.rest.market import MarketClient
13
+ from infoway.rest.plate import PlateClient
14
+ from infoway.rest.stock_info import StockInfoClient
15
+
16
+
17
+ class InfowayClient:
18
+ """Infoway API client.
19
+
20
+ Usage::
21
+
22
+ from infoway import InfowayClient
23
+
24
+ client = InfowayClient(api_key="YOUR_API_KEY")
25
+ trades = client.stock.get_trade("AAPL.US")
26
+ klines = client.crypto.get_kline("BTCUSDT", kline_type=8, count=100)
27
+ temp = client.market.get_temperature(market="HK,US")
28
+ """
29
+
30
+ def __init__(
31
+ self,
32
+ api_key: str | None = None,
33
+ base_url: str = "https://data.infoway.io",
34
+ timeout: float = 15.0,
35
+ max_retries: int = 3,
36
+ ):
37
+ self._http = HttpClient(
38
+ api_key=api_key, base_url=base_url, timeout=timeout, max_retries=max_retries,
39
+ )
40
+ self.stock = StockClient(self._http)
41
+ self.crypto = CryptoClient(self._http)
42
+ self.japan = JapanClient(self._http)
43
+ self.india = IndiaClient(self._http)
44
+ self.common = CommonClient(self._http)
45
+ self.basic = BasicClient(self._http)
46
+ self.market = MarketClient(self._http)
47
+ self.plate = PlateClient(self._http)
48
+ self.stock_info = StockInfoClient(self._http)
49
+
50
+ def close(self):
51
+ self._http.close()
52
+
53
+ def __enter__(self):
54
+ return self
55
+
56
+ def __exit__(self, *args):
57
+ self.close()
@@ -0,0 +1,22 @@
1
+ """Infoway SDK exception types."""
2
+
3
+
4
+ class InfowayTimeoutError(Exception):
5
+ """Raised when a request times out."""
6
+
7
+
8
+ class InfowayAPIError(Exception):
9
+ """Raised when the API returns a non-success response."""
10
+
11
+ def __init__(self, ret: int, msg: str, trace_id: str | None = None):
12
+ self.ret = ret
13
+ self.msg = msg
14
+ self.trace_id = trace_id
15
+ super().__init__(f"[{ret}] {msg}" + (f" (trace: {trace_id})" if trace_id else ""))
16
+
17
+
18
+ class InfowayAuthError(InfowayAPIError):
19
+ """Raised on 401 Unauthorized."""
20
+
21
+ def __init__(self, msg: str = "Unauthorized"):
22
+ super().__init__(ret=401, msg=msg)
File without changes