Skip to content

Added force_decimal option for Bitcoin rates #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,37 @@ Usage Examples:
>>> c.convert('USD', 'INR', 10)
674.73

- Force use of Decimal

.. code-block:: python

python
>>> from forex_python.converter import CurrencyRates
>>> c = CurrencyRates(force_decimal=True)
>>> c.convert('USD', 'INR', Decimal('10.45'))
705.09
>>> c.convert('USD', 'INR', 10)
DecimalFloatMismatchError: convert requires amount parameter is of type Decimal when use_decimal=True

- Detect use of Decimal

.. code-block:: python

python
>>> from forex_python.converter import CurrencyRates
>>> c = CurrencyRates()
>>> c.convert('USD', 'INR', Decimal('10.45'))
705.09
>>> c.convert('USD', 'INR', 10)
674.73

- Get latest Bitcoin price.

.. code-block:: python

python
>>> from forex_python.bitcoin import BtcConverter
>>> b = BtcConverter()
>>> b = BtcConverter() # force_decimal=True to get Decimal rates
>>> b.get_latest_price('USD')
533.913

Expand Down
14 changes: 10 additions & 4 deletions docs/source/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ Currency Rates
>>> from forex_python.converter import CurrencyRates
>>> c = CurrencyRates(force_decimal=True)
>>> c.convert('USD', 'INR', Decimal('10.45'))
705.09
Decimal('705.09')
>>> c.convert('USD', 'INR', 10)
DecimalFloatMismatchError: convert requires amount parameter is of type Decimal when use_decimal=True

8. Detect use of Decimal::
>>> from forex_python.converter import CurrencyRates
>>> c = CurrencyRates()
>>> c.convert('USD', 'INR', Decimal('10.45'))
705.09
Decimal('705.09')
>>> c.convert('USD', 'INR', 10)
674.73

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

Expand Down Expand Up @@ -94,7 +94,13 @@ Bitcoin Prices:
>>> b.get_previous_price_list('INR', start_date, end_date) # get_previous_price_list('INR', start_date, end_date)
{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}

8. Get Bitcoin symbol::
8. Force use of Decimal::
>>> from forex_python.bitcoin import BtcConverter
>>> b = BtcConverter(force_decimal=True)
>>> b.get_latest_price('EUR') # you can directly call get_latest_price('EUR')
Decimal('942.245000000000004547') # return type Decimal

9. Get Bitcoin symbol::
>>> print(b.get_symbol()) # get_btc_symbol()
฿

Expand Down
90 changes: 71 additions & 19 deletions forex_python/bitcoin.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
from decimal import Decimal
import simplejson as json
import requests
from .converter import RatesNotAvailableError, DecimalFloatMismatchError


class BtcConverter(object):
"""
Get bit coin rates and convertion
"""
def __init__(self, force_decimal=False):
self._force_decimal = force_decimal

def _decode_rates(self, response, use_decimal=False):
if self._force_decimal or use_decimal:
decoded_data = json.loads(response.text, use_decimal=True)
else:
decoded_data = response.json()
return decoded_data

def get_latest_price(self, currency):
"""
Expand All @@ -15,6 +27,8 @@ def get_latest_price(self, currency):
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
return None

Expand All @@ -34,8 +48,10 @@ def get_previous_price(self, currency, date_obj):
if response.status_code == 200:
data = response.json()
price = data.get('bpi', {}).get(start, None)
if self._force_decimal:
return Decimal(price)
return price
return None
raise RatesNotAvailableError("BitCoin Rates Source Not Ready For Given date")

def get_previous_price_list(self, currency, start_date, end_date):
"""
Expand All @@ -51,7 +67,7 @@ def get_previous_price_list(self, currency, start_date, end_date):
)
response = requests.get(url)
if response.status_code == 200:
data = response.json()
data = self._decode_rates(response)
price_dict = data.get('bpi', {})
return price_dict
return {}
Expand All @@ -60,36 +76,59 @@ def convert_to_btc(self, amount, currency):
"""
Convert X amount to Bit Coins
"""
if isinstance(amount, Decimal):
use_decimal = True
else:
use_decimal = self._force_decimal

