exchanges-wrapper 2.1.15__tar.gz → 2.1.17__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.
- {exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/PKG-INFO +1 -1
- {exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/exchanges_wrapper/__init__.py +1 -1
- {exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/exchanges_wrapper/client.py +10 -7
- {exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/exchanges_wrapper/exch_srv.py +1 -1
- {exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/exchanges_wrapper/parsers/okx_parser.py +1 -1
- {exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/exchanges_wrapper/web_sockets.py +23 -8
- {exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/LICENSE.md +0 -0
- {exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/README.md +0 -0
- {exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/exchanges_wrapper/definitions.py +0 -0
- {exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/exchanges_wrapper/errors.py +0 -0
- {exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/exchanges_wrapper/events.py +0 -0
- {exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/exchanges_wrapper/exch_srv_cfg.toml.template +0 -0
- {exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/exchanges_wrapper/http_client.py +0 -0
- {exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/exchanges_wrapper/lib.py +0 -0
- {exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/exchanges_wrapper/martin/__init__.py +0 -0
- {exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/exchanges_wrapper/parsers/bitfinex_parser.py +0 -0
- {exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/exchanges_wrapper/parsers/bybit_parser.py +0 -0
- {exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/exchanges_wrapper/parsers/huobi_parser.py +0 -0
- {exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/exchanges_wrapper/proto/martin.proto +0 -0
- {exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/pyproject.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: exchanges-wrapper
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.17
|
|
4
4
|
Summary: REST API and WebSocket asyncio wrapper with grpc powered multiplexer server
|
|
5
5
|
Author-email: Thomas Marchand <thomas.marchand@tuta.io>, Jerry Fedorenko <jerry.fedorenko@yahoo.com>
|
|
6
6
|
Requires-Python: >=3.9
|
|
@@ -12,7 +12,7 @@ __maintainer__ = "Jerry Fedorenko"
|
|
|
12
12
|
__contact__ = "https://github.com/DogsTailFarmer"
|
|
13
13
|
__email__ = "jerry.fedorenko@yahoo.com"
|
|
14
14
|
__credits__ = ["https://github.com/DanyaSWorlD"]
|
|
15
|
-
__version__ = "2.1.
|
|
15
|
+
__version__ = "2.1.17"
|
|
16
16
|
|
|
17
17
|
from pathlib import Path
|
|
18
18
|
import shutil
|
|
@@ -354,13 +354,7 @@ class Client:
|
|
|
354
354
|
server_time = await self.fetch_server_time()
|
|
355
355
|
params = {'symbols': symbol.lower()}
|
|
356
356
|
trading_symbol = await self.http.send_api_call("v1/settings/common/market-symbols", **params)
|
|
357
|
-
|
|
358
|
-
accounts = await self.http.send_api_call("v1/account/accounts", signed=True)
|
|
359
|
-
for account in accounts:
|
|
360
|
-
if account.get('type') == 'spot':
|
|
361
|
-
self.account_id = account.get('id')
|
|
362
|
-
break
|
|
363
|
-
self.account_uid = await self.http.send_api_call("v2/user/uid", signed=True)
|
|
357
|
+
await self.set_htx_ids()
|
|
364
358
|
binance_res = hbp.exchange_info(server_time.get('serverTime'), trading_symbol[0])
|
|
365
359
|
elif self.exchange == 'okx':
|
|
366
360
|
params = {'instType': 'SPOT'}
|
|
@@ -376,6 +370,15 @@ class Client:
|
|
|
376
370
|
# logger.info(f"fetch_exchange_info: binance_res: {binance_res}")
|
|
377
371
|
return binance_res
|
|
378
372
|
|
|
373
|
+
async def set_htx_ids(self):
|
|
374
|
+
if self.account_id is None:
|
|
375
|
+
accounts = await self.http.send_api_call("v1/account/accounts", signed=True)
|
|
376
|
+
for account in accounts:
|
|
377
|
+
if account.get('type') == 'spot':
|
|
378
|
+
self.account_id = account.get('id')
|
|
379
|
+
break
|
|
380
|
+
self.account_uid = await self.http.send_api_call("v2/user/uid", signed=True)
|
|
381
|
+
|
|
379
382
|
# MARKET DATA ENDPOINTS
|
|
380
383
|
|
|
381
384
|
# https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#order-book
|
|
@@ -173,7 +173,7 @@ class Martin(mr.MartinBase):
|
|
|
173
173
|
# For HuobiPro get master account uid and account_id
|
|
174
174
|
main_account = get_account(open_client.client.master_name)
|
|
175
175
|
main_client = Client(*main_account)
|
|
176
|
-
await main_client.
|
|
176
|
+
await asyncio.wait_for(main_client.set_htx_ids(), timeout=HEARTBEAT * 60)
|
|
177
177
|
if main_client.account_uid and main_client.account_id:
|
|
178
178
|
open_client.client.main_account_uid = main_client.account_uid
|
|
179
179
|
open_client.client.main_account_id = main_client.account_id
|
{exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/exchanges_wrapper/parsers/okx_parser.py
RENAMED
|
@@ -16,7 +16,7 @@ def fetch_server_time(res: []) -> {}:
|
|
|
16
16
|
def exchange_info(server_time: int, trading_symbol: [], tickers: [], symbol_t) -> {}:
|
|
17
17
|
symbols = []
|
|
18
18
|
symbols_price = {
|
|
19
|
-
pair.get('instId').replace('-', ''): Decimal(pair.get('last'))
|
|
19
|
+
pair.get('instId').replace('-', ''): Decimal(pair.get('last', '0'))
|
|
20
20
|
for pair in tickers
|
|
21
21
|
}
|
|
22
22
|
for market in trading_symbol:
|
|
@@ -17,10 +17,7 @@ import exchanges_wrapper.parsers.bybit_parser as bbt
|
|
|
17
17
|
from crypto_ws_api.ws_session import generate_signature
|
|
18
18
|
from exchanges_wrapper import LOG_PATH
|
|
19
19
|
|
|
20
|
-
logger = logging.getLogger(
|
|
21
|
-
|
|
22
|
-
logger_ws = logging.getLogger(__name__)
|
|
23
|
-
logger_ws.level = logging.INFO
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
24
21
|
formatter = logging.Formatter(fmt="[%(asctime)s: %(levelname)s] %(message)s")
|
|
25
22
|
#
|
|
26
23
|
fh = logging.handlers.RotatingFileHandler(Path(LOG_PATH, 'websockets.log'), maxBytes=1000000, backupCount=10)
|
|
@@ -31,8 +28,9 @@ sh = logging.StreamHandler()
|
|
|
31
28
|
sh.setFormatter(formatter)
|
|
32
29
|
sh.setLevel(logging.INFO)
|
|
33
30
|
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
logger.addHandler(fh)
|
|
32
|
+
logger.addHandler(sh)
|
|
33
|
+
logger.propagate = False
|
|
36
34
|
|
|
37
35
|
sys.tracebacklimit = 0
|
|
38
36
|
|
|
@@ -50,12 +48,13 @@ class EventsDataStream:
|
|
|
50
48
|
self._price = None
|
|
51
49
|
self.tasks = set()
|
|
52
50
|
self.wss_started = False
|
|
51
|
+
self.ping = 0
|
|
53
52
|
|
|
54
53
|
async def start(self):
|
|
55
54
|
ping_interval = None if self.exchange == 'huobi' else 20
|
|
56
55
|
async for self.websocket in websockets.connect(
|
|
57
56
|
self.endpoint,
|
|
58
|
-
logger=
|
|
57
|
+
logger=logger,
|
|
59
58
|
ping_interval=ping_interval
|
|
60
59
|
):
|
|
61
60
|
try:
|
|
@@ -66,7 +65,7 @@ class EventsDataStream:
|
|
|
66
65
|
logger.info(f"WSS closed for {self.exchange}:{self.trade_id}")
|
|
67
66
|
break
|
|
68
67
|
else:
|
|
69
|
-
logger.warning(f"Restart WSS for {self.exchange}")
|
|
68
|
+
logger.warning(f"Restart WSS for {self.exchange}: {ex}")
|
|
70
69
|
continue
|
|
71
70
|
except Exception as ex:
|
|
72
71
|
self.tasks_cancel()
|
|
@@ -187,9 +186,11 @@ class EventsDataStream:
|
|
|
187
186
|
logger.debug(f"Bitfinex undefined WSS: symbol: {symbol}, ch_type: {ch_type}, msg_data: {msg_data}")
|
|
188
187
|
elif self.exchange == 'huobi':
|
|
189
188
|
if ping := msg_data.get('ping'):
|
|
189
|
+
self.ping = 0
|
|
190
190
|
await self.websocket.send(json.dumps({"pong": ping}))
|
|
191
191
|
await asyncio.sleep(0)
|
|
192
192
|
elif msg_data.get('action') == 'ping':
|
|
193
|
+
self.ping = 0
|
|
193
194
|
pong = {
|
|
194
195
|
"action": "pong",
|
|
195
196
|
"data": {
|
|
@@ -229,6 +230,17 @@ class EventsDataStream:
|
|
|
229
230
|
await asyncio.sleep(interval)
|
|
230
231
|
await self.websocket.send(json.dumps({"req_id": req_id, "op": "ping"}))
|
|
231
232
|
|
|
233
|
+
async def htx_keepalive(self, interval=60):
|
|
234
|
+
await asyncio.sleep(interval * 10)
|
|
235
|
+
while True:
|
|
236
|
+
await asyncio.sleep(interval)
|
|
237
|
+
if self.ping:
|
|
238
|
+
break
|
|
239
|
+
else:
|
|
240
|
+
self.ping = 1
|
|
241
|
+
logger.warning("From HTX server PING timeout exceeded")
|
|
242
|
+
await self.websocket.close()
|
|
243
|
+
|
|
232
244
|
|
|
233
245
|
class MarketEventsDataStream(EventsDataStream):
|
|
234
246
|
def __init__(self, client, endpoint, exchange, trade_id, channel=None):
|
|
@@ -300,6 +312,8 @@ class MarketEventsDataStream(EventsDataStream):
|
|
|
300
312
|
elif ch_type == 'depth5':
|
|
301
313
|
request = {'sub': f"market.{symbol}.depth.step0"}
|
|
302
314
|
|
|
315
|
+
self.tasks_manage(self.htx_keepalive(interval=30))
|
|
316
|
+
|
|
303
317
|
await self.ws_listener(request, symbol, ch_type)
|
|
304
318
|
|
|
305
319
|
async def _handle_event(self, content, symbol=None, ch_type=str()):
|
|
@@ -404,6 +418,7 @@ class HbpPrivateEventsDataStream(EventsDataStream):
|
|
|
404
418
|
"action": "sub",
|
|
405
419
|
"ch": f"trade.clearing#{self.symbol.lower()}#0"
|
|
406
420
|
}
|
|
421
|
+
self.tasks_manage(self.htx_keepalive())
|
|
407
422
|
await self.ws_listener(request, symbol=self.symbol)
|
|
408
423
|
|
|
409
424
|
async def _handle_event(self, msg_data, *args):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/exchanges_wrapper/exch_srv_cfg.toml.template
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/exchanges_wrapper/parsers/bitfinex_parser.py
RENAMED
|
File without changes
|
{exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/exchanges_wrapper/parsers/bybit_parser.py
RENAMED
|
File without changes
|
{exchanges_wrapper-2.1.15 → exchanges_wrapper-2.1.17}/exchanges_wrapper/parsers/huobi_parser.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|