binance-common 1.0.0__py3-none-any.whl

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.
CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # Changelog
2
+
3
+ ## 1.0.0 - 2025-xx-xx
4
+
5
+ First release
README.md ADDED
@@ -0,0 +1,36 @@
1
+ # Binance Common Types and Utilities for Binance Connectors
2
+
3
+ [![Code Style: Black](https://img.shields.io/badge/code_style-black-black)](https://black.readthedocs.io/en/stable/)
4
+ [![PyPI version](https://img.shields.io/pypi/v/binance-common)](https://pypi.python.org/pypi/binance-common)
5
+ [![PyPI Downloads](https://img.shields.io/pypi/dm/binance-common.svg)](https://pypi.org/project/binance-common/)
6
+ [![Python version](https://img.shields.io/pypi/pyversions/binance-connector)](https://www.python.org/downloads/)
7
+ [![Known Vulnerabilities](https://img.shields.io/badge/security-scanned-brightgreen)](https://github.com/binance/binance-connector-python/security)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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.
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
@@ -0,0 +1,92 @@
1
+ from typing import List, Optional, Callable, TypeVar, Generic
2
+ from pydantic import BaseModel
3
+
4
+ T = TypeVar("T")
5
+
6
+
7
+ class RateLimit(BaseModel):
8
+ """Represents a single rate limit entry.
9
+
10
+ :param rateLimitType: The type of the rate limit (e.g., 'REQUEST_WEIGHT', 'ORDERS').
11
+ :param interval: The time interval (e.g., 'SECOND', 'MINUTE', 'HOUR', 'DAY').
12
+ :param intervalNum: The interval number (e.g., 1, 10, etc.).
13
+ :param count: The number of requests/orders used in the interval.
14
+ :param retryAfter: Optional retry time in seconds if rate-limited.
15
+ """
16
+
17
+ rateLimitType: str
18
+ interval: str
19
+ intervalNum: int
20
+ count: int
21
+ retryAfter: Optional[int]
22
+
23
+
24
+ class ApiResponse(Generic[T]):
25
+ """A wrapper for API responses that includes parsed data and rate limit headers.
26
+
27
+ :param data_function: A callable that lazily returns the parsed data of type T.
28
+ :param status: The HTTP status code of the response.
29
+ :param headers: A dictionary of response headers.
30
+ :param rate_limits: A list of rate limit headers parsed from the response.
31
+ """
32
+
33
+ def __init__(
34
+ self,
35
+ data_function: Callable[[], T],
36
+ status: int,
37
+ headers: dict,
38
+ rate_limits: List[RateLimit] = None,
39
+ ):
40
+ self._data_function = data_function
41
+ self.status = status
42
+ self.headers = headers or {}
43
+ self.rate_limits = rate_limits or []
44
+
45
+ def data(self) -> T:
46
+ """Lazily retrieves the response data.
47
+
48
+ :return: The parsed data of type T.
49
+ """
50
+ return self._data_function()
51
+
52
+
53
+ class WebsocketApiRateLimit(BaseModel):
54
+ """Represents a single rate limit entry for WebSocket API.
55
+
56
+ :param rateLimitType: The type of the rate limit (e.g., 'REQUEST_WEIGHT', 'ORDERS').
57
+ :param interval: The time interval (e.g., 'SECOND', 'MINUTE', 'HOUR', 'DAY').
58
+ :param intervalNum: The number of intervals for the rate limit.
59
+ :param limit: The maximum number of requests or orders allowed within the specified interval.
60
+ :param count: The current count of requests or orders for the rate limit.
61
+ """
62
+
63
+ rateLimitType: str
64
+ interval: str
65
+ intervalNum: int
66
+ limit: int
67
+ count: int = 0
68
+
69
+
70
+ class WebsocketApiResponse(Generic[T]):
71
+ """A wrapper for WebSocket API responses that includes parsed data and rate limit headers.
72
+
73
+ :param data_function: A callable that lazily returns the parsed data of type T.
74
+ :param status: The HTTP status code of the response.
75
+ :param headers: A dictionary of response headers.
76
+ :param rate_limits: A list of rate limit headers parsed from the response.
77
+ """
78
+
79
+ def __init__(
80
+ self,
81
+ data_function: T = None,
82
+ rate_limits: List[WebsocketApiRateLimit] = None,
83
+ ):
84
+ self._data_function = data_function
85
+ self.rate_limits = rate_limits or []
86
+
87
+ def data(self) -> T:
88
+ """Lazily retrieves the response data.
89
+
90
+ :return: The parsed data of type T.
91
+ """
92
+ return self._data_function()