url = 'https://api.coindesk.com/v1/bpi/currentprice/{}.json'.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:
converted_btc = amount/price
return converted_btc
return None
return None
if use_decimal:
price = Decimal(price)
try:
converted_btc = amount/price
return converted_btc
except TypeError:
raise DecimalFloatMismatchError("convert_to_btc requires amount parameter is of type Decimal when force_decimal=True")
raise RatesNotAvailableError("BitCoin Rates Source Not Ready For Given date")

def convert_btc_to_cur(self, coins, currency):
"""
Convert X bit coins to valid currency amount
"""
if isinstance(coins, Decimal):
use_decimal = True
else:
use_decimal = self._force_decimal

url = 'https://api.coindesk.com/v1/bpi/currentprice/{}.json'.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:
converted_amount = coins * price
return converted_amount
return None
return None
if use_decimal:
price = Decimal(price)
try:
converted_amount = coins * price
return converted_amount
except TypeError:
raise DecimalFloatMismatchError("convert_btc_to_cur requires coins parameter is of type Decimal when force_decimal=True")
raise RatesNotAvailableError("BitCoin Rates Source Not Ready For Given date")

def convert_to_btc_on(self, amount, currency, date_obj):
"""
Convert X amount to BTC based on given date rate
"""
if isinstance(amount, Decimal):
use_decimal = True
else:
use_decimal = self._force_decimal

start = date_obj.strftime('%Y-%m-%d')
end = date_obj.strftime('%Y-%m-%d')
url = (
Expand All @@ -103,15 +142,24 @@ def convert_to_btc_on(self, amount, currency, date_obj):
data = response.json()
price = data.get('bpi', {}).get(start, None)
if price:
converted_btc = amount/price
return converted_btc
return None
return None
if use_decimal:
price = Decimal(price)
try:
converted_btc = amount/price
return converted_btc
except TypeError:
raise DecimalFloatMismatchError("convert_to_btc_on requires amount parameter is of type Decimal when force_decimal=True")
raise RatesNotAvailableError("BitCoin Rates Source Not Ready For Given Date")

def convert_btc_to_cur_on(self, coins, currency, date_obj):
"""
Convert X BTC to valid currency amount based on given date
"""
if isinstance(coins, Decimal):
use_decimal = True
else:
use_decimal = self._force_decimal

start = date_obj.strftime('%Y-%m-%d')
end = date_obj.strftime('%Y-%m-%d')
url = (
Expand All @@ -125,14 +173,18 @@ def convert_btc_to_cur_on(self, coins, currency, date_obj):
data = response.json()
price = data.get('bpi', {}).get(start, None)
if price:
converted_btc = coins*price
return converted_btc
return None
return None
if use_decimal:
price = Decimal(price)
try:
converted_btc = coins*price
return converted_btc
except TypeError:
raise DecimalFloatMismatchError("convert_btc_to_cur_on requires amount parameter is of type Decimal when force_decimal=True")
raise RatesNotAvailableError("BitCoin Rates Source Not Ready For Given Date")

def get_symbol(self):
"""
Here is Unicode symbol for bit coin
Here is Unicode symbol for bitcoin
"""
return "\u0E3F"

Expand Down
2 changes: 1 addition & 1 deletion forex_python/converter.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os
from decimal import Decimal
import simplejson as json
import requests
from decimal import Decimal


class RatesNotAvailableError(Exception):
Expand Down
2 changes: 1 addition & 1 deletion tests/test.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import datetime
from decimal import Decimal
from unittest import TestCase
from forex_python.converter import (get_rates, get_rate, convert, get_symbol,
get_currency_name, RatesNotAvailableError,
CurrencyRates, DecimalFloatMismatchError)
from decimal import Decimal


class TestGetRates(TestCase):
Expand Down
Loading