Add backoff timer for coingecko API

Set a future timestamp when we should retry getting coingecko data.

This fixes conversion from stake to fiat when running multiple bots
as we don't simply accept the 429 error from Coingecko but handle it.
This commit is contained in:
A. Schueler 2021-05-17 11:31:19 +02:00
parent df0928c8b5
commit a0921ec753

View File

@ -4,10 +4,12 @@ e.g BTC to USD
""" """
import logging import logging
from typing import Dict import datetime
from typing import Dict
from cachetools.ttl import TTLCache from cachetools.ttl import TTLCache
from pycoingecko import CoinGeckoAPI from pycoingecko import CoinGeckoAPI
from requests.exceptions import RequestException
from freqtrade.constants import SUPPORTED_FIAT from freqtrade.constants import SUPPORTED_FIAT
@ -25,6 +27,7 @@ class CryptoToFiatConverter:
_coingekko: CoinGeckoAPI = None _coingekko: CoinGeckoAPI = None
_cryptomap: Dict = {} _cryptomap: Dict = {}
_backoff = int
def __new__(cls): def __new__(cls):
""" """
@ -47,8 +50,13 @@ class CryptoToFiatConverter:
def _load_cryptomap(self) -> None: def _load_cryptomap(self) -> None:
try: try:
coinlistings = self._coingekko.get_coins_list() coinlistings = self._coingekko.get_coins_list()
# Create mapping table from synbol to coingekko_id # Create mapping table from symbol to coingekko_id
self._cryptomap = {x['symbol']: x['id'] for x in coinlistings} self._cryptomap = {x['symbol']: x['id'] for x in coinlistings}
except RequestException as request_exception:
if "429" in str(request_exception):
logger.warning("Too many requests for Coingecko API, backing off and trying again later.")
# Set backoff timestamp to 60 seconds in the future
self._backoff = datetime.datetime.now().timestamp() + 60
except (Exception) as exception: except (Exception) as exception:
logger.error( logger.error(
f"Could not load FIAT Cryptocurrency map for the following problem: {exception}") f"Could not load FIAT Cryptocurrency map for the following problem: {exception}")
@ -127,6 +135,9 @@ class CryptoToFiatConverter:
if crypto_symbol == fiat_symbol: if crypto_symbol == fiat_symbol:
return 1.0 return 1.0
if self._cryptomap == {} and self._backoff <= datetime.datetime.now().timestamp():
self._load_cryptomap()
if crypto_symbol not in self._cryptomap: if crypto_symbol not in self._cryptomap:
# return 0 for unsupported stake currencies (fiat-convert should not break the bot) # return 0 for unsupported stake currencies (fiat-convert should not break the bot)
logger.warning("unsupported crypto-symbol %s - returning 0.0", crypto_symbol) logger.warning("unsupported crypto-symbol %s - returning 0.0", crypto_symbol)