binance-common 1.0.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.
- binance_common-1.0.0/CHANGELOG.md +5 -0
- binance_common-1.0.0/LICENCE +21 -0
- binance_common-1.0.0/PKG-INFO +62 -0
- binance_common-1.0.0/README.md +36 -0
- binance_common-1.0.0/pyproject.toml +40 -0
- binance_common-1.0.0/src/binance_common/__init__.py +0 -0
- binance_common-1.0.0/src/binance_common/configuration.py +190 -0
- binance_common-1.0.0/src/binance_common/constants.py +115 -0
- binance_common-1.0.0/src/binance_common/errors.py +104 -0
- binance_common-1.0.0/src/binance_common/logger.py +69 -0
- binance_common-1.0.0/src/binance_common/models.py +92 -0
- binance_common-1.0.0/src/binance_common/signature.py +76 -0
- binance_common-1.0.0/src/binance_common/utils.py +559 -0
- binance_common-1.0.0/src/binance_common/websocket.py +732 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) [2025] [Binance]
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: binance-common
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Binance Common Types and Utilities for Binance Connectors
|
|
5
|
+
License: MIT
|
|
6
|
+
Author: Binance
|
|
7
|
+
Requires-Python: >=3.9,<=3.13
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Provides-Extra: dev
|
|
16
|
+
Requires-Dist: aiohttp (>=3.9,<4.0)
|
|
17
|
+
Requires-Dist: black (>=25.1.0,<26.0.0)
|
|
18
|
+
Requires-Dist: pycryptodome (>=3.17,<4.0)
|
|
19
|
+
Requires-Dist: pydantic (>=2.10.0)
|
|
20
|
+
Requires-Dist: pytest (>=6.2.5) ; extra == "dev"
|
|
21
|
+
Requires-Dist: requests (>=2.31.0)
|
|
22
|
+
Requires-Dist: ruff (>=0.12.0,<0.13.0)
|
|
23
|
+
Requires-Dist: websockets (>=15.0.1,<16.0.0)
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# Binance Common Types and Utilities for Binance Connectors
|
|
27
|
+
|
|
28
|
+
[](https://black.readthedocs.io/en/stable/)
|
|
29
|
+
[](https://pypi.python.org/pypi/binance-common)
|
|
30
|
+
[](https://pypi.org/project/binance-common/)
|
|
31
|
+
[](https://www.python.org/downloads/)
|
|
32
|
+
[](https://github.com/binance/binance-connector-python/security)
|
|
33
|
+
[](https://opensource.org/licenses/MIT)
|
|
34
|
+
|
|
35
|
+
`binance-common` is a **utility package** for Binance modular connectors, providing commonly used functions and helpers for working with Binance REST/WebSocket APIs. It ensures reusable and optimized utilities to streamline development.
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
To use this library, ensure your environment is running Python version **3.9** or later.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install binance-common
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Features
|
|
46
|
+
|
|
47
|
+
- **Common Utility Functions** for API requests, timestamps, and signatures.
|
|
48
|
+
- **Optimized for Binance Connectors** to ensure seamless integration.
|
|
49
|
+
- **Lightweight & Tree-Shakeable** – only imports what you need.
|
|
50
|
+
|
|
51
|
+
## Contributing
|
|
52
|
+
|
|
53
|
+
Contributions are welcome!
|
|
54
|
+
|
|
55
|
+
1. Open a GitHub issue before making changes.
|
|
56
|
+
2. Discuss proposed changes with maintainers.
|
|
57
|
+
3. Follow the existing TypeScript structure.
|
|
58
|
+
|
|
59
|
+
## License
|
|
60
|
+
|
|
61
|
+
This project is licensed under the MIT License - see the [LICENSE](./LICENCE) file for details.
|
|
62
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Binance Common Types and Utilities for Binance Connectors
|
|
2
|
+
|
|
3
|
+
[](https://black.readthedocs.io/en/stable/)
|
|
4
|
+
[](https://pypi.python.org/pypi/binance-common)
|
|
5
|
+
[](https://pypi.org/project/binance-common/)
|
|
6
|
+
[](https://www.python.org/downloads/)
|
|
7
|
+
[](https://github.com/binance/binance-connector-python/security)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
|
|
10
|
+
`binance-common` is a **utility package** for Binance modular connectors, providing commonly used functions and helpers for working with Binance REST/WebSocket APIs. It ensures reusable and optimized utilities to streamline development.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
To use this library, ensure your environment is running Python version **3.9** or later.
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install binance-common
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
- **Common Utility Functions** for API requests, timestamps, and signatures.
|
|
23
|
+
- **Optimized for Binance Connectors** to ensure seamless integration.
|
|
24
|
+
- **Lightweight & Tree-Shakeable** – only imports what you need.
|
|
25
|
+
|
|
26
|
+
## Contributing
|
|
27
|
+
|
|
28
|
+
Contributions are welcome!
|
|
29
|
+
|
|
30
|
+
1. Open a GitHub issue before making changes.
|
|
31
|
+
2. Discuss proposed changes with maintainers.
|
|
32
|
+
3. Follow the existing TypeScript structure.
|
|
33
|
+
|
|
34
|
+
## License
|
|
35
|
+
|
|
36
|
+
This project is licensed under the MIT License - see the [LICENSE](./LICENCE) file for details.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "binance-common"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
description = "Binance Common Types and Utilities for Binance Connectors"
|
|
5
|
+
authors = ["Binance"]
|
|
6
|
+
license = "MIT"
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
include = ["CHANGELOG.md", "LICENSE", "README.md"]
|
|
9
|
+
packages = [
|
|
10
|
+
{ include = "binance_common", from = "src" }
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
[tool.poetry.dependencies]
|
|
14
|
+
python = ">=3.9,<=3.13"
|
|
15
|
+
requests = ">=2.31.0"
|
|
16
|
+
pydantic = ">=2.10.0"
|
|
17
|
+
websockets = "^15.0.1"
|
|
18
|
+
black = "^25.1.0"
|
|
19
|
+
ruff = "^0.12.0"
|
|
20
|
+
pycryptodome = "^3.17"
|
|
21
|
+
aiohttp = "^3.9"
|
|
22
|
+
pytest = { version = ">=6.2.5", optional = true }
|
|
23
|
+
|
|
24
|
+
[tool.poetry.extras]
|
|
25
|
+
dev = ["pytest"]
|
|
26
|
+
|
|
27
|
+
[tool.poetry.group.dev.dependencies]
|
|
28
|
+
tox = "^4.27.0"
|
|
29
|
+
pytest = ">=8.4.1"
|
|
30
|
+
pytest-asyncio = "^1.0.0"
|
|
31
|
+
|
|
32
|
+
[build-system]
|
|
33
|
+
requires = ["poetry-core"]
|
|
34
|
+
build-backend = "poetry.core.masonry.api"
|
|
35
|
+
|
|
36
|
+
[tool.ruff]
|
|
37
|
+
exclude = [".git", ".tox", "build", "dist"]
|
|
38
|
+
|
|
39
|
+
[tool.ruff.lint]
|
|
40
|
+
ignore = ["E741"]
|
|
File without changes
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import ssl
|
|
2
|
+
|
|
3
|
+
from typing import Optional, Dict, Union
|
|
4
|
+
from http.client import HTTPSConnection
|
|
5
|
+
|
|
6
|
+
from binance_common.constants import TimeUnit, WebsocketMode
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ConfigurationRestAPI:
|
|
10
|
+
"""
|
|
11
|
+
Configuration for the Binance REST API client.
|
|
12
|
+
|
|
13
|
+
Supports:
|
|
14
|
+
- API authentication
|
|
15
|
+
- Keep-Alive
|
|
16
|
+
- Timeout handling
|
|
17
|
+
- Compression (gzip, deflate, br)
|
|
18
|
+
- HTTPS Agent
|
|
19
|
+
- Time Unit
|
|
20
|
+
- Proxy support
|
|
21
|
+
- Retries & Backoff
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
api_key: str = None,
|
|
27
|
+
api_secret: Optional[str] = None,
|
|
28
|
+
base_path: str = None,
|
|
29
|
+
timeout: int = 1000,
|
|
30
|
+
proxy: Optional[Dict[str, Union[str, int, Dict[str, str]]]] = None,
|
|
31
|
+
keep_alive: bool = True,
|
|
32
|
+
compression: bool = True,
|
|
33
|
+
retries: int = 3,
|
|
34
|
+
backoff: int = 1000,
|
|
35
|
+
https_agent: Optional[Union[bool, HTTPSConnection]] = None,
|
|
36
|
+
time_unit: Optional[str] = None,
|
|
37
|
+
private_key: Optional[Union[bytes, str]] = None,
|
|
38
|
+
private_key_passphrase: Optional[str] = None,
|
|
39
|
+
):
|
|
40
|
+
"""
|
|
41
|
+
Initialize the API configuration.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
api_key (str): API key for authentication.
|
|
45
|
+
api_secret (Optional[str]): API secret for authentication (default: None).
|
|
46
|
+
base_path (str): Base API URL (default: None).
|
|
47
|
+
timeout (int): Request timeout in milliseconds (default: 1000).
|
|
48
|
+
proxy (Optional[Dict[str, Union[str, int, Dict[str, str]]]]): Proxy settings (default: None).
|
|
49
|
+
keep_alive (bool): Enable Keep-Alive (default: True).
|
|
50
|
+
compression (bool): Enable response compression (default: True).
|
|
51
|
+
retries (int): Number of retry attempts for failed requests (default: 3).
|
|
52
|
+
backoff (int): Delay (ms) between retries (default: 1000).
|
|
53
|
+
https_agent (Optional[Union[bool, HTTPSConnection]]): Custom HTTPS Agent (default: None).
|
|
54
|
+
time_unit (Optional[str]): Time unit for time-based responses (default: None).
|
|
55
|
+
private_key (Optional[Union[bytes, str]]): Private key for authentication (default: None).
|
|
56
|
+
private_key_passphrase (Optional[str]): Passphrase for private key (default: None).
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
self.api_key = api_key
|
|
60
|
+
self.api_secret = api_secret
|
|
61
|
+
self.base_path = base_path
|
|
62
|
+
self.timeout = timeout
|
|
63
|
+
self.proxy = proxy
|
|
64
|
+
self.keep_alive = keep_alive
|
|
65
|
+
self.compression = compression
|
|
66
|
+
self.retries = retries
|
|
67
|
+
self.backoff = backoff
|
|
68
|
+
self.https_agent = https_agent
|
|
69
|
+
self.time_unit = time_unit
|
|
70
|
+
self.private_key = private_key
|
|
71
|
+
self.private_key_passphrase = private_key_passphrase
|
|
72
|
+
|
|
73
|
+
self.base_headers = {
|
|
74
|
+
"Accept": "application/json",
|
|
75
|
+
"X-MBX-APIKEY": str(self.api_key) if self.api_key else "",
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class ConfigurationWebSocketAPI:
|
|
80
|
+
"""
|
|
81
|
+
Configuration for the Binance Websocket API client.
|
|
82
|
+
|
|
83
|
+
Supports:
|
|
84
|
+
- API authentication
|
|
85
|
+
- Keep-Alive
|
|
86
|
+
- Timeout handling
|
|
87
|
+
- Compression (gzip, deflate, br)
|
|
88
|
+
- HTTPS Agent
|
|
89
|
+
- WebSocket Pool
|
|
90
|
+
- Time Unit
|
|
91
|
+
- Proxy support
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
def __init__(
|
|
95
|
+
self,
|
|
96
|
+
api_key: str = None,
|
|
97
|
+
api_secret: Optional[str] = None,
|
|
98
|
+
private_key: Optional[Union[bytes, str]] = None,
|
|
99
|
+
private_key_passphrase: Optional[str] = None,
|
|
100
|
+
stream_url: str = "wss://ws-api.binance.com/ws-api/v3",
|
|
101
|
+
timeout: int = 5,
|
|
102
|
+
reconnect_delay: int = 5,
|
|
103
|
+
compression: int = 0,
|
|
104
|
+
proxy: Optional[Dict[str, Union[str, int, Dict[str, str]]]] = None,
|
|
105
|
+
mode: WebsocketMode = WebsocketMode.SINGLE,
|
|
106
|
+
pool_size: int = 2,
|
|
107
|
+
time_unit: TimeUnit = None,
|
|
108
|
+
https_agent: Optional[ssl.SSLContext] = None,
|
|
109
|
+
):
|
|
110
|
+
"""
|
|
111
|
+
Initialize the API configuration.
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
api_key (str): API key for authentication.
|
|
115
|
+
api_secret (Optional[str]): API secret for authentication (default: None).
|
|
116
|
+
private_key (Optional[Union[bytes, str]]): Private key for authentication (default: None).
|
|
117
|
+
private_key_passphrase (Optional[str]): Passphrase for private key (default: None).
|
|
118
|
+
stream_url (str): Base WebSocket API URL (default: "wss://ws-api.binance.com/ws-api/v3").
|
|
119
|
+
timeout (int): Request timeout in milliseconds (default: 5000).
|
|
120
|
+
reconnect_delay (int): Delay (ms) between reconnections (default: 5000).
|
|
121
|
+
compression (int): Compression level (default: 0).
|
|
122
|
+
proxy (Optional[Dict[str, Union[str, int, Dict[str, str]]]]): Proxy settings (default: None).
|
|
123
|
+
mode (WebsocketMode): WebSocket mode ("single" or "pool") (default: "single").
|
|
124
|
+
pool_size (int): Number of WebSocket connections in pool (default: 2).
|
|
125
|
+
time_unit (Optional[TimeUnit]): Time unit for time-based responses (default: None).
|
|
126
|
+
https_agent (Optional[ssl.SSLContext]): Custom HTTPS Agent (default: None).
|
|
127
|
+
"""
|
|
128
|
+
|
|
129
|
+
self.api_key = api_key
|
|
130
|
+
self.api_secret = api_secret
|
|
131
|
+
self.private_key = private_key
|
|
132
|
+
self.private_key_passphrase = private_key_passphrase
|
|
133
|
+
self.stream_url = stream_url
|
|
134
|
+
self.timeout = timeout
|
|
135
|
+
self.reconnect_delay = reconnect_delay
|
|
136
|
+
self.compression = compression
|
|
137
|
+
self.proxy = proxy
|
|
138
|
+
self.mode = mode
|
|
139
|
+
self.pool_size = pool_size
|
|
140
|
+
self.time_unit = time_unit
|
|
141
|
+
self.https_agent = https_agent
|
|
142
|
+
self.user_agent = ""
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class ConfigurationWebSocketStreams:
|
|
146
|
+
"""
|
|
147
|
+
Configuration for the Binance Websocket Stream client.
|
|
148
|
+
|
|
149
|
+
Supports:
|
|
150
|
+
- Keep-Alive
|
|
151
|
+
- Compression (gzip, deflate, br)
|
|
152
|
+
- HTTPS Agent
|
|
153
|
+
- WebSocket Pool
|
|
154
|
+
- Time Unit
|
|
155
|
+
"""
|
|
156
|
+
|
|
157
|
+
def __init__(
|
|
158
|
+
self,
|
|
159
|
+
stream_url: str = "wss://stream.binance.com:9443/stream",
|
|
160
|
+
reconnect_delay: int = 5,
|
|
161
|
+
compression: int = 0,
|
|
162
|
+
proxy: Optional[Dict[str, Union[str, int, Dict[str, str]]]] = None,
|
|
163
|
+
mode: WebsocketMode = WebsocketMode.SINGLE,
|
|
164
|
+
pool_size: int = 2,
|
|
165
|
+
time_unit: TimeUnit = None,
|
|
166
|
+
https_agent: Optional[ssl.SSLContext] = None,
|
|
167
|
+
):
|
|
168
|
+
"""
|
|
169
|
+
Initialize the Websocket Stream configuration.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
stream_url (str): Base WebSocket Stream URL (default: "wss://stream.binance.com:9443").
|
|
173
|
+
reconnect_delay (int): Delay (ms) between reconnections (default: 5000).
|
|
174
|
+
compression (int): Compression level (default: 0).
|
|
175
|
+
proxy (Optional[Dict[str, Union[str, int, Dict[str, str]]]]): Proxy settings (default: None).
|
|
176
|
+
mode (WebsocketMode): WebSocket mode ("single" or "pool") (default: "single").
|
|
177
|
+
pool_size (int): Number of WebSocket connections in pool (default: 2).
|
|
178
|
+
time_unit (Optional[TimeUnit]): Time unit for time-based responses (default: None).
|
|
179
|
+
https_agent (Optional[ssl.SSLContext]): Custom HTTPS Agent (default: None).
|
|
180
|
+
"""
|
|
181
|
+
|
|
182
|
+
self.stream_url = stream_url
|
|
183
|
+
self.reconnect_delay = reconnect_delay
|
|
184
|
+
self.compression = compression
|
|
185
|
+
self.proxy = proxy
|
|
186
|
+
self.mode = mode
|
|
187
|
+
self.pool_size = pool_size
|
|
188
|
+
self.time_unit = time_unit
|
|
189
|
+
self.https_agent = https_agent
|
|
190
|
+
self.user_agent = ""
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# TimeUnit Constants
|
|
5
|
+
class TimeUnit(Enum):
|
|
6
|
+
MILLISECOND = "MILLISECOND"
|
|
7
|
+
millisecond = "millisecond"
|
|
8
|
+
MICROSECOND = "MICROSECOND"
|
|
9
|
+
microsecond = "microsecond"
|
|
10
|
+
|
|
11
|
+
class WebsocketMode(Enum):
|
|
12
|
+
SINGLE = "single"
|
|
13
|
+
POOL = "pool"
|
|
14
|
+
|
|
15
|
+
# Algo constants
|
|
16
|
+
ALGO_REST_API_PROD_URL = "https://api.binance.com"
|
|
17
|
+
|
|
18
|
+
# Auto Invest constants
|
|
19
|
+
AUTO_INVEST_REST_API_PROD_URL = "https://api.binance.com"
|
|
20
|
+
|
|
21
|
+
# C2C constants
|
|
22
|
+
C2C_REST_API_PROD_URL = "https://api.binance.com"
|
|
23
|
+
|
|
24
|
+
# Convert constants
|
|
25
|
+
CONVERT_REST_API_PROD_URL = "https://api.binance.com"
|
|
26
|
+
|
|
27
|
+
# Copy Trading constants
|
|
28
|
+
COPY_TRADING_REST_API_PROD_URL = "https://api.binance.com"
|
|
29
|
+
|
|
30
|
+
# Crypto Loan constants
|
|
31
|
+
CRYPTO_LOAN_REST_API_PROD_URL = "https://api.binance.com"
|
|
32
|
+
|
|
33
|
+
# Derivatives Trading constants
|
|
34
|
+
DERIVATIVES_TRADING_REST_API_PROD_URL = "https://api.binance.com"
|
|
35
|
+
|
|
36
|
+
# Derivatives Trading (COIN-M Futures) constants
|
|
37
|
+
DERIVATIVES_TRADING_COIN_FUTURES_REST_API_PROD_URL = "https://dapi.binance.com"
|
|
38
|
+
DERIVATIVES_TRADING_COIN_FUTURES_REST_API_TESTNET_URL = "https://testnet.binancefuture.com"
|
|
39
|
+
DERIVATIVES_TRADING_COIN_FUTURES_WS_API_PROD_URL = "wss://ws-dapi.binance.com/ws-dapi/v1"
|
|
40
|
+
DERIVATIVES_TRADING_COIN_FUTURES_WS_API_TESTNET_URL = "wss://testnet.binancefuture.com/ws-dapi/v1"
|
|
41
|
+
DERIVATIVES_TRADING_COIN_FUTURES_WS_STREAMS_PROD_URL = "wss://dstream.binance.com"
|
|
42
|
+
DERIVATIVES_TRADING_COIN_FUTURES_WS_STREAMS_TESTNET_URL = "wss://dstream.binancefuture.com"
|
|
43
|
+
|
|
44
|
+
# Derivatives Trading (USDS Futures) constants
|
|
45
|
+
DERIVATIVES_TRADING_USDS_FUTURES_REST_API_PROD_URL = "https://fapi.binance.com"
|
|
46
|
+
DERIVATIVES_TRADING_USDS_FUTURES_REST_API_TESTNET_URL = "https://testnet.binancefuture.com"
|
|
47
|
+
DERIVATIVES_TRADING_USDS_FUTURES_WS_API_PROD_URL = "wss://ws-fapi.binance.com/ws-fapi/v1"
|
|
48
|
+
DERIVATIVES_TRADING_USDS_FUTURES_WS_API_TESTNET_URL = "wss://testnet.binancefuture.com/ws-fapi/v1"
|
|
49
|
+
DERIVATIVES_TRADING_USDS_FUTURES_WS_STREAMS_PROD_URL = "wss://fstream.binance.com"
|
|
50
|
+
DERIVATIVES_TRADING_USDS_FUTURES_WS_STREAMS_TESTNET_URL = "wss://stream.binancefuture.com"
|
|
51
|
+
|
|
52
|
+
# Derivatives Trading (Options) constants
|
|
53
|
+
DERIVATIVES_TRADING_OPTIONS_REST_API_PROD_URL = "https://eapi.binance.com"
|
|
54
|
+
DERIVATIVES_TRADING_OPTIONS_WS_STREAMS_PROD_URL = "wss://nbstream.binance.com/eoptions"
|
|
55
|
+
|
|
56
|
+
# Derivatives Trading (Portfolio Margin) constants
|
|
57
|
+
DERIVATIVES_TRADING_PORTFOLIO_MARGIN_REST_API_PROD_URL = "https://papi.binance.com"
|
|
58
|
+
DERIVATIVES_TRADING_PORTFOLIO_MARGIN_REST_API_TESTNET_URL = "https://testnet.binancefuture.com"
|
|
59
|
+
DERIVATIVES_TRADING_PORTFOLIO_MARGIN_WS_STREAMS_PROD_URL = "wss://fstream.binance.com/pm"
|
|
60
|
+
DERIVATIVES_TRADING_PORTFOLIO_MARGIN_WS_STREAMS_TESTNET_URL = "wss://fstream.binancefuture.com/pm"
|
|
61
|
+
|
|
62
|
+
# Derivatives Trading (Portfolio Margin Pro) constants
|
|
63
|
+
DERIVATIVES_TRADING_PORTFOLIO_MARGIN_PRO_REST_API_PROD_URL = "https://api.binance.com"
|
|
64
|
+
DERIVATIVES_TRADING_PORTFOLIO_MARGIN_PRO_WS_STREAMS_PROD_URL = "wss://fstream.binance.com/pm-classic"
|
|
65
|
+
|
|
66
|
+
# Dual Investment constants
|
|
67
|
+
DUAL_INVESTMENT_REST_API_PROD_URL = "https://api.binance.com"
|
|
68
|
+
|
|
69
|
+
# Fiat constants
|
|
70
|
+
FIAT_REST_API_PROD_URL = "https://api.binance.com"
|
|
71
|
+
|
|
72
|
+
# Gift Card constants
|
|
73
|
+
GIFT_CARD_REST_API_PROD_URL = "https://api.binance.com"
|
|
74
|
+
|
|
75
|
+
# Margin Trading constants
|
|
76
|
+
MARGIN_TRADING_REST_API_PROD_URL = "https://api.binance.com"
|
|
77
|
+
MARGIN_TRADING_WS_STREAMS_PROD_URL = "wss://stream.binance.com:9443"
|
|
78
|
+
MARGIN_TRADING_RISK_WS_STREAMS_PROD_URL = "wss://margin-stream.binance.com"
|
|
79
|
+
|
|
80
|
+
# Mining constants
|
|
81
|
+
MINING_REST_API_PROD_URL = "https://api.binance.com"
|
|
82
|
+
|
|
83
|
+
# NFT constants
|
|
84
|
+
NFT_REST_API_PROD_URL = "https://api.binance.com"
|
|
85
|
+
|
|
86
|
+
# Pay constants
|
|
87
|
+
PAY_REST_API_PROD_URL = "https://api.binance.com"
|
|
88
|
+
|
|
89
|
+
# Rebate constants
|
|
90
|
+
REBATE_REST_API_PROD_URL = "https://api.binance.com"
|
|
91
|
+
|
|
92
|
+
# Simple Earn constants
|
|
93
|
+
SIMPLE_EARN_REST_API_PROD_URL = "https://api.binance.com"
|
|
94
|
+
|
|
95
|
+
# Spot Constants
|
|
96
|
+
SPOT_REST_API_PROD_URL = "https://api.binance.com"
|
|
97
|
+
SPOT_REST_API_TESTNET_URL = "https://testnet.binance.vision"
|
|
98
|
+
SPOT_WS_API_PROD_URL = "wss://ws-api.binance.com:443/ws-api/v3"
|
|
99
|
+
SPOT_WS_API_TESTNET_URL = "wss://ws-api.testnet.binance.vision/ws-api/v3"
|
|
100
|
+
SPOT_WS_STREAMS_PROD_URL = "wss://stream.binance.com:9443"
|
|
101
|
+
SPOT_WS_STREAMS_TESTNET_URL = "wss://stream.testnet.binance.vision"
|
|
102
|
+
SPOT_REST_API_MARKET_URL = "https://data-api.binance.vision"
|
|
103
|
+
SPOT_WS_STREAMS_MARKET_URL = "wss://data-stream.binance.vision"
|
|
104
|
+
|
|
105
|
+
# Staking constants
|
|
106
|
+
STAKING_REST_API_PROD_URL = "https://api.binance.com"
|
|
107
|
+
|
|
108
|
+
# Sub Account constants
|
|
109
|
+
SUB_ACCOUNT_REST_API_PROD_URL = "https://api.binance.com"
|
|
110
|
+
|
|
111
|
+
# VIP Loan constants
|
|
112
|
+
VIP_LOAN_REST_API_PROD_URL = "https://api.binance.com"
|
|
113
|
+
|
|
114
|
+
# Wallet constants
|
|
115
|
+
WALLET_REST_API_PROD_URL = "https://api.binance.com"
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Error(Exception):
|
|
5
|
+
pass
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ClientError(Error):
|
|
9
|
+
"""Represents an error that occurred in the Connector client."""
|
|
10
|
+
|
|
11
|
+
def __init__(self, error_message: Optional[str] = None):
|
|
12
|
+
self.error_message = error_message or "An unexpected error occurred."
|
|
13
|
+
super().__init__(error_message)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class RequiredError(Error):
|
|
17
|
+
"""Represents an error when a required parameter is missing or undefined."""
|
|
18
|
+
|
|
19
|
+
def __init__(self, field: str, error_message: Optional[str] = None):
|
|
20
|
+
self.error_message = (
|
|
21
|
+
error_message or f"Required parameter {field} was null or undefined."
|
|
22
|
+
)
|
|
23
|
+
self.field = field
|
|
24
|
+
super().__init__(error_message)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class UnauthorizedError(Error):
|
|
28
|
+
"""Represents an error when a client is unauthorized to access a resource."""
|
|
29
|
+
|
|
30
|
+
def __init__(self, error_message: Optional[str] = None):
|
|
31
|
+
self.error_message = (
|
|
32
|
+
error_message or "Unauthorized access. Authentication required."
|
|
33
|
+
)
|
|
34
|
+
super().__init__(error_message)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class ForbiddenError(Error):
|
|
38
|
+
"""Represents an error when access to the resource is forbidden."""
|
|
39
|
+
|
|
40
|
+
def __init__(self, error_message: Optional[str] = None):
|
|
41
|
+
self.error_message = (
|
|
42
|
+
error_message or "Access to the requested resource is forbidden."
|
|
43
|
+
)
|
|
44
|
+
super().__init__(error_message)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class TooManyRequestsError(Error):
|
|
48
|
+
"""Represents an error when the client is doing too many requests."""
|
|
49
|
+
|
|
50
|
+
def __init__(self, error_message: Optional[str] = None):
|
|
51
|
+
self.error_message = (
|
|
52
|
+
error_message or "Too many requests. You are being rate-limited."
|
|
53
|
+
)
|
|
54
|
+
super().__init__(error_message)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class RateLimitBanError(Error):
|
|
58
|
+
"""Represents an error when the client's IP has been banned for exceeding rate
|
|
59
|
+
limits."""
|
|
60
|
+
|
|
61
|
+
def __init__(self, error_message: Optional[str] = None):
|
|
62
|
+
self.error_message = (
|
|
63
|
+
error_message or "The IP address has been banned for exceeding rate limits."
|
|
64
|
+
)
|
|
65
|
+
super().__init__(error_message)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class ServerError(Error):
|
|
69
|
+
"""Represents an error when there is an internal server error."""
|
|
70
|
+
|
|
71
|
+
def __init__(
|
|
72
|
+
self,
|
|
73
|
+
error_message: Optional[str] = None,
|
|
74
|
+
status_code: Optional[int] = None,
|
|
75
|
+
):
|
|
76
|
+
self.error_message = error_message or "An internal server error occurred."
|
|
77
|
+
self.status_code = status_code
|
|
78
|
+
super().__init__(error_message)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class NetworkError(Error):
|
|
82
|
+
"""Represents an error when a network error occurs."""
|
|
83
|
+
|
|
84
|
+
def __init__(self, error_message: Optional[str] = None):
|
|
85
|
+
self.error_message = error_message or "A network error occurred."
|
|
86
|
+
super().__init__(error_message)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class NotFoundError(Error):
|
|
90
|
+
"""Represents an error when the requested resource was not found."""
|
|
91
|
+
|
|
92
|
+
def __init__(self, error_message: Optional[str] = None):
|
|
93
|
+
self.error_message = error_message or "The requested resource was not found."
|
|
94
|
+
super().__init__(error_message)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class BadRequestError(Error):
|
|
98
|
+
"""Represents an error when a request is invalid or cannot be otherwise served."""
|
|
99
|
+
|
|
100
|
+
def __init__(self, error_message: Optional[str] = None):
|
|
101
|
+
self.error_message = (
|
|
102
|
+
error_message or "The request was invalid or cannot be otherwise served."
|
|
103
|
+
)
|
|
104
|
+
super().__init__(self.error_message)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from enum import Enum
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class LogLevel(Enum):
|
|
6
|
+
NONE = 0
|
|
7
|
+
DEBUG = 10
|
|
8
|
+
INFO = 20
|
|
9
|
+
WARN = 30
|
|
10
|
+
ERROR = 40
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Logger:
|
|
14
|
+
_instance = None
|
|
15
|
+
|
|
16
|
+
def __init__(self):
|
|
17
|
+
"""Ensure only one instance is initialized."""
|
|
18
|
+
if not Logger._instance:
|
|
19
|
+
Logger._instance = self
|
|
20
|
+
self._initialize()
|
|
21
|
+
else:
|
|
22
|
+
self.__dict__ = Logger._instance.__dict__ # Share attributes
|
|
23
|
+
|
|
24
|
+
@classmethod
|
|
25
|
+
def get_instance(cls):
|
|
26
|
+
"""Retrieve or initialize the singleton logger."""
|
|
27
|
+
if not cls._instance:
|
|
28
|
+
cls._instance = cls()
|
|
29
|
+
return cls._instance
|
|
30
|
+
|
|
31
|
+
def _initialize(self):
|
|
32
|
+
"""Initialize the logger settings."""
|
|
33
|
+
self._logger = logging.getLogger("ConnectorLogger")
|
|
34
|
+
|
|
35
|
+
# Prevent duplicate handlers if logger is re-initialized
|
|
36
|
+
if not self._logger.hasHandlers():
|
|
37
|
+
handler = logging.StreamHandler()
|
|
38
|
+
formatter = logging.Formatter("[%(asctime)s] [%(levelname)s] %(message)s")
|
|
39
|
+
handler.setFormatter(formatter)
|
|
40
|
+
self._logger.addHandler(handler)
|
|
41
|
+
|
|
42
|
+
self._logger.setLevel(LogLevel.INFO.value)
|
|
43
|
+
self.min_log_level = LogLevel.INFO
|
|
44
|
+
|
|
45
|
+
def set_min_log_level(self, level: LogLevel):
|
|
46
|
+
"""Set the minimum log level."""
|
|
47
|
+
if not isinstance(level, LogLevel):
|
|
48
|
+
raise ValueError(f"Invalid log level: {level}")
|
|
49
|
+
self.min_log_level = level
|
|
50
|
+
self._logger.setLevel(level.value)
|
|
51
|
+
|
|
52
|
+
def debug(self, *message):
|
|
53
|
+
if self._allow_level_log(LogLevel.DEBUG):
|
|
54
|
+
self._logger.debug(" ".join(map(str, message)))
|
|
55
|
+
|
|
56
|
+
def info(self, *message):
|
|
57
|
+
if self._allow_level_log(LogLevel.INFO):
|
|
58
|
+
self._logger.info(" ".join(map(str, message)))
|
|
59
|
+
|
|
60
|
+
def warn(self, *message):
|
|
61
|
+
if self._allow_level_log(LogLevel.WARN):
|
|
62
|
+
self._logger.warning(" ".join(map(str, message)))
|
|
63
|
+
|
|
64
|
+
def error(self, *message):
|
|
65
|
+
if self._allow_level_log(LogLevel.ERROR):
|
|
66
|
+
self._logger.error(" ".join(map(str, message)))
|
|
67
|
+
|
|
68
|
+
def _allow_level_log(self, level: LogLevel) -> bool:
|
|
69
|
+
return level.value >= self.min_log_level.value
|