From 551e424782a5c91942645b4cff84b2de194bd364 Mon Sep 17 00:00:00 2001 From: Saleh Mir Date: Sat, 28 Dec 2024 20:40:37 +0330 Subject: [PATCH] feat(BybitMain): implement session with retry strategy for API requests - Enhanced the BybitMain class to use a requests.Session with a retry strategy, improving resilience against transient network issues. - Updated API calls to utilize the session, allowing for automatic retries on specified HTTP status codes. - Added timeout settings to API requests to prevent hanging connections. --- .../drivers/Bybit/BybitMain.py | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/jesse/modes/import_candles_mode/drivers/Bybit/BybitMain.py b/jesse/modes/import_candles_mode/drivers/Bybit/BybitMain.py index 318f3bba3..be3d08d47 100644 --- a/jesse/modes/import_candles_mode/drivers/Bybit/BybitMain.py +++ b/jesse/modes/import_candles_mode/drivers/Bybit/BybitMain.py @@ -1,4 +1,6 @@ import requests +from requests.adapters import HTTPAdapter +from urllib3.util.retry import Retry import jesse.helpers as jh from jesse.modes.import_candles_mode.drivers.interface import CandleExchange from typing import Union @@ -14,6 +16,16 @@ def __init__(self, name: str, rest_endpoint: str, category: str) -> None: self.name = name self.endpoint = rest_endpoint self.category = category + + # Setup session with retry strategy + self.session = requests.Session() + retries = Retry( + total=3, + backoff_factor=1, + status_forcelist=[408, 429, 500, 502, 503, 504], + allowed_methods=["HEAD", "GET", "POST"] + ) + self.session.mount('https://', HTTPAdapter(max_retries=retries, pool_maxsize=100)) def get_starting_time(self, symbol: str) -> int: dashless_symbol = jh.dashless_symbol(symbol) @@ -25,12 +37,11 @@ def get_starting_time(self, symbol: str) -> int: 'start': 1514811660000 } - response = requests.get(self.endpoint + '/v5/market/kline', params=payload) + response = self.session.get(self.endpoint + '/v5/market/kline', params=payload, timeout=10) self.validate_response(response) data = response.json()['result']['list'] # Reverse the data list data = data[::-1] - return int(data[1][0]) def fetch(self, symbol: str, start_timestamp: int, timeframe: str = '1m') -> Union[list, None]: @@ -44,7 +55,7 @@ def fetch(self, symbol: str, start_timestamp: int, timeframe: str = '1m') -> Uni 'limit': self.count } - response = requests.get(self.endpoint + '/v5/market/kline', params=payload) + response = self.session.get(self.endpoint + '/v5/market/kline', params=payload, timeout=10) if response.json()['retMsg'] != 'OK': raise exceptions.SymbolNotFound(response.json()['retMsg']) @@ -68,8 +79,7 @@ def fetch(self, symbol: str, start_timestamp: int, timeframe: str = '1m') -> Uni ] def get_available_symbols(self) -> list: - response = requests.get(self.endpoint + '/v5/market/instruments-info?category=' + self.category) + response = self.session.get(self.endpoint + '/v5/market/instruments-info?category=' + self.category, timeout=10) self.validate_response(response) data = response.json()['result']['list'] - return [jh.dashy_symbol(d['symbol']) for d in data]