unicex 0.17.9__tar.gz → 0.17.10__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.17.9/unicex.egg-info → unicex-0.17.10}/PKG-INFO +1 -1
- {unicex-0.17.9 → unicex-0.17.10}/pyproject.toml +1 -1
- unicex-0.17.10/unicex/kucoin/websocket_manager.py +121 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/_spot_ws_proto/__init__.py +335 -335
- {unicex-0.17.9 → unicex-0.17.10/unicex.egg-info}/PKG-INFO +1 -1
- unicex-0.17.9/unicex/kucoin/websocket_manager.py +0 -11
- {unicex-0.17.9 → unicex-0.17.10}/LICENSE +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/README.md +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/setup.cfg +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/__init__.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/_abc/__init__.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/_abc/exchange_info.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/_abc/uni_client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/_abc/uni_websocket_manager.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/_base/__init__.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/_base/client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/_base/websocket.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/aster/__init__.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/aster/adapter.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/aster/client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/aster/exchange_info.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/aster/uni_client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/aster/uni_websocket_manager.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/aster/user_websocket.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/aster/websocket_manager.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/binance/__init__.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/binance/adapter.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/binance/client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/binance/exchange_info.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/binance/uni_client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/binance/uni_websocket_manager.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/binance/user_websocket.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/binance/websocket_manager.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bingx/__init__.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bingx/adapter.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bingx/client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bingx/exchange_info.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bingx/uni_client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bingx/uni_websocket_manager.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bingx/user_websocket.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bingx/websocket_manager.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bitget/__init__.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bitget/adapter.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bitget/client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bitget/exchange_info.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bitget/uni_client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bitget/uni_websocket_manager.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bitget/user_websocket.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bitget/websocket_manager.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bybit/__init__.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bybit/adapter.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bybit/client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bybit/exchange_info.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bybit/uni_client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bybit/uni_websocket_manager.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bybit/user_websocket.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/bybit/websocket_manager.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/enums.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/exceptions.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/extra.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/gate/__init__.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/gate/adapter.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/gate/client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/gate/exchange_info.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/gate/uni_client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/gate/uni_websocket_manager.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/gate/user_websocket.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/gate/websocket_manager.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/hyperliquid/__init__.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/hyperliquid/adapter.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/hyperliquid/client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/hyperliquid/exchange_info.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/hyperliquid/uni_client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/hyperliquid/uni_websocket_manager.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/hyperliquid/user_websocket.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/hyperliquid/websocket_manager.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/kucoin/__init__.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/kucoin/adapter.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/kucoin/client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/kucoin/exchange_info.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/kucoin/uni_client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/kucoin/uni_websocket_manager.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/kucoin/user_websocket.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mapper.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/__init__.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/_spot_ws_proto/PrivateAccountV3Api_pb2.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/_spot_ws_proto/PrivateDealsV3Api_pb2.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/_spot_ws_proto/PrivateOrdersV3Api_pb2.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/_spot_ws_proto/PublicAggreBookTickerV3Api_pb2.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/_spot_ws_proto/PublicAggreDealsV3Api_pb2.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/_spot_ws_proto/PublicAggreDepthsV3Api_pb2.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/_spot_ws_proto/PublicBookTickerBatchV3Api_pb2.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/_spot_ws_proto/PublicBookTickerV3Api_pb2.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/_spot_ws_proto/PublicDealsV3Api_pb2.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/_spot_ws_proto/PublicFuture_pb2.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/_spot_ws_proto/PublicIncreaseDepthsBatchV3Api_pb2.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/_spot_ws_proto/PublicIncreaseDepthsV3Api_pb2.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/_spot_ws_proto/PublicLimitDepthsV3Api_pb2.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/_spot_ws_proto/PublicMiniTickerV3Api_pb2.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/_spot_ws_proto/PublicMiniTickersV3Api_pb2.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/_spot_ws_proto/PublicSpotKlineV3Api_pb2.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/_spot_ws_proto/PushDataV3ApiWrapper_pb2.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/adapter.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/exchange_info.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/uni_client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/uni_websocket_manager.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/user_websocket.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/mexc/websocket_manager.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/okx/__init__.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/okx/adapter.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/okx/client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/okx/exchange_info.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/okx/uni_client.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/okx/uni_websocket_manager.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/okx/user_websocket.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/okx/websocket_manager.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/types.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex/utils.py +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex.egg-info/SOURCES.txt +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex.egg-info/dependency_links.txt +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/unicex.egg-info/requires.txt +0 -0
- {unicex-0.17.9 → unicex-0.17.10}/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.17.
|
|
7
|
+
version = "0.17.10"
|
|
8
8
|
|
|
9
9
|
description = "Unified Crypto Exchange API "
|
|
10
10
|
readme = "README.md"
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
__all__ = ["WebsocketManager"]
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import time
|
|
5
|
+
from collections.abc import Awaitable, Callable, Sequence
|
|
6
|
+
from typing import Any, Literal
|
|
7
|
+
|
|
8
|
+
from unicex._base import Websocket
|
|
9
|
+
from unicex.utils import validate_single_symbol_args
|
|
10
|
+
|
|
11
|
+
from .client import Client
|
|
12
|
+
|
|
13
|
+
type CallbackType = Callable[[Any], Awaitable[None]]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class WebsocketManager:
|
|
17
|
+
"""Менеджер асинхронных вебсокетов для Kucoin."""
|
|
18
|
+
|
|
19
|
+
_SPOT_URL: str = "wss://x-push-spot.kucoin.com"
|
|
20
|
+
"""Базовый URL для вебсокета на спот."""
|
|
21
|
+
|
|
22
|
+
_FUTURES_URL: str = "wss://x-push-futures.kucoin.com"
|
|
23
|
+
"""Базовый URL для вебсокета на фьючерсы."""
|
|
24
|
+
|
|
25
|
+
def __init__(self, client: Client | None = None, **ws_kwargs: Any) -> None:
|
|
26
|
+
"""Инициализирует менеджер вебсокетов для Kucoin.
|
|
27
|
+
|
|
28
|
+
Параметры:
|
|
29
|
+
client (`Client | None`): Клиент для выполнения запросов. Нужен, чтобы открыть приватные вебсокеты.
|
|
30
|
+
ws_kwargs (`dict[str, Any]`): Дополнительные аргументы, которые прокидываются в `Websocket`.
|
|
31
|
+
"""
|
|
32
|
+
self.client = client
|
|
33
|
+
self._ws_kwargs = ws_kwargs
|
|
34
|
+
|
|
35
|
+
def _get_url(self, trade_type: Literal["SPOT", "FUTURES"]) -> str:
|
|
36
|
+
"""Возвращает URL для указанного типа рынка."""
|
|
37
|
+
if trade_type == "SPOT":
|
|
38
|
+
return self._SPOT_URL
|
|
39
|
+
if trade_type == "FUTURES":
|
|
40
|
+
return self._FUTURES_URL
|
|
41
|
+
raise ValueError(f"Unsupported trade type: {trade_type}")
|
|
42
|
+
|
|
43
|
+
def _normalize_depth(self, depth: str | int) -> str:
|
|
44
|
+
"""Нормализует значение глубины стакана."""
|
|
45
|
+
depth_value = str(depth)
|
|
46
|
+
if depth_value not in {"1", "5", "50", "increment"}:
|
|
47
|
+
raise ValueError("depth must be one of: 1, 5, 50, increment")
|
|
48
|
+
return depth_value
|
|
49
|
+
|
|
50
|
+
def _build_subscription_messages(
|
|
51
|
+
self,
|
|
52
|
+
trade_type: Literal["SPOT", "FUTURES"],
|
|
53
|
+
depth: str,
|
|
54
|
+
symbols: Sequence[str],
|
|
55
|
+
rpi_filter: Literal[0, 1],
|
|
56
|
+
request_id: str | None = None,
|
|
57
|
+
) -> list[str]:
|
|
58
|
+
"""Формирует сообщения для подписки."""
|
|
59
|
+
base_id = int(time.time() * 1000)
|
|
60
|
+
messages: list[str] = []
|
|
61
|
+
for index, symbol in enumerate(symbols):
|
|
62
|
+
payload = {
|
|
63
|
+
"id": request_id or str(base_id + index),
|
|
64
|
+
"action": "SUBSCRIBE",
|
|
65
|
+
"channel": "obu",
|
|
66
|
+
"tradeType": trade_type,
|
|
67
|
+
"symbol": symbol.upper(),
|
|
68
|
+
"depth": depth,
|
|
69
|
+
"rpiFilter": rpi_filter,
|
|
70
|
+
}
|
|
71
|
+
messages.append(json.dumps(payload))
|
|
72
|
+
return messages
|
|
73
|
+
|
|
74
|
+
def orderbook(
|
|
75
|
+
self,
|
|
76
|
+
callback: CallbackType,
|
|
77
|
+
trade_type: Literal["SPOT", "FUTURES"],
|
|
78
|
+
depth: Literal["1", "5", "50", "increment"] | int = "1",
|
|
79
|
+
symbol: str | None = None,
|
|
80
|
+
symbols: Sequence[str] | None = None,
|
|
81
|
+
rpi_filter: Literal[0, 1] = 0,
|
|
82
|
+
request_id: str | None = None,
|
|
83
|
+
) -> Websocket:
|
|
84
|
+
"""Создает вебсокет для получения order book.
|
|
85
|
+
|
|
86
|
+
Параметры:
|
|
87
|
+
callback (`CallbackType`): Асинхронная функция обратного вызова для обработки сообщений.
|
|
88
|
+
trade_type (`Literal["SPOT", "FUTURES"]`): Тип рынка.
|
|
89
|
+
depth (`Literal["1", "5", "50", "increment"] | int`): Глубина стакана.
|
|
90
|
+
symbol (`str | None`): Один символ для подписки.
|
|
91
|
+
symbols (`Sequence[str] | None`): Список символов для мультиплекс‑подключения.
|
|
92
|
+
rpi_filter (`Literal[0, 1]`): Фильтр RPI. Доступен только для фьючерсов (depth=5/50).
|
|
93
|
+
request_id (`str | None`): Опциональный идентификатор запроса.
|
|
94
|
+
|
|
95
|
+
Возвращает:
|
|
96
|
+
`Websocket`: Объект для управления вебсокет соединением.
|
|
97
|
+
"""
|
|
98
|
+
validate_single_symbol_args(symbol, symbols)
|
|
99
|
+
|
|
100
|
+
depth_value = self._normalize_depth(depth)
|
|
101
|
+
if rpi_filter not in (0, 1):
|
|
102
|
+
raise ValueError("rpi_filter must be 0 or 1")
|
|
103
|
+
if trade_type == "SPOT" and rpi_filter == 1:
|
|
104
|
+
raise ValueError("rpi_filter=1 is supported only for FUTURES")
|
|
105
|
+
if rpi_filter == 1 and depth_value not in {"5", "50"}:
|
|
106
|
+
raise ValueError("rpi_filter=1 supports only depth=5 or depth=50")
|
|
107
|
+
|
|
108
|
+
tickers = [symbol] if symbol else symbols
|
|
109
|
+
subscription_messages = self._build_subscription_messages(
|
|
110
|
+
trade_type=trade_type,
|
|
111
|
+
depth=depth_value,
|
|
112
|
+
symbols=tickers, # type: ignore[arg-type]
|
|
113
|
+
rpi_filter=rpi_filter,
|
|
114
|
+
request_id=request_id,
|
|
115
|
+
)
|
|
116
|
+
return Websocket(
|
|
117
|
+
callback=callback,
|
|
118
|
+
url=self._get_url(trade_type),
|
|
119
|
+
subscription_messages=subscription_messages,
|
|
120
|
+
**self._ws_kwargs,
|
|
121
|
+
)
|