1
+ from decimal import Decimal
2
+ import simplejson as json
1
3
import requests
4
+ from .converter import RatesNotAvailableError , DecimalFloatMismatchError
2
5
3
6
4
7
class BtcConverter (object ):
5
8
"""
6
9
Get bit coin rates and convertion
7
10
"""
11
+ def __init__ (self , force_decimal = False ):
12
+ self ._force_decimal = force_decimal
13
+
14
+ def _decode_rates (self , response , use_decimal = False ):
15
+ if self ._force_decimal or use_decimal :
16
+ decoded_data = json .loads (response .text , use_decimal = True )
17
+ else :
18
+ decoded_data = response .json ()
19
+ return decoded_data
8
20
9
21
def get_latest_price (self , currency ):
10
22
"""
@@ -15,6 +27,8 @@ def get_latest_price(self, currency):
15
27
if response .status_code == 200 :
16
28
data = response .json ()
17
29
price = data .get ('bpi' ).get (currency , {}).get ('rate_float' , None )
30
+ if self ._force_decimal :
31
+ return Decimal (price )
18
32
return price
19
33
return None
20
34
@@ -34,8 +48,10 @@ def get_previous_price(self, currency, date_obj):
34
48
if response .status_code == 200 :
35
49
data = response .json ()
36
50
price = data .get ('bpi' , {}).get (start , None )
51
+ if self ._force_decimal :
52
+ return Decimal (price )
37
53
return price
38
- return None
54
+ raise RatesNotAvailableError ( "BitCoin Rates Source Not Ready For Given date" )
39
55
40
56
def get_previous_price_list (self , currency , start_date , end_date ):
41
57
"""
@@ -51,7 +67,7 @@ def get_previous_price_list(self, currency, start_date, end_date):
51
67
)
52
68
response = requests .get (url )
53
69
if response .status_code == 200 :
54
- data = response . json ( )
70
+ data = self . _decode_rates ( response )
55
71
price_dict = data .get ('bpi' , {})
56
72
return price_dict
57
73
return {}
@@ -60,36 +76,59 @@ def convert_to_btc(self, amount, currency):
60
76
"""
61
77
Convert X amount to Bit Coins
62
78
"""
79
+ if isinstance (amount , Decimal ):
80
+ use_decimal = True
81
+ else :
82
+ use_decimal = self ._force_decimal
83
+
63
84
url = 'https://api.coindesk.com/v1/bpi/currentprice/{}.json' .format (currency )
64
85
response = requests .get (url )
65
86
if response .status_code == 200 :
66
87
data = response .json ()
67
88
price = data .get ('bpi' ).get (currency , {}).get ('rate_float' , None )
68
89
if price :
69
- converted_btc = amount / price
70
- return converted_btc
71
- return None
72
- return None
90
+ if use_decimal :
91
+ price = Decimal (price )
92
+ try :
93
+ converted_btc = amount / price
94
+ return converted_btc
95
+ except TypeError :
96
+ raise DecimalFloatMismatchError ("convert_to_btc requires amount parameter is of type Decimal when force_decimal=True" )
97
+ raise RatesNotAvailableError ("BitCoin Rates Source Not Ready For Given date" )
73
98
74
99
def convert_btc_to_cur (self , coins , currency ):
75
100
"""
76
101
Convert X bit coins to valid currency amount
77
102
"""
103
+ if isinstance (coins , Decimal ):
104
+ use_decimal = True
105
+ else :
106
+ use_decimal = self ._force_decimal
107
+
78
108
url = 'https://api.coindesk.com/v1/bpi/currentprice/{}.json' .format (currency )
79
109
response = requests .get (url )
80
110
if response .status_code == 200 :
81
111
data = response .json ()
82
112
price = data .get ('bpi' ).get (currency , {}).get ('rate_float' , None )
83
113
if price :
84
- converted_amount = coins * price
85
- return converted_amount
86
- return None
87
- return None
114
+ if use_decimal :
115
+ price = Decimal (price )
116
+ try :
117
+ converted_amount = coins * price
118
+ return converted_amount
119
+ except TypeError :
120
+ raise DecimalFloatMismatchError ("convert_btc_to_cur requires coins parameter is of type Decimal when force_decimal=True" )
121
+ raise RatesNotAvailableError ("BitCoin Rates Source Not Ready For Given date" )
88
122
89
123
def convert_to_btc_on (self , amount , currency , date_obj ):
90
124
"""
91
125
Convert X amount to BTC based on given date rate
92
126
"""
127
+ if isinstance (amount , Decimal ):
128
+ use_decimal = True
129
+ else :
130
+ use_decimal = self ._force_decimal
131
+
93
132
start = date_obj .strftime ('%Y-%m-%d' )
94
133
end = date_obj .strftime ('%Y-%m-%d' )
95
134
url = (
@@ -103,15 +142,24 @@ def convert_to_btc_on(self, amount, currency, date_obj):
103
142
data = response .json ()
104
143
price = data .get ('bpi' , {}).get (start , None )
105
144
if price :
106
- converted_btc = amount / price
107
- return converted_btc
108
- return None
109
- return None
145
+ if use_decimal :
146
+ price = Decimal (price )
147
+ try :
148
+ converted_btc = amount / price
149
+ return converted_btc
150
+ except TypeError :
151
+ raise DecimalFloatMismatchError ("convert_to_btc_on requires amount parameter is of type Decimal when force_decimal=True" )
152
+ raise RatesNotAvailableError ("BitCoin Rates Source Not Ready For Given Date" )
110
153
111
154
def convert_btc_to_cur_on (self , coins , currency , date_obj ):
112
155
"""
113
156
Convert X BTC to valid currency amount based on given date
114
157
"""
158
+ if isinstance (coins , Decimal ):
159
+ use_decimal = True
160
+ else :
161
+ use_decimal = self ._force_decimal
162
+
115
163
start = date_obj .strftime ('%Y-%m-%d' )
116
164
end = date_obj .strftime ('%Y-%m-%d' )
117
165
url = (
@@ -125,14 +173,18 @@ def convert_btc_to_cur_on(self, coins, currency, date_obj):
125
173
data = response .json ()
126
174
price = data .get ('bpi' , {}).get (start , None )
127
175
if price :
128
- converted_btc = coins * price
129
- return converted_btc
130
- return None
131
- return None
176
+ if use_decimal :
177
+ price = Decimal (price )
178
+ try :
179
+ converted_btc = coins * price
180
+ return converted_btc
181
+ except TypeError :
182
+ raise DecimalFloatMismatchError ("convert_btc_to_cur_on requires amount parameter is of type Decimal when force_decimal=True" )
183
+ raise RatesNotAvailableError ("BitCoin Rates Source Not Ready For Given Date" )
132
184
133
185
def get_symbol (self ):
134
186
"""
135
- Here is Unicode symbol for bit coin
187
+ Here is Unicode symbol for bitcoin
136
188
"""
137
189
return "\u0E3F "
138
190
0 commit comments