From c6bd752fe304a55d98f0b7e617089304cf3aa0f8 Mon Sep 17 00:00:00 2001 From: Morty Space Date: Sat, 8 Jan 2022 15:53:50 +0200 Subject: [PATCH] Fixed ticker, added websocket reconnect timeout --- README.md | 1 + setup.py | 3 ++- src/cryptocom/exchange/__init__.py | 2 +- src/cryptocom/exchange/api.py | 26 ++++++++++++++------------ tests/test_market.py | 2 +- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index d331177..ec9994b 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ Exchange original API docs: [https://exchange-docs.crypto.com](https://exchange- ### Changelog +- **0.10.1** - added read timeouts for websockets, fixed test with tickers - **0.10.0** - moved into httpx + websockets, added autoreconnect, simplified code, improved stability - **0.9.5** - added timeout for websocket if no data received in 3 mins we trying to reconnect - **0.9.4** - fixed spread func, fixed missing params diff --git a/setup.py b/setup.py index f7ed245..06d4da0 100644 --- a/setup.py +++ b/setup.py @@ -40,7 +40,8 @@ setup( 'httpx', 'websockets', 'cached-property', - 'aiolimiter' + 'aiolimiter', + 'async-timeout' ], extras_require={ 'dev': [ diff --git a/src/cryptocom/exchange/__init__.py b/src/cryptocom/exchange/__init__.py index a0bbcf5..e1cf4f1 100644 --- a/src/cryptocom/exchange/__init__.py +++ b/src/cryptocom/exchange/__init__.py @@ -23,4 +23,4 @@ __all__ = [ 'ApiError', 'ApiProvider' ] -__version__ = '0.10.0' +__version__ = '0.10.1' diff --git a/src/cryptocom/exchange/api.py b/src/cryptocom/exchange/api.py index 3a3ada5..fcf08a9 100644 --- a/src/cryptocom/exchange/api.py +++ b/src/cryptocom/exchange/api.py @@ -7,11 +7,11 @@ import asyncio import hashlib from urllib.parse import urljoin -from aiolimiter import AsyncLimiter - import httpx import websockets +import async_timeout +import aiolimiter RATE_LIMITS = { @@ -138,11 +138,12 @@ class ApiProvider: for urls in RATE_LIMITS: for url in urls: - self.rate_limiters[url] = AsyncLimiter(*RATE_LIMITS[urls]) + self.rate_limiters[url] =\ + aiolimiter.AsyncLimiter(*RATE_LIMITS[urls]) # limits for not matched methods - self.general_private_limit = AsyncLimiter(3, 0.1) - self.general_public_limit = AsyncLimiter(100, 1) + self.general_private_limit = aiolimiter.AsyncLimiter(3, 0.1) + self.general_public_limit = aiolimiter.AsyncLimiter(100, 1) if not auth_required: return @@ -223,15 +224,14 @@ class ApiProvider: if count == self.retries: raise ApiError( f"Timeout error, retries: {self.retries}. " - f"Code: {resp.status_code}. Data: {data}" + f"Path: {path}. Data: {data}" ) from exc continue except json.JSONDecodeError: if resp.status_code == 429: continue - text = await resp.text raise ApiError( - f"Can't decode json, content: {text}. " + f"Can't decode json, content: {resp.text()}. " f"Code: {resp.status_code}") finally: await client.aclose() @@ -258,8 +258,10 @@ class ApiProvider: async for ws in websockets.connect(url, open_timeout=self.timeout): try: dataiterator = ApiListenAsyncIterable(self, ws, channels, sign) - async for data in dataiterator: - if data: - yield data - except websockets.ConnectionClosed: + async with async_timeout.timeout(60) as tm: + async for data in dataiterator: + if data: + tm.shift(60) + yield data + except (websockets.ConnectionClosed, asyncio.TimeoutError): continue diff --git a/tests/test_market.py b/tests/test_market.py index 2c878a2..051b608 100644 --- a/tests/test_market.py +++ b/tests/test_market.py @@ -18,7 +18,7 @@ async def test_get_pairs(exchange: cro.Exchange): async def test_get_tickers(exchange: cro.Exchange): tickers = await exchange.get_tickers() for pair, ticker in tickers.items(): - assert ticker.high > ticker.low + assert ticker.high >= ticker.low assert ticker.pair == pair assert ticker.volume > 0