unicex 0.13.3__tar.gz → 0.13.5__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.
- {unicex-0.13.3/unicex.egg-info → unicex-0.13.5}/PKG-INFO +1 -1
- {unicex-0.13.3 → unicex-0.13.5}/pyproject.toml +1 -1
- {unicex-0.13.3 → unicex-0.13.5}/unicex/_base/websocket.py +35 -27
- {unicex-0.13.3 → unicex-0.13.5/unicex.egg-info}/PKG-INFO +1 -1
- {unicex-0.13.3 → unicex-0.13.5}/LICENSE +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/README.md +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/setup.cfg +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/__init__.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/_abc/__init__.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/_abc/exchange_info.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/_abc/uni_client.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/_abc/uni_websocket_manager.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/_base/__init__.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/_base/client.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/binance/__init__.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/binance/adapter.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/binance/client.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/binance/exchange_info.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/binance/uni_client.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/binance/uni_websocket_manager.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/binance/user_websocket.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/binance/websocket_manager.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/bitget/__init__.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/bitget/adapter.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/bitget/client.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/bitget/exchange_info.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/bitget/uni_client.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/bitget/uni_websocket_manager.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/bitget/user_websocket.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/bitget/websocket_manager.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/bybit/__init__.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/bybit/adapter.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/bybit/client.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/bybit/exchange_info.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/bybit/uni_client.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/bybit/uni_websocket_manager.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/bybit/user_websocket.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/bybit/websocket_manager.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/enums.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/exceptions.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/extra.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/gate/__init__.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/gate/adapter.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/gate/client.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/gate/exchange_info.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/gate/uni_client.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/gate/uni_websocket_manager.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/gate/user_websocket.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/gate/websocket_manager.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/hyperliquid/__init__.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/hyperliquid/adapter.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/hyperliquid/client.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/hyperliquid/exchange_info.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/hyperliquid/uni_client.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/hyperliquid/uni_websocket_manager.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/hyperliquid/user_websocket.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/hyperliquid/websocket_manager.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mapper.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/__init__.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/_spot_ws_proto/PrivateAccountV3Api_pb2.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/_spot_ws_proto/PrivateDealsV3Api_pb2.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/_spot_ws_proto/PrivateOrdersV3Api_pb2.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/_spot_ws_proto/PublicAggreBookTickerV3Api_pb2.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/_spot_ws_proto/PublicAggreDealsV3Api_pb2.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/_spot_ws_proto/PublicAggreDepthsV3Api_pb2.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/_spot_ws_proto/PublicBookTickerBatchV3Api_pb2.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/_spot_ws_proto/PublicBookTickerV3Api_pb2.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/_spot_ws_proto/PublicDealsV3Api_pb2.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/_spot_ws_proto/PublicFuture_pb2.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/_spot_ws_proto/PublicIncreaseDepthsBatchV3Api_pb2.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/_spot_ws_proto/PublicIncreaseDepthsV3Api_pb2.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/_spot_ws_proto/PublicLimitDepthsV3Api_pb2.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/_spot_ws_proto/PublicMiniTickerV3Api_pb2.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/_spot_ws_proto/PublicMiniTickersV3Api_pb2.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/_spot_ws_proto/PublicSpotKlineV3Api_pb2.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/_spot_ws_proto/PushDataV3ApiWrapper_pb2.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/_spot_ws_proto/__init__.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/adapter.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/client.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/exchange_info.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/uni_client.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/uni_websocket_manager.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/user_websocket.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/websocket_manager.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/okx/__init__.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/okx/adapter.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/okx/client.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/okx/exchange_info.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/okx/uni_client.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/okx/uni_websocket_manager.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/okx/user_websocket.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/okx/websocket_manager.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/types.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex/utils.py +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex.egg-info/SOURCES.txt +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex.egg-info/dependency_links.txt +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex.egg-info/requires.txt +0 -0
- {unicex-0.13.3 → unicex-0.13.5}/unicex.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ name = "unicex"
|
|
|
4
4
|
# • PATCH (x.y.Z) → увеличивается при багфиксе, который не ломает совместимость.
|
|
5
5
|
# • MINOR (x.Y.z) → увеличивается при добавлении новой функциональности, но без ломающих изменений (backward-compatible).
|
|
6
6
|
# • MAJOR (X.y.z) → увеличивается при изменениях, которые ломают обратную совместимость.
|
|
7
|
-
version = "0.13.
|
|
7
|
+
version = "0.13.5"
|
|
8
8
|
|
|
9
9
|
description = "Unified Crypto Exchange API "
|
|
10
10
|
readme = "README.md"
|
|
@@ -17,7 +17,7 @@ from unicex.types import LoggerLike
|
|
|
17
17
|
class Websocket:
|
|
18
18
|
"""Базовый класс асинхронного вебсокета."""
|
|
19
19
|
|
|
20
|
-
MAX_QUEUE_SIZE: int =
|
|
20
|
+
MAX_QUEUE_SIZE: int = 500
|
|
21
21
|
"""Максимальная длина очереди."""
|
|
22
22
|
|
|
23
23
|
class _DecoderProtocol(Protocol):
|
|
@@ -95,12 +95,7 @@ class Websocket:
|
|
|
95
95
|
async def stop(self) -> None:
|
|
96
96
|
"""Останавливает вебсокет и рабочие задачи."""
|
|
97
97
|
self._running = False
|
|
98
|
-
|
|
99
|
-
task.cancel()
|
|
100
|
-
self._tasks.clear()
|
|
101
|
-
|
|
102
|
-
# Очистка очереди
|
|
103
|
-
self._queue = asyncio.Queue()
|
|
98
|
+
await self._after_disconnect()
|
|
104
99
|
|
|
105
100
|
async def restart(self) -> None:
|
|
106
101
|
"""Перезапускает вебсокет."""
|
|
@@ -111,25 +106,27 @@ class Websocket:
|
|
|
111
106
|
async def _connect(self) -> None:
|
|
112
107
|
"""Подключается к вебсокету и настраивает соединение."""
|
|
113
108
|
self._logger.debug(f"Establishing connection with {self._url}")
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
109
|
+
async for conn in websockets.connect(uri=self._url, **self._generate_ws_kwargs()):
|
|
110
|
+
try:
|
|
111
|
+
self._logger.info(f"Websocket connection was established to {self._url}")
|
|
112
|
+
await self._after_connect(conn)
|
|
113
|
+
|
|
114
|
+
# Цикл получения сообщений
|
|
115
|
+
while self._running:
|
|
116
|
+
message = await conn.recv()
|
|
117
|
+
await self._handle_message(message)
|
|
118
|
+
|
|
119
|
+
except websockets.exceptions.ConnectionClosed as e:
|
|
120
|
+
self._logger.error(f"Websocket connection was closed unexpectedly: {e}")
|
|
121
|
+
except Exception as e:
|
|
122
|
+
self._logger.error(f"Unexpected error in websosocket connection: {e}")
|
|
123
|
+
finally:
|
|
124
|
+
# Делаем реконнект только если вебсокет активен, иначе выходим из итератора
|
|
125
|
+
if self._running:
|
|
126
|
+
await asyncio.sleep(self._reconnect_timeout)
|
|
127
|
+
await self._after_disconnect()
|
|
128
|
+
else:
|
|
129
|
+
return # Выходим из итератора, если вебсокет уже выключен
|
|
133
130
|
|
|
134
131
|
async def _handle_message(self, message: str | bytes) -> None:
|
|
135
132
|
"""Обрабатывает входящее сообщение вебсокета."""
|
|
@@ -182,11 +179,22 @@ class Websocket:
|
|
|
182
179
|
|
|
183
180
|
async def _after_disconnect(self) -> None:
|
|
184
181
|
"""Вызывается после отключения от вебсокета."""
|
|
182
|
+
# Останавливаем воркеров
|
|
185
183
|
for task in self._tasks:
|
|
186
184
|
task.cancel()
|
|
185
|
+
|
|
186
|
+
# Дожидаемся завершения задач (в т.ч. воркеров)
|
|
187
|
+
for task in self._tasks:
|
|
188
|
+
try:
|
|
189
|
+
await task
|
|
190
|
+
except asyncio.CancelledError:
|
|
191
|
+
pass
|
|
192
|
+
except Exception as e:
|
|
193
|
+
self._logger.warning(f"Worker raised during shutdown: {e}")
|
|
194
|
+
|
|
187
195
|
self._tasks.clear()
|
|
188
196
|
|
|
189
|
-
# Очистить очередь
|
|
197
|
+
# Очистить очередь уже безопасно, после остановки воркеров
|
|
190
198
|
self._queue = asyncio.Queue()
|
|
191
199
|
|
|
192
200
|
async def _send_subscribe_messages(self, conn: ClientConnection) -> None:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/_spot_ws_proto/PublicAggreBookTickerV3Api_pb2.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/_spot_ws_proto/PublicBookTickerBatchV3Api_pb2.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unicex-0.13.3 → unicex-0.13.5}/unicex/mexc/_spot_ws_proto/PublicIncreaseDepthsBatchV3Api_pb2.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|