From 1201e33393ba283c6ce8c8f1e03518937020219a Mon Sep 17 00:00:00 2001 From: Manit Arora Date: Mon, 29 Jun 2026 20:52:59 +0530 Subject: [PATCH] Fix BtcConverter by migrating from decommissioned CoinDesk API to Coinbase --- forex_python/bitcoin.py | 110 ++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 65 deletions(-) diff --git a/forex_python/bitcoin.py b/forex_python/bitcoin.py index b699a4d..b93fde6 100644 --- a/forex_python/bitcoin.py +++ b/forex_python/bitcoin.py @@ -22,55 +22,51 @@ def get_latest_price(self, currency): """ Get latest price of one Bitcoin to valid currency 1BTC => X USD """ - url = 'https://api.coindesk.com/v1/bpi/currentprice/{}.json'.format(currency) + url = 'https://api.coinbase.com/v2/prices/BTC-{}/spot'.format(currency) response = requests.get(url) if response.status_code == 200: data = response.json() - price = data.get('bpi').get(currency, {}).get('rate_float', None) - if self._force_decimal: - return Decimal(price) - return price + price_str = data.get('data', {}).get('amount', None) + if price_str is not None: + if self._force_decimal: + return Decimal(price_str) + return float(price_str) return None def get_previous_price(self, currency, date_obj): """ Get price for one Bitcoin on given date """ - start = date_obj.strftime('%Y-%m-%d') - end = date_obj.strftime('%Y-%m-%d') - url = ( - 'https://api.coindesk.com/v1/bpi/historical/close.json' - '?start={}&end={}¤cy={}'.format( - start, end, currency - ) - ) + date_str = date_obj.strftime('%Y-%m-%d') + url = 'https://api.coinbase.com/v2/prices/BTC-{}/spot?date={}'.format(currency, date_str) response = requests.get(url) if response.status_code == 200: data = response.json() - price = data.get('bpi', {}).get(start, None) - if self._force_decimal: - return Decimal(price) - return price + price_str = data.get('data', {}).get('amount', None) + if price_str is not None: + if self._force_decimal: + return Decimal(price_str) + return float(price_str) raise RatesNotAvailableError("BitCoin Rates Source Not Ready For Given date") def get_previous_price_list(self, currency, start_date, end_date): """ Get list of Bitcoin prices between two dates """ - start = start_date.strftime('%Y-%m-%d') - end = end_date.strftime('%Y-%m-%d') - url = ( - 'https://api.coindesk.com/v1/bpi/historical/close.json' - '?start={}&end={}¤cy={}'.format( - start, end, currency - ) - ) - response = requests.get(url) - if response.status_code == 200: - data = self._decode_rates(response) - price_dict = data.get('bpi', {}) - return price_dict - return {} + from datetime import timedelta + price_dict = {} + curr_date = start_date + while curr_date <= end_date: + date_str = curr_date.strftime('%Y-%m-%d') + url = 'https://api.coinbase.com/v2/prices/BTC-{}/spot?date={}'.format(currency, date_str) + response = requests.get(url) + if response.status_code == 200: + data = response.json() + price_str = data.get('data', {}).get('amount', None) + if price_str is not None: + price_dict[date_str] = Decimal(price_str) if self._force_decimal else float(price_str) + curr_date += timedelta(days=1) + return price_dict def convert_to_btc(self, amount, currency): """ @@ -81,14 +77,13 @@ def convert_to_btc(self, amount, currency): else: use_decimal = self._force_decimal - url = 'https://api.coindesk.com/v1/bpi/currentprice/{}.json'.format(currency) + url = 'https://api.coinbase.com/v2/prices/BTC-{}/spot'.format(currency) response = requests.get(url) if response.status_code == 200: data = response.json() - price = data.get('bpi').get(currency, {}).get('rate_float', None) - if price: - if use_decimal: - price = Decimal(price) + price_str = data.get('data', {}).get('amount', None) + if price_str: + price = Decimal(price_str) if use_decimal else float(price_str) try: converted_btc = amount/price return converted_btc @@ -105,14 +100,13 @@ def convert_btc_to_cur(self, coins, currency): else: use_decimal = self._force_decimal - url = 'https://api.coindesk.com/v1/bpi/currentprice/{}.json'.format(currency) + url = 'https://api.coinbase.com/v2/prices/BTC-{}/spot'.format(currency) response = requests.get(url) if response.status_code == 200: data = response.json() - price = data.get('bpi').get(currency, {}).get('rate_float', None) - if price: - if use_decimal: - price = Decimal(price) + price_str = data.get('data', {}).get('amount', None) + if price_str: + price = Decimal(price_str) if use_decimal else float(price_str) try: converted_amount = coins * price return converted_amount @@ -129,21 +123,14 @@ def convert_to_btc_on(self, amount, currency, date_obj): else: use_decimal = self._force_decimal - start = date_obj.strftime('%Y-%m-%d') - end = date_obj.strftime('%Y-%m-%d') - url = ( - 'https://api.coindesk.com/v1/bpi/historical/close.json' - '?start={}&end={}¤cy={}'.format( - start, end, currency - ) - ) + date_str = date_obj.strftime('%Y-%m-%d') + url = 'https://api.coinbase.com/v2/prices/BTC-{}/spot?date={}'.format(currency, date_str) response = requests.get(url) if response.status_code == 200: data = response.json() - price = data.get('bpi', {}).get(start, None) - if price: - if use_decimal: - price = Decimal(price) + price_str = data.get('data', {}).get('amount', None) + if price_str: + price = Decimal(price_str) if use_decimal else float(price_str) try: converted_btc = amount/price return converted_btc @@ -160,21 +147,14 @@ def convert_btc_to_cur_on(self, coins, currency, date_obj): else: use_decimal = self._force_decimal - start = date_obj.strftime('%Y-%m-%d') - end = date_obj.strftime('%Y-%m-%d') - url = ( - 'https://api.coindesk.com/v1/bpi/historical/close.json' - '?start={}&end={}¤cy={}'.format( - start, end, currency - ) - ) + date_str = date_obj.strftime('%Y-%m-%d') + url = 'https://api.coinbase.com/v2/prices/BTC-{}/spot?date={}'.format(currency, date_str) response = requests.get(url) if response.status_code == 200: data = response.json() - price = data.get('bpi', {}).get(start, None) - if price: - if use_decimal: - price = Decimal(price) + price_str = data.get('data', {}).get('amount', None) + if price_str: + price = Decimal(price_str) if use_decimal else float(price_str) try: converted_btc = coins*price return converted_btc