unicex 0.5.0__py3-none-any.whl → 0.8.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.
Files changed (100) hide show
  1. unicex/__init__.py +56 -124
  2. unicex/_abc/__init__.py +2 -0
  3. unicex/_abc/exchange_info.py +176 -0
  4. unicex/_abc/uni_client.py +2 -2
  5. unicex/_base/client.py +2 -2
  6. unicex/binance/__init__.py +12 -0
  7. unicex/binance/adapter.py +2 -2
  8. unicex/binance/exchange_info.py +12 -0
  9. unicex/bitget/__init__.py +14 -4
  10. unicex/bitget/adapter.py +1 -1
  11. unicex/bitget/exchange_info.py +12 -0
  12. unicex/bitget/uni_websocket_manager.py +1 -1
  13. unicex/bybit/__init__.py +12 -0
  14. unicex/bybit/adapter.py +2 -2
  15. unicex/bybit/exchange_info.py +12 -0
  16. unicex/bybit/uni_client.py +2 -2
  17. unicex/enums.py +16 -5
  18. unicex/extra.py +84 -6
  19. unicex/gateio/__init__.py +12 -0
  20. unicex/gateio/adapter.py +4 -4
  21. unicex/gateio/exchange_info.py +12 -0
  22. unicex/hyperliquid/__init__.py +12 -0
  23. unicex/hyperliquid/adapter.py +151 -30
  24. unicex/hyperliquid/client.py +2208 -125
  25. unicex/hyperliquid/exchange_info.py +100 -0
  26. unicex/hyperliquid/uni_client.py +176 -22
  27. unicex/mapper.py +35 -33
  28. unicex/mexc/__init__.py +12 -0
  29. unicex/mexc/adapter.py +30 -13
  30. unicex/mexc/exchange_info.py +32 -0
  31. unicex/mexc/uni_client.py +6 -0
  32. unicex/okx/__init__.py +12 -0
  33. unicex/okx/adapter.py +25 -9
  34. unicex/okx/client.py +2599 -26
  35. unicex/okx/exchange_info.py +50 -0
  36. unicex/okx/uni_client.py +10 -10
  37. unicex/types.py +31 -0
  38. unicex-0.8.0.dist-info/METADATA +192 -0
  39. unicex-0.8.0.dist-info/RECORD +75 -0
  40. unicex/bitrue/__init__.py +0 -15
  41. unicex/bitrue/adapter.py +0 -8
  42. unicex/bitrue/client.py +0 -128
  43. unicex/bitrue/uni_client.py +0 -151
  44. unicex/bitrue/uni_websocket_manager.py +0 -269
  45. unicex/bitrue/user_websocket.py +0 -7
  46. unicex/bitrue/websocket_manager.py +0 -11
  47. unicex/bitunix/__init__.py +0 -15
  48. unicex/bitunix/adapter.py +0 -8
  49. unicex/bitunix/client.py +0 -8
  50. unicex/bitunix/uni_client.py +0 -151
  51. unicex/bitunix/uni_websocket_manager.py +0 -269
  52. unicex/bitunix/user_websocket.py +0 -7
  53. unicex/bitunix/websocket_manager.py +0 -11
  54. unicex/btse/__init__.py +0 -15
  55. unicex/btse/adapter.py +0 -8
  56. unicex/btse/client.py +0 -123
  57. unicex/btse/uni_client.py +0 -151
  58. unicex/btse/uni_websocket_manager.py +0 -269
  59. unicex/btse/user_websocket.py +0 -7
  60. unicex/btse/websocket_manager.py +0 -11
  61. unicex/kcex/__init__.py +0 -15
  62. unicex/kcex/adapter.py +0 -8
  63. unicex/kcex/client.py +0 -8
  64. unicex/kcex/uni_client.py +0 -151
  65. unicex/kcex/uni_websocket_manager.py +0 -269
  66. unicex/kcex/user_websocket.py +0 -7
  67. unicex/kcex/websocket_manager.py +0 -11
  68. unicex/kraken/__init__.py +0 -15
  69. unicex/kraken/adapter.py +0 -8
  70. unicex/kraken/client.py +0 -165
  71. unicex/kraken/uni_client.py +0 -151
  72. unicex/kraken/uni_websocket_manager.py +0 -269
  73. unicex/kraken/user_websocket.py +0 -7
  74. unicex/kraken/websocket_manager.py +0 -11
  75. unicex/kucoin/__init__.py +0 -15
  76. unicex/kucoin/adapter.py +0 -8
  77. unicex/kucoin/client.py +0 -120
  78. unicex/kucoin/uni_client.py +0 -151
  79. unicex/kucoin/uni_websocket_manager.py +0 -269
  80. unicex/kucoin/user_websocket.py +0 -7
  81. unicex/kucoin/websocket_manager.py +0 -11
  82. unicex/weex/__init__.py +0 -15
  83. unicex/weex/adapter.py +0 -8
  84. unicex/weex/client.py +0 -8
  85. unicex/weex/uni_client.py +0 -151
  86. unicex/weex/uni_websocket_manager.py +0 -269
  87. unicex/weex/user_websocket.py +0 -7
  88. unicex/weex/websocket_manager.py +0 -11
  89. unicex/xt/__init__.py +0 -15
  90. unicex/xt/adapter.py +0 -8
  91. unicex/xt/client.py +0 -8
  92. unicex/xt/uni_client.py +0 -151
  93. unicex/xt/uni_websocket_manager.py +0 -269
  94. unicex/xt/user_websocket.py +0 -7
  95. unicex/xt/websocket_manager.py +0 -11
  96. unicex-0.5.0.dist-info/METADATA +0 -170
  97. unicex-0.5.0.dist-info/RECORD +0 -123
  98. {unicex-0.5.0.dist-info → unicex-0.8.0.dist-info}/WHEEL +0 -0
  99. {unicex-0.5.0.dist-info → unicex-0.8.0.dist-info}/licenses/LICENSE +0 -0
  100. {unicex-0.5.0.dist-info → unicex-0.8.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,50 @@
1
+ __all__ = ["ExchangeInfo"]
2
+
3
+ import aiohttp
4
+
5
+ from unicex._abc import IExchangeInfo
6
+ from unicex.types import TickerInfoItem
7
+
8
+
9
+ class ExchangeInfo(IExchangeInfo):
10
+ """Предзагружает информацию о тикерах для биржи Okx."""
11
+
12
+ @classmethod
13
+ async def _load_exchange_info(cls) -> None:
14
+ """Загружает информацию о бирже."""
15
+ async with aiohttp.ClientSession() as session:
16
+ tickers_info = {}
17
+ url = "https://www.okx.com/api/v5/public/instruments?instType=SPOT"
18
+ async with session.get(url) as response:
19
+ data = await response.json()
20
+ for el in data["data"]:
21
+ tickers_info[el["instId"]] = TickerInfoItem(
22
+ tick_precision=cls._step_size_to_precision(el["tickSz"]),
23
+ size_precision=cls._step_size_to_precision(el["lotSz"]),
24
+ contract_size=1,
25
+ min_market_size=float(el["minSz"]),
26
+ max_market_size=float(el["maxMktSz"]),
27
+ min_limit_size=float(el["minSz"]),
28
+ max_limit_size=float(el["maxLmtSz"]),
29
+ )
30
+
31
+ cls._tickers_info = tickers_info
32
+ cls._logger.debug("Okx spot exchange info loaded")
33
+
34
+ futures_tickers_info = {}
35
+ url = "https://www.okx.com/api/v5/public/instruments?instType=SWAP"
36
+ async with session.get(url) as response:
37
+ data = await response.json()
38
+ for el in data["data"]:
39
+ futures_tickers_info[el["instId"]] = TickerInfoItem(
40
+ tick_precision=cls._step_size_to_precision(el["tickSz"]),
41
+ size_precision=cls._step_size_to_precision(el["lotSz"]),
42
+ contract_size=float(el["ctVal"]),
43
+ min_market_size=el["minSz"],
44
+ max_market_size=el["maxMktSz"],
45
+ min_limit_size=el["minSz"],
46
+ max_limit_size=el["maxLmtSz"],
47
+ )
48
+
49
+ cls._futures_tickers_info = futures_tickers_info
50
+ cls._logger.debug("Okx futures exchange info loaded")
unicex/okx/uni_client.py CHANGED
@@ -32,7 +32,7 @@ class UniClient(IUniClient[Client]):
32
32
  Возвращает:
33
33
  list[str]: Список тикеров.
34
34
  """
35
- raw_data = await self._client.tickers(inst_type="SPOT")
35
+ raw_data = await self._client.get_tickers(inst_type="SPOT")
36
36
  return Adapter.tickers(raw_data=raw_data, only_usdt=only_usdt)
37
37
 
38
38
  async def futures_tickers(self, only_usdt: bool = True) -> list[str]:
@@ -44,8 +44,8 @@ class UniClient(IUniClient[Client]):
44
44
  Возвращает:
45
45
  list[str]: Список тикеров.
46
46
  """
47
- raw_data = await self._client.tickers(inst_type="SWAP")
48
- return Adapter.tickers(raw_data=raw_data, only_usdt=only_usdt)
47
+ raw_data = await self._client.get_tickers(inst_type="SWAP")
48
+ return Adapter.futures_tickers(raw_data=raw_data, only_usdt=only_usdt)
49
49
 
50
50
  async def last_price(self) -> dict[str, float]:
51
51
  """Возвращает последнюю цену для каждого тикера.
@@ -53,7 +53,7 @@ class UniClient(IUniClient[Client]):
53
53
  Возвращает:
54
54
  dict[str, float]: Словарь с последними ценами для каждого тикера.
55
55
  """
56
- raw_data = await self._client.tickers(inst_type="SPOT")
56
+ raw_data = await self._client.get_tickers(inst_type="SPOT")
57
57
  return Adapter.last_price(raw_data)
58
58
 
59
59
  async def futures_last_price(self) -> dict[str, float]:
@@ -62,7 +62,7 @@ class UniClient(IUniClient[Client]):
62
62
  Возвращает:
63
63
  dict[str, float]: Словарь с последними ценами для каждого тикера.
64
64
  """
65
- raw_data = await self._client.tickers(inst_type="SWAP")
65
+ raw_data = await self._client.get_tickers(inst_type="SWAP")
66
66
  return Adapter.last_price(raw_data)
67
67
 
68
68
  async def ticker_24hr(self) -> TickerDailyDict:
@@ -71,7 +71,7 @@ class UniClient(IUniClient[Client]):
71
71
  Возвращает:
72
72
  TickerDailyDict: Словарь с статистикой за последние 24 часа для каждого тикера.
73
73
  """
74
- raw_data = await self._client.tickers(inst_type="SPOT")
74
+ raw_data = await self._client.get_tickers(inst_type="SPOT")
75
75
  return Adapter.ticker_24hr(raw_data=raw_data)
76
76
 
77
77
  async def futures_ticker_24hr(self) -> TickerDailyDict:
@@ -80,8 +80,8 @@ class UniClient(IUniClient[Client]):
80
80
  Возвращает:
81
81
  TickerDailyDict: Словарь с статистикой за последние 24 часа для каждого тикера.
82
82
  """
83
- raw_data = await self._client.tickers(inst_type="SWAP")
84
- return Adapter.ticker_24hr(raw_data=raw_data)
83
+ raw_data = await self._client.get_tickers(inst_type="SWAP")
84
+ return Adapter.futures_ticker_24hr(raw_data=raw_data)
85
85
 
86
86
  async def klines(
87
87
  self,
@@ -108,7 +108,7 @@ class UniClient(IUniClient[Client]):
108
108
  if isinstance(interval, Timeframe)
109
109
  else interval
110
110
  )
111
- raw_data = await self._client.candles(
111
+ raw_data = await self._client.get_candlesticks(
112
112
  inst_id=symbol,
113
113
  bar=interval,
114
114
  after=start_time,
@@ -142,7 +142,7 @@ class UniClient(IUniClient[Client]):
142
142
  if isinstance(interval, Timeframe)
143
143
  else interval
144
144
  )
145
- raw_data = await self._client.candles(
145
+ raw_data = await self._client.get_candlesticks(
146
146
  inst_id=symbol,
147
147
  bar=interval,
148
148
  after=start_time,
unicex/types.py CHANGED
@@ -11,6 +11,8 @@ __all__ = [
11
11
  "AccountType",
12
12
  "OpenInterestDict",
13
13
  "OpenInterestItem",
14
+ "TickerInfoItem",
15
+ "TickersInfoDict",
14
16
  ]
15
17
 
16
18
  from logging import Logger as LoggingLogger
@@ -117,3 +119,32 @@ type OpenInterestDict = dict[str, OpenInterestItem]
117
119
 
118
120
  type AccountType = Literal["SPOT", "FUTURES"]
119
121
  """Тип аккаунта."""
122
+
123
+
124
+ class TickerInfoItem(TypedDict):
125
+ """Информация о размерах тиков, ступеней цены и множителя контракта (если есть) для тикера."""
126
+
127
+ tick_precision: int
128
+ """Количество знаков после запятой для цены."""
129
+
130
+ size_precision: int
131
+ """Количество знаков после запятой для объема."""
132
+
133
+ contract_size: float | None
134
+ """Множитель контракта (если есть)."""
135
+
136
+ min_market_size: float | None
137
+ """Минимальный размер рыночного ордера в монетах (если есть)."""
138
+
139
+ max_market_size: float | None
140
+ """Максимальный размер рыночного ордера в монетах (если есть)."""
141
+
142
+ min_limit_size: float | None
143
+ """Минимальный размер лимитного ордера в монетах (если есть)."""
144
+
145
+ max_limit_size: float | None
146
+ """Максимальный размер лимитного ордера в монетах (если есть)."""
147
+
148
+
149
+ type TickersInfoDict = dict[str, TickerInfoItem]
150
+ """Информация о размерах тиков, ступеней цены и множителя контракта (если есть) для всех тикеров."""
@@ -0,0 +1,192 @@
1
+ Metadata-Version: 2.4
2
+ Name: unicex
3
+ Version: 0.8.0
4
+ Summary: Unified Crypto Exchange API
5
+ Author-email: LoveBloodAndDiamonds <ayazshakirzyanov27@gmail.com>
6
+ License: BSD 3-Clause License
7
+
8
+ Copyright (c) 2025, LoveBloodAndDiamonds
9
+
10
+ Redistribution and use in source and binary forms, with or without
11
+ modification, are permitted provided that the following conditions are met:
12
+
13
+ 1. Redistributions of source code must retain the above copyright notice, this
14
+ list of conditions and the following disclaimer.
15
+
16
+ 2. Redistributions in binary form must reproduce the above copyright notice,
17
+ this list of conditions and the following disclaimer in the documentation
18
+ and/or other materials provided with the distribution.
19
+
20
+ 3. Neither the name of the copyright holder nor the names of its
21
+ contributors may be used to endorse or promote products derived from
22
+ this software without specific prior written permission.
23
+
24
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
+
35
+ Project-URL: Github, https://github.com/LoveBloodAndDiamonds/uni-cex-api
36
+ Project-URL: Author, https://t.me/LoveBloodAndDiamonds
37
+ Project-URL: Readthedocs, https://unicex.readthedocs.io/ru/latest/
38
+ Requires-Python: >=3.12
39
+ Description-Content-Type: text/markdown
40
+ License-File: LICENSE
41
+ Requires-Dist: aiohttp>=3.12.15
42
+ Requires-Dist: eth-account>=0.13.7
43
+ Requires-Dist: loguru>=0.7.3
44
+ Requires-Dist: msgpack>=1.1.1
45
+ Requires-Dist: orjson>=3.11.3
46
+ Requires-Dist: websockets>=15.0.1
47
+ Dynamic: license-file
48
+
49
+ # Unified Crypto Exchange API
50
+
51
+ `unicex` — асинхронная библиотека для работы с криптовалютными биржами, реализующая унифицированный интерфейс поверх «сырых» REST и WebSocket API разных бирж.
52
+
53
+ ## ✅ Статус реализации
54
+
55
+ | Exchange | Client | Auth | WS Manager | User WS | Uni Client | Uni WS Manager | ExchangeInfo |
56
+ |-----------------|--------|------|------------|---------|------------|----------------|--------------|
57
+ | **Binance** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |
58
+ | **Bitget** | ✓ | ✓ | ✓ | | ✓ | | |
59
+ | **Bybit** | ✓ | ✓ | | | ✓ | | |
60
+ | **Gateio** | ✓ | ✓ | | | ✓ | | |
61
+ | **Hyperliquid** | ✓ | ✓ | | | ✓ | | |
62
+ | **Mexc** | ✓ | ✓ | | | ✓ | | |
63
+ | **Okx** | ✓ | ✓ | | | ✓ | | ✓ |
64
+ ---
65
+
66
+
67
+ ### 📖 Описание колонок
68
+
69
+ - **Client** – Обертки над HTTP методами следующих разделов: market, order, position, account.
70
+ - **Auth** – Поддержка авторизации и приватных эндпоинтов.
71
+ - **WS Manager** – Обертки над вебсокетами биржи.
72
+ - **User WS** – Поддержка пользовательских вебсокетов.
73
+ - **UniClient** –Унифированный клиент.
74
+ - **UniWebsocketManager** – Унифированный менеджер вебсокетов.
75
+ - **ExchangeInfo** - Информация о бирже для округления цен и объемов
76
+ ---
77
+
78
+ ## 🚀 Быстрый старт
79
+
80
+ - Установка: `pip install unicex` или из исходников: `pip install -e .`
81
+ - Библиотека полностью асинхронная. Примеры импорта:
82
+ - Сырые клиенты: `from unicex.binance import Client`
83
+ - Унифицированные клиенты: `from unicex.binance import UniClient`
84
+ - Вебсокет менеджеры: `from unicex.binance import WebsocketManager, UniWebsocketManager`
85
+
86
+ ### Пример: Получение рыночных данных через API
87
+
88
+ ```python
89
+ import asyncio
90
+
91
+ from unicex import Exchange, Timeframe, get_uni_client
92
+
93
+ # Выбираем биржу, с которой хотим работать.
94
+ # Поддерживаются: Binance, Bybit, Bitget, Mexc, Gateio, Hyperliquid и другие.
95
+ exchange = Exchange.BYBIT
96
+
97
+
98
+ async def main() -> None:
99
+ """Пример простого использования унифицированного клиента unicex."""
100
+ # 1️⃣ Создаём клиент для выбранной биржи
101
+ client = await get_uni_client(exchange).create()
102
+
103
+ # 2️⃣ Получаем открытый интерес по всем контрактам
104
+ open_interest = await client.open_interest()
105
+ print(open_interest)
106
+
107
+ # Пример вывода:
108
+ # {
109
+ # "BTCUSDT": {"t": 1759669833728, "v": 61099320.0},
110
+ # "ETHUSDT": {"t": 1759669833728, "v": 16302340.0},
111
+ # "SOLUSDT": {"t": 1759669833728, "v": 3427780.0},
112
+ # ...
113
+ # }
114
+
115
+ # 3️⃣ Можно точно так же получать другие данные в едином формате:
116
+ await client.tickers() # список всех тикеров
117
+ await client.futures_tickers() # тикеры фьючерсов
118
+ await client.ticker_24hr() # статистика за 24 часа (spot)
119
+ await client.futures_ticker_24hr() # статистика за 24 часа (futures)
120
+ await client.klines("BTCUSDT", Timeframe.MIN_5) # свечи спота
121
+ await client.futures_klines("BTCUSDT", Timeframe.HOUR_1) # свечи фьючерсов
122
+ await client.funding_rate() # ставка финансирования
123
+
124
+
125
+ if __name__ == "__main__":
126
+ asyncio.run(main())
127
+
128
+ ```
129
+
130
+ ### Пример: Получение данных в реальном времени через Websocket API
131
+
132
+ ```python
133
+ import asyncio
134
+ from unicex import Exchange, TradeDict, get_uni_websocket_manager
135
+ from unicex.enums import Timeframe
136
+
137
+ # Выбираем биржу, с которой хотим работать.
138
+ # Поддерживаются: Binance, Bybit, Bitget, Mexc, Gateio, Hyperliquid и другие.
139
+ exchange = Exchange.BITGET
140
+
141
+
142
+ async def main() -> None:
143
+ """Пример простого использования унифицированного менеджера Websocket от UniCEX."""
144
+
145
+ # 1️⃣ Создаём WebSocket-менеджер для выбранной биржи
146
+ ws_manager = get_uni_websocket_manager(exchange)()
147
+
148
+ # 2️⃣ Подключаемся к потоку сделок (aggTrades)
149
+ aggtrades_ws = ws_manager.aggtrades(
150
+ callback=callback,
151
+ symbols=["BTCUSDT", "ETHUSDT"],
152
+ )
153
+
154
+ # Запускаем получение данных
155
+ await aggtrades_ws.start()
156
+
157
+ # 3️⃣ Примеры других типов потоков:
158
+ futures_aggtrades_ws = ws_manager.futures_aggtrades(
159
+ callback=callback,
160
+ symbols=["BTCUSDT", "ETHUSDT"],
161
+ )
162
+
163
+ klines_ws = ws_manager.klines(
164
+ callback=callback,
165
+ symbols=["BTCUSDT", "ETHUSDT"],
166
+ timeframe=Timeframe.MIN_5,
167
+ )
168
+
169
+ futures_klines_ws = ws_manager.futures_klines(
170
+ callback=callback,
171
+ symbols=["BTCUSDT", "ETHUSDT"],
172
+ timeframe=Timeframe.MIN_1,
173
+ )
174
+
175
+ # 💡 Также у каждой биржи есть свой WebsocketManager:
176
+ # unicex.<exchange>.websocket_manager.WebsocketManager
177
+ # В нём реализованы остальные методы для работы с WS API.
178
+
179
+
180
+ async def callback(trade: TradeDict) -> None:
181
+ """Обработка входящих данных из Websocket."""
182
+ print(trade)
183
+ # Пример вывода:
184
+ # {'t': 1759670527594, 's': 'BTCUSDT', 'S': 'BUY', 'p': 123238.87, 'v': 0.05}
185
+ # {'t': 1759670527594, 's': 'BTCUSDT', 'S': 'BUY', 'p': 123238.87, 'v': 0.04}
186
+ # {'t': 1759670346828, 's': 'ETHUSDT', 'S': 'SELL', 'p': 4535.0, 'v': 0.0044}
187
+ # {'t': 1759670347087, 's': 'ETHUSDT', 'S': 'BUY', 'p': 4534.91, 'v': 0.2712}
188
+
189
+
190
+ if __name__ == "__main__":
191
+ asyncio.run(main())
192
+ ```
@@ -0,0 +1,75 @@
1
+ unicex/__init__.py,sha256=J9UDSWyAS8ozDxSWFXgN4002fqHVUb1Ol-YtafNtJgs,5533
2
+ unicex/enums.py,sha256=8E_Nb57kriOif57XSLnW8joFufbthZTJ7tcExKWf1Wg,9633
3
+ unicex/exceptions.py,sha256=r-xZzX78VuxVnI5pe99AM8FIiGcdIUDcF5CaTkQ4NE0,2213
4
+ unicex/extra.py,sha256=MZRSsDRok05KZCqKur-hjOexZuoZ-tC9J6e-EIZr_lw,13824
5
+ unicex/mapper.py,sha256=zOuInRQGJnSnwRI5yJ_axx-0svGn-nOqgLr7XXSlq14,4915
6
+ unicex/types.py,sha256=NMitdbyD-_pRvR_gm2aapHU7wwL8CZCaqWFIuCAYMgA,4291
7
+ unicex/utils.py,sha256=dwU1VYuP2xcMpzaETtNQerL1V8Y_JH8H8EsLJ__-M4s,8050
8
+ unicex/_abc/__init__.py,sha256=Sg0VW0vHByBX4mh8SnKFbP31yVrSJ8cqHZHM8S_KZiE,214
9
+ unicex/_abc/exchange_info.py,sha256=j0nbTeF9-_LwHGDZLBHYF2Dd1DYBCQ-DlUO5N5tZgEY,7541
10
+ unicex/_abc/uni_client.py,sha256=3jikCsByZBF126inSIY9j1lyq55K5Ro-N-rWfP0xbkw,13774
11
+ unicex/_abc/uni_websocket_manager.py,sha256=yYKypPkIe3rKfWBuTsS8rkwIPljpd1588CYDkeTOYqE,9905
12
+ unicex/_base/__init__.py,sha256=ckqI6LVP3DHuIiLXKx67rJyG0SEEsPnBr8uk1Dw9cwg,114
13
+ unicex/_base/client.py,sha256=asIIQLZlRwwmUDvxveSv7aCvth54iiSRJdz19bxGorI,8904
14
+ unicex/_base/websocket.py,sha256=LEOmO5U4YmF3NjbCRdeiawGBkP_TCTjASU49civMT_c,10186
15
+ unicex/binance/__init__.py,sha256=sDk4ZjakRdpFMaMSpOCfqjf6ZPfAS9tlrt4WlDHtDkw,932
16
+ unicex/binance/adapter.py,sha256=JbUFyjnDAFtyuYYrh90YeOvQOZQ6faim0nWS6U0NxXw,8799
17
+ unicex/binance/client.py,sha256=DuHpcQn3XfRBF5-8uFlY6gXr4QWPfeOte9vqQsCC7lI,61016
18
+ unicex/binance/exchange_info.py,sha256=_1AEa9B8Id4aj4-0VPDBL3rWE0yqwj0KFwT9N97OSeA,353
19
+ unicex/binance/uni_client.py,sha256=W4yxiU0kkJKPJjimhv4KAWreuEBwt7GgrWXefcw5BEA,8365
20
+ unicex/binance/uni_websocket_manager.py,sha256=FywEuUt3CiDcAQPo3ItdW2pPgbLDvVpVYFM2D_QscPU,8679
21
+ unicex/binance/user_websocket.py,sha256=HJ_3VZV0Bil0vfsdLrZElXm-gUqd8mGzXzfQ0_sHjFc,7861
22
+ unicex/binance/websocket_manager.py,sha256=Idrq0Qzi14QgpIG5d77S-r1h_BvRXphcxY2BT2IOQXA,45511
23
+ unicex/bitget/__init__.py,sha256=8govSOEyWjA62js-ZTQIiSYWSmcEUFSC9hVTpS8eosk,929
24
+ unicex/bitget/adapter.py,sha256=frQBOKFsIB8mXc_Ime2-Iby_nRQlSpzXjshC5AxoDTA,7741
25
+ unicex/bitget/client.py,sha256=PNjozV_qRXU2_OZVWhfHao0jJcaBO4X66ysvMdShQ-s,89687
26
+ unicex/bitget/exchange_info.py,sha256=oR0L60Ew4QDkNle5-e7CBmWBwTj-5IbW57CkEeTGDMw,352
27
+ unicex/bitget/uni_client.py,sha256=MrXAmthTDTEQZ1ZY3LuqkCKL1bw_mKHMdiV4XiRFO-M,8641
28
+ unicex/bitget/uni_websocket_manager.py,sha256=y-HXrREy_ruNeUzdRv5nHwBZQgbupxzp1UV-IFOpN_8,9793
29
+ unicex/bitget/user_websocket.py,sha256=tlkv7Rmsw_FSfCJnEMOK_9jRsXRk2Ah_slqG8C-uhuo,129
30
+ unicex/bitget/websocket_manager.py,sha256=RmJmEWwdzi05cfsmwOI2jybjIHBgt6qyYipJZ5BUw94,9916
31
+ unicex/bybit/__init__.py,sha256=SrMBh6K5zUt4JheWUpNUYNb1NCDr2ujTFv4IDguaGZI,926
32
+ unicex/bybit/adapter.py,sha256=ZgsH8jyR-fbMHSTJO6e4stT-7l5MszGuZqMJIAEOnXY,5203
33
+ unicex/bybit/client.py,sha256=FRISjOcGqR4AM02TF16fUUY54o4GUvaarWKZdy61MYQ,60971
34
+ unicex/bybit/exchange_info.py,sha256=36WiJ49TxpSdZpeMwZdjQIkRdf2wJXahdkNxVaNjNRE,351
35
+ unicex/bybit/uni_client.py,sha256=0wmIRRgofuJXWvZMB1gHwuIEfoWuPhLJXthmK1f9w40,8382
36
+ unicex/bybit/uni_websocket_manager.py,sha256=JQgZ_rl5qe30BOOMtzUYY2ZaAeQ-gYZj3HixQ1DiSpg,9328
37
+ unicex/bybit/user_websocket.py,sha256=IGGEnwyWs5jOppgK_R7SisBDvsiF1_piTswBrdQOgDg,128
38
+ unicex/bybit/websocket_manager.py,sha256=7edh7C0mMgYBRQx-_IcL21rdy-AvNfUyaZ9dL30syfI,269
39
+ unicex/gateio/__init__.py,sha256=dsKvhQhDcw4_w0S4c9IjKkCoOg4DCUtSecEUOlfstug,929
40
+ unicex/gateio/adapter.py,sha256=PE5lXQORAKLhzFZBtxcarNIt2xEcDrPrphxWS0k0wEk,6842
41
+ unicex/gateio/client.py,sha256=slwVygRBZT5dW8te6ysLJAbr56nVURwpB8eLc2xVoaA,53717
42
+ unicex/gateio/exchange_info.py,sha256=x_jZT14vMt2Cv4AtGhkFiAuCv43t4hwqQ4tiEjJ-HPY,352
43
+ unicex/gateio/uni_client.py,sha256=btfI-dozBRsbjEMvSlUX8zp6SOvIS1xDxk_5hNqRfz4,9648
44
+ unicex/gateio/uni_websocket_manager.py,sha256=3KAHhgJNISTOZRBTwbZPigc8iq_IHS19NwnuAsnfeXg,9329
45
+ unicex/gateio/user_websocket.py,sha256=4qZX9N2RjlJ-e25Eszz12OeCM17j5DdXVimBVaLj53w,129
46
+ unicex/gateio/websocket_manager.py,sha256=l2gGGHrJTNAth15pURjDkzn36gplqlhsfslPPvdypIw,270
47
+ unicex/hyperliquid/__init__.py,sha256=qGTAkwfXLvknvHET_iA7Qml3jkxxxA0moU_98nGTcVU,944
48
+ unicex/hyperliquid/adapter.py,sha256=Q45OLQBhnXAvjIhNWLMrRgzOZTGmgbZhIdIT6lVAVIg,10595
49
+ unicex/hyperliquid/client.py,sha256=8YnPh_6Hj8vFYcPbMaPae6OfroFzn28VI6iL3FQfa84,84255
50
+ unicex/hyperliquid/exchange_info.py,sha256=OBaBpAEij2Fv6q10rbQwGzBEU-5xGkCze_slEo9Q2N0,4128
51
+ unicex/hyperliquid/uni_client.py,sha256=4jv2uC076PBeq-EzCKvwaEEMk_M3HpsWA6iwNepJg7E,15674
52
+ unicex/hyperliquid/uni_websocket_manager.py,sha256=AzR_8Aq98NkCA1oc2IiH02ysMOYLaisEmcuuaafeaJw,9334
53
+ unicex/hyperliquid/user_websocket.py,sha256=BKD9ap2bx5DwpkkwwecfOTVedrZBR9eMAITgCBgg02w,134
54
+ unicex/hyperliquid/websocket_manager.py,sha256=ijs5bDX6pdQmCKvCsRowhxVf6Su_PuW58NTblwxeeXw,275
55
+ unicex/mexc/__init__.py,sha256=lltANqM_2P-fmF5j8o5-pjmORPuK6C5sVjcQhuUU_R0,923
56
+ unicex/mexc/adapter.py,sha256=GzFwUsdabh90_pRf1u2AipxJeDW7g1-2BVvSC2xvN_E,9810
57
+ unicex/mexc/client.py,sha256=RZffkRARyViEPv_LeUEc7Tni4ZGJkvoyHrG25a1UANQ,30936
58
+ unicex/mexc/exchange_info.py,sha256=Nqzn4b791H3DLXsI6YZiY34VOZgHTG7evfRNWQnd9Nk,1329
59
+ unicex/mexc/uni_client.py,sha256=0unhbU3WfqrMsV_y15VnIFjwUzQLVtp1tx6spV6cHKI,9477
60
+ unicex/mexc/uni_websocket_manager.py,sha256=MAKyGyit8Ve4doM7y8cTQbVVbpzlJx2HcHaSkLG4Jp4,9327
61
+ unicex/mexc/user_websocket.py,sha256=l77-e6i0B2btd7a5IcCytbgswnV171NqOhunTcbaq48,127
62
+ unicex/mexc/websocket_manager.py,sha256=6bl0LHPS7bDOeUkrRKVEpFBfrfHAUIG_SA_2P2beD3o,268
63
+ unicex/okx/__init__.py,sha256=Ljbw3AP0YrPF5bIPJi_3JP3B_czR9xurYHI24rgWk9M,920
64
+ unicex/okx/adapter.py,sha256=zXSLieRC80KY56ey1X-ss51uQ0QzouDxXppjcofLNRQ,5351
65
+ unicex/okx/client.py,sha256=uWcmVV9M5LpQvs89p0NFzHYytOUBt63naR9dYm6cwyM,90727
66
+ unicex/okx/exchange_info.py,sha256=q2DSVDq-JYN72LA5d_RX0C73Ha_xAxjeOobX8IxjpkM,2257
67
+ unicex/okx/uni_client.py,sha256=E_Wod0JSGt1K6k1mAIWnOv350pELbv-nic7g1KgOuos,8694
68
+ unicex/okx/uni_websocket_manager.py,sha256=b4f_QjA64DJmENQdIGb5IOVc7kvit7KMCdWeCmRbxGY,9326
69
+ unicex/okx/user_websocket.py,sha256=8c9kpm-xVa729pW93OKUGLHaE9MY0uzEpjIgNIFRF80,126
70
+ unicex/okx/websocket_manager.py,sha256=Bw25A592zTuIJQu8yR55eG7V37RwntA2LWLeMY8Popo,267
71
+ unicex-0.8.0.dist-info/licenses/LICENSE,sha256=lNNK4Vqak9cXm6qVJLhbqS7iR_BMj6k7fd7XQ6l1k54,1507
72
+ unicex-0.8.0.dist-info/METADATA,sha256=IFx_SwqjV2p8BhedS3vTrwsJi5oyyCBS4XXzfybueIY,9101
73
+ unicex-0.8.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
74
+ unicex-0.8.0.dist-info/top_level.txt,sha256=_7rar-0OENIg4KRy6cgjWiebFYAJhjKEcMggAocGWG4,7
75
+ unicex-0.8.0.dist-info/RECORD,,
unicex/bitrue/__init__.py DELETED
@@ -1,15 +0,0 @@
1
- """Пакет, содержащий реализации клиентов и менеджеров для работы с биржей Bitrue."""
2
-
3
- __all__ = [
4
- "Client",
5
- "UniClient",
6
- "UserWebsocket",
7
- "WebsocketManager",
8
- "UniWebsocketManager",
9
- ]
10
-
11
- from .client import Client
12
- from .uni_client import UniClient
13
- from .uni_websocket_manager import UniWebsocketManager
14
- from .user_websocket import UserWebsocket
15
- from .websocket_manager import WebsocketManager
unicex/bitrue/adapter.py DELETED
@@ -1,8 +0,0 @@
1
- __all__ = ["Adapter"]
2
-
3
- from unicex.utils import catch_adapter_errors, decorate_all_methods
4
-
5
-
6
- @decorate_all_methods(catch_adapter_errors)
7
- class Adapter:
8
- """Адаптер для унификации данных с Bitrue API."""
unicex/bitrue/client.py DELETED
@@ -1,128 +0,0 @@
1
- __all__ = ["Client"]
2
-
3
- import time
4
- from typing import Any
5
-
6
- from unicex._base import BaseClient
7
- from unicex.exceptions import NotAuthorized
8
- from unicex.types import RequestMethod
9
- from unicex.utils import dict_to_query_string, filter_params, generate_hmac_sha256_signature
10
-
11
-
12
- class Client(BaseClient):
13
- """Клиент для работы с Bitrue API."""
14
-
15
- _BASE_URL: str = "https://www.bitrue.com"
16
- """Базовый URL для REST API Bitrue."""
17
-
18
- _RECV_WINDOW: int = 5000
19
- """Стандартный интервал времени для получения ответа от сервера."""
20
-
21
- def _get_headers(self) -> dict[str, str]:
22
- """Возвращает заголовки для авторизованных запросов."""
23
- headers = {"Accept": "application/json"}
24
- if self._api_key: # type: ignore[attr-defined]
25
- headers["X-MBX-APIKEY"] = self._api_key # type: ignore[attr-defined]
26
- return headers
27
-
28
- def _prepare_payload(
29
- self,
30
- *,
31
- signed: bool,
32
- params: dict[str, Any] | None,
33
- data: dict[str, Any] | None,
34
- ) -> tuple[dict[str, Any], dict[str, str] | None]:
35
- """Подготавливает payload и заголовки для запроса."""
36
- params = filter_params(params) if params else {}
37
- data = filter_params(data) if data else {}
38
-
39
- if not signed:
40
- return {"params": params, "data": data}, None
41
-
42
- if not self.is_authorized():
43
- raise NotAuthorized("Api key is required to private endpoints")
44
-
45
- payload = {**params, **data}
46
- payload["timestamp"] = int(time.time() * 1000)
47
- payload["recvWindow"] = self._RECV_WINDOW
48
-
49
- query_string = dict_to_query_string(payload)
50
- payload["signature"] = generate_hmac_sha256_signature(
51
- self._api_secret, # type: ignore[attr-defined]
52
- query_string,
53
- )
54
-
55
- headers = self._get_headers()
56
- return payload, headers
57
-
58
- async def _make_request(
59
- self,
60
- method: RequestMethod,
61
- endpoint: str,
62
- signed: bool = False,
63
- *,
64
- params: dict[str, Any] | None = None,
65
- data: dict[str, Any] | None = None,
66
- ) -> Any:
67
- """Выполняет HTTP-запрос к Bitrue API."""
68
- url = f"{self._BASE_URL}{endpoint}"
69
- has_body = bool(data)
70
- payload, headers = self._prepare_payload(signed=signed, params=params, data=data)
71
-
72
- if not signed:
73
- return await super()._make_request(
74
- method=method,
75
- url=url,
76
- params=payload["params"],
77
- data=payload["data"],
78
- headers=headers,
79
- )
80
-
81
- if has_body:
82
- return await super()._make_request(
83
- method=method,
84
- url=url,
85
- data=payload,
86
- headers=headers,
87
- )
88
- return await super()._make_request(
89
- method=method,
90
- url=url,
91
- params=payload,
92
- headers=headers,
93
- )
94
-
95
- async def request(
96
- self,
97
- method: RequestMethod,
98
- endpoint: str,
99
- params: dict[str, Any] | None,
100
- data: dict[str, Any] | None,
101
- signed: bool,
102
- ) -> dict:
103
- """Специальный метод для выполнения произвольных REST-запросов.
104
-
105
- Параметры:
106
- method (`RequestMethod`): HTTP-метод запроса ("GET", "POST" и т.д.).
107
- endpoint (`str`): Относительный путь эндпоинта Bitrue API.
108
- params (`dict | None`): Query-параметры запроса.
109
- data (`dict | None`): Тело запроса.
110
- signed (`bool`): Нужно ли подписывать запрос.
111
-
112
- Возвращает:
113
- `dict`: Ответ Bitrue API.
114
- """
115
- return await self._make_request(
116
- method=method,
117
- endpoint=endpoint,
118
- params=params,
119
- data=data,
120
- signed=signed,
121
- )
122
-
123
- async def server_time(self) -> dict:
124
- """Получение серверного времени.
125
-
126
- https://www.bitrue.com/api_docs_includes_file/spot/index.html#general-endpoints
127
- """
128
- return await self._make_request("GET", "/api/v1/time")