1+ from decimal import Decimal
2+ from datetime import timedelta , datetime
3+ import simplejson as json
14import requests
5+ from converter import RatesNotAvailableError , DecimalFloatMismatchError
26
37
48class 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 """
0 commit comments