Skip to content

Commit 18a1ade

Browse files
author
ravigadila
committed
Added force_decimal option to get Bitcoin decimal rates
1 parent 99c783f commit 18a1ade

File tree

6 files changed

+252
-44
lines changed

6 files changed

+252
-44
lines changed

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ Usage Examples:
116116
117117
python
118118
>>> from forex_python.bitcoin import BtcConverter
119-
>>> b = BtcConverter()
119+
>>> b = BtcConverter() # force_decimal=True to get Decimal rates
120120
>>> b.get_latest_price('USD')
121121
533.913
122122

docs/source/usage.rst

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,15 @@ Currency Rates
3939
>>> from forex_python.converter import CurrencyRates
4040
>>> c = CurrencyRates(force_decimal=True)
4141
>>> c.convert('USD', 'INR', Decimal('10.45'))
42-
705.09
42+
Decimal('705.09')
4343
>>> c.convert('USD', 'INR', 10)
4444
DecimalFloatMismatchError: convert requires amount parameter is of type Decimal when use_decimal=True
4545

4646
8. Detect use of Decimal::
4747
>>> from forex_python.converter import CurrencyRates
4848
>>> c = CurrencyRates()
4949
>>> c.convert('USD', 'INR', Decimal('10.45'))
50-
705.09
50+
Decimal('705.09')
5151
>>> c.convert('USD', 'INR', 10)
5252
674.73
5353

@@ -56,7 +56,7 @@ Bitcoin Prices:
5656
---------------
5757
1. Get latest price of one Bitcoin::
5858
>>> from forex_python.bitcoin import BtcConverter
59-
>>> b = BtcConverter()
59+
>>> b = BtcConverter() # add "force_decimal=True" parmeter to get Decimal rates
6060
>>> b.get_latest_price('EUR') # you can directly call get_latest_price('EUR')
6161
476.5225 # return type float
6262

@@ -94,7 +94,13 @@ Bitcoin Prices:
9494
>>> b.get_previous_price_list('INR', start_date, end_date) # get_previous_price_list('INR', start_date, end_date)
9595
{u'2016-05-19': 29371.7579, u'2016-05-18': 30402.3169, u'2016-05-22': 29586.3631, u'2016-05-23': 29925.3272, u'2016-05-20': 29864.0256, u'2016-05-21': 29884.7449}
9696

97-
8. Get Bitcoin symbol::
97+
8. Force use of Decimal::
98+
>>> from forex_python.bitcoin import BtcConverter
99+
>>> b = BtcConverter(force_decimal=True)
100+
>>> b.get_latest_price('EUR') # you can directly call get_latest_price('EUR')
101+
Decimal('942.245000000000004547') # return type Decimal
102+
103+
9. Get Bitcoin symbol::
98104
>>> print(b.get_symbol()) # get_btc_symbol()
99105
฿
100106

forex_python/bitcoin.py

Lines changed: 71 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,23 @@
1+
from decimal import Decimal
2+
from datetime import timedelta, datetime
3+
import simplejson as json
14
import requests
5+
from converter import RatesNotAvailableError, DecimalFloatMismatchError
26

37

48
class BtcConverter(object):
59
"""
610
Get bit coin rates and convertion
711
"""
12+
def __init__(self, force_decimal=False):
13+
self._force_decimal = force_decimal
14+
15+
def _decode_rates(self, response, use_decimal=False):
16+
if self._force_decimal or use_decimal:
17+
decoded_data = json.loads(response.text, use_decimal=True)
18+
else:
19+
decoded_data = response.json()
20+
return decoded_data
821

922
def get_latest_price(self, currency):
1023
"""
@@ -15,6 +28,8 @@ def get_latest_price(self, currency):
1528
if response.status_code == 200:
1629
data = response.json()
1730
price = data.get('bpi').get(currency, {}).get('rate_float', None)
31+
if self._force_decimal:
32+
return Decimal(price)
1833
return price
1934
return None
2035

@@ -34,8 +49,10 @@ def get_previous_price(self, currency, date_obj):
3449
if response.status_code == 200:
3550
data = response.json()
3651
price = data.get('bpi', {}).get(start, None)
52+
if self._force_decimal:
53+
return Decimal(price)
3754
return price
38-
return None
55+
raise RatesNotAvailableError("BitCoin Rates Source Not Ready For Given date")
3956

4057
def get_previous_price_list(self, currency, start_date, end_date):
4158
"""
@@ -51,7 +68,7 @@ def get_previous_price_list(self, currency, start_date, end_date):
5168
)
5269
response = requests.get(url)
5370
if response.status_code == 200:
54-
data = response.json()
71+
data = self._decode_rates(response)
5572
price_dict = data.get('bpi', {})
5673
return price_dict
5774
return {}
@@ -60,36 +77,59 @@ def convert_to_btc(self, amount, currency):
6077
"""
6178
Convert X amount to Bit Coins
6279
"""
80+
if isinstance(amount, Decimal):
81+
use_decimal = True
82+
else:
83+
use_decimal = self._force_decimal
84+
6385
url = 'https://api.coindesk.com/v1/bpi/currentprice/{}.json'.format(currency)
6486
response = requests.get(url)
6587
if response.status_code == 200:
6688
data = response.json()
6789
price = data.get('bpi').get(currency, {}).get('rate_float', None)
6890
if price:
69-
converted_btc = amount/price
70-
return converted_btc
71-
return None
72-
return None
91+
if use_decimal:
92+
price = Decimal(price)
93+
try:
94+
converted_btc = amount/price
95+
return converted_btc
96+
except TypeError:
97+
raise DecimalFloatMismatchError("convert_to_btc requires amount parameter is of type Decimal when force_decimal=True")
98+
raise RatesNotAvailableError("BitCoin Rates Source Not Ready For Given date")
7399

