crypto-ws-api 2.0.8__tar.gz → 2.0.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.
@@ -1,3 +1,11 @@
1
+ ## 2.0.10 - 2024-04-19
2
+ ### Update
3
+ * Some minor improvement
4
+
5
+ ## 2.0.9 - 2024-04-14
6
+ ### Fix
7
+ * Creating asynchronous tasks done right
8
+
1
9
  ## 2.0.8 - 2024-03-31
2
10
  ### Fix
3
11
  * tons log records: `websockets socket.send() raised exception.`
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: crypto-ws-api
3
- Version: 2.0.8
3
+ Version: 2.0.10
4
4
  Summary: Crypto WS API connector for ASYNC requests
5
5
  Author-email: Jerry Fedorenko <jerry.fedorenko@yahoo.com>
6
6
  Requires-Python: >=3.8
@@ -13,7 +13,7 @@ __maintainer__ = "Jerry Fedorenko"
13
13
  __contact__ = "https://github.com/DogsTailFarmer"
14
14
  __email__ = "jerry.fedorenko@yahoo.com"
15
15
  __credits__ = ["https://github.com/DanyaSWorlD"]
16
- __version__ = "2.0.8"
16
+ __version__ = "2.0.10"
17
17
 
18
18
  from pathlib import Path
19
19
  import shutil
@@ -66,7 +66,7 @@ class UserWSS:
66
66
  "request_limit_reached",
67
67
  "in_event",
68
68
  "_response_pool",
69
- "tasks_list",
69
+ "tasks",
70
70
  )
71
71
 
72
72
  def __init__(self, method, ws_id, exchange, endpoint, api_key, api_secret, passphrase=None):
@@ -87,10 +87,15 @@ class UserWSS:
87
87
  self.order_handling = False
88
88
  self.request_limit_reached = False
89
89
  self.in_event = asyncio.Event()
90
- self.tasks_list = []
90
+ self.tasks = set()
91
+
92
+ def tasks_manage(self, coro, name=None):
93
+ _t = asyncio.create_task(coro, name=name)
94
+ self.tasks.add(_t)
95
+ _t.add_done_callback(self.tasks.discard)
91
96
 
92
97
  async def _ws_listener(self):
93
- asyncio.ensure_future(self.ws_login())
98
+ self.tasks_manage(self.ws_login())
94
99
  async for msg in self._ws:
95
100
  # logger.info(f"_ws_listener: msg: {self.ws_id}: {msg}")
96
101
  if isinstance(msg, str):
@@ -119,8 +124,8 @@ class UserWSS:
119
124
  break
120
125
  else:
121
126
  self.operational_status = False
122
- [task.cancel() for task in self.tasks_list if not task.done()]
123
- self.tasks_list.clear()
127
+ [task.cancel() for task in self.tasks if not task.done()]
128
+ self.tasks.clear()
124
129
  logger.warning(f"Restart WSS for {self.ws_id}")
125
130
  continue
126
131
  except Exception as ex:
@@ -134,16 +139,12 @@ class UserWSS:
134
139
  else:
135
140
  if self.exchange == 'binance':
136
141
  self._listen_key = res.get('listenKey')
137
- _t = asyncio.ensure_future(self.heartbeat())
138
- _t.set_name(f"heartbeat-{self.ws_id}")
139
- self.tasks_list.append(_t)
142
+ self.tasks_manage(self.heartbeat(), f"heartbeat-{self.ws_id}")
140
143
  else:
141
144
  self._listen_key = f"{int(time.time() * 1000)}{self.ws_id}"
142
145
  self.operational_status = True
143
146
  self.order_handling = True
144
- _t = asyncio.ensure_future(self._keepalive())
145
- _t.set_name(f"keepalive-{self.ws_id}")
146
- self.tasks_list.append(_t)
147
+ self.tasks_manage(self._keepalive(), f"keepalive-{self.ws_id}")
147
148
  logger.info(f"UserWSS: 'logged in' for {self.ws_id}")
148
149
 
149
150
  async def request(self, _method=None, _params=None, _api_key=False, _signed=False):
@@ -275,8 +276,8 @@ class UserWSS:
275
276
  self.operational_status = None # Not restart and break all loops
276
277
  self.order_handling = False
277
278
  self.init = True
278
- [task.cancel() for task in self.tasks_list if not task.done()]
279
- self.tasks_list.clear()
279
+ [task.cancel() for task in self.tasks if not task.done()]
280
+ self.tasks.clear()
280
281
  if self._ws and not self._ws.closed:
281
282
  await self._ws.close(code=4000)
282
283
  gc.collect()
@@ -297,7 +298,7 @@ class UserWSS:
297
298
  elif self.exchange == 'bitfinex':
298
299
  return await self.bitfinex_error_handle(msg)
299
300
 
300
- #region BitfinexErrorHandle
301
+ # region BitfinexErrorHandle
301
302
  async def bitfinex_error_handle(self, msg):
302
303
  if isinstance(msg, dict):
303
304
  return await self._handle_dict_message(msg)
@@ -349,7 +350,7 @@ class UserWSS:
349
350
  msg[2][7]
350
351
  ]
351
352
  }
352
- #endregion
353
+ # endregion
353
354
 
354
355
  async def okx_error_handle(self, msg):
355
356
  if msg.get('code') == '1':
@@ -391,6 +392,7 @@ class UserWSSession:
391
392
  "_api_secret",
392
393
  "_passphrase",
393
394
  "user_wss",
395
+ "tasks_wss",
394
396
  )
395
397
 
396
398
  def __init__(self, exchange, endpoint, api_key, api_secret, passphrase=None):
@@ -403,6 +405,7 @@ class UserWSSession:
403
405
  self._api_secret = api_secret
404
406
  self._passphrase = passphrase
405
407
  self.user_wss = {}
408
+ self.tasks_wss = set()
406
409
 
407
410
  async def handle_request(
408
411
  self,
@@ -429,7 +432,9 @@ class UserWSSession:
429
432
  if user_wss.init:
430
433
  user_wss.init = False
431
434
  user_wss.operational_status = False
432
- asyncio.ensure_future(user_wss.start_wss())
435
+ _t = asyncio.create_task(user_wss.start_wss())
436
+ self.tasks_wss.add(_t)
437
+ _t.add_done_callback(self.tasks_wss.discard)
433
438
 
434
439
  duration = 0
435
440
  while not (user_wss.operational_status and user_wss.order_handling):
@@ -451,3 +456,5 @@ class UserWSSession:
451
456
  for ws in user_wss_copy.values():
452
457
  await ws.stop()
453
458
  self.user_wss.clear()
459
+ [task.cancel() for task in self.tasks_wss if not task.done()]
460
+ self.tasks_wss.clear()
File without changes
File without changes