74100
def convert_btc_to_cur(self, coins, currency):
75101
"""
76102
Convert X bit coins to valid currency amount
77103
"""
104+
if isinstance(coins, Decimal):
105+
use_decimal = True
106+
else:
107+
use_decimal = self._force_decimal
108+
78109
url = 'https://api.coindesk.com/v1/bpi/currentprice/{}.json'.format(currency)
79110
response = requests.get(url)
80111
if response.status_code == 200:
81112
data = response.json()
82113
price = data.get('bpi').get(currency, {}).get('rate_float', None)
83114
if price:
84-
converted_amount = coins * price
85-
return converted_amount
86-
return None
87-
return None
115+
if use_decimal:
116+
price = Decimal(price)
117+
try:
118+
converted_amount = coins * price
119+
return converted_amount
120+
except TypeError:
121+
raise DecimalFloatMismatchError("convert_btc_to_cur requires coins parameter is of type Decimal when force_decimal=True")
122+
raise RatesNotAvailableError("BitCoin Rates Source Not Ready For Given date")
88123

89124
def convert_to_btc_on(self, amount, currency, date_obj):
90125
"""
91126
Convert X amount to BTC based on given date rate
92127
"""
128+
if isinstance(amount, Decimal):
129+
use_decimal = True
130+
else:
131+
use_decimal = self._force_decimal
132+
93133
start = date_obj.strftime('%Y-%m-%d')
94134
end = date_obj.strftime('%Y-%m-%d')
95135
url = (
@@ -103,15 +143,24 @@ def convert_to_btc_on(self, amount, currency, date_obj):
103143
data = response.json()
104144
price = data.get('bpi', {}).get(start, None)
105145
if price:
106-
converted_btc = amount/price
107-
return converted_btc
108-
return None
109-
return None
146+
if use_decimal:
147+
price = Decimal(price)
148+
try:
149+
converted_btc = amount/price
150+
return converted_btc
151+
except TypeError:
152+
raise DecimalFloatMismatchError("convert_to_btc_on requires amount parameter is of type Decimal when force_decimal=True")
153+
raise RatesNotAvailableError("BitCoin Rates Source Not Ready For Given Date")
110154

111155
def convert_btc_to_cur_on(self, coins, currency, date_obj):
112156
"""
113157
Convert X BTC to valid currency amount based on given date
114158
"""
159+
if isinstance(coins, Decimal):
160+
use_decimal = True
161+
else:
162+
use_decimal = self._force_decimal
163+
115164
start = date_obj.strftime('%Y-%m-%d')
116165
end = date_obj.strftime('%Y-%m-%d')
117166
url = (
@@ -125,10 +174,14 @@ def convert_btc_to_cur_on(self, coins, currency, date_obj):
125174
data = response.json()
126175
price = data.get('bpi', {}).get(start, None)
127176
if price:
128-
converted_btc = coins*price
129-
return converted_btc
130-
return None
131-
return None
177+
if use_decimal:
178+
price = Decimal(price)
179+
try:
180+
converted_btc = coins*price
181+
return converted_btc
182+
except TypeError:
183+
raise DecimalFloatMismatchError("convert_btc_to_cur_on requires amount parameter is of type Decimal when force_decimal=True")
184+
raise RatesNotAvailableError("BitCoin Rates Source Not Ready For Given Date")
132185

133186
def get_symbol(self):
134187
"""

forex_python/converter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import os
2+
from decimal import Decimal
23
import simplejson as json
34
import requests
4-
from decimal import Decimal
55

66

77
class RatesNotAvailableError(Exception):

tests/test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import datetime
2+
from decimal import Decimal
23
from unittest import TestCase
34
from forex_python.converter import (get_rates, get_rate, convert, get_symbol,
45
get_currency_name, RatesNotAvailableError,
56
CurrencyRates, DecimalFloatMismatchError)
6-
from decimal import Decimal
77

88

99
class TestGetRates(TestCase):

0 commit comments

Comments
 (0)