Skip to content

Commit 1f567cd

Browse files
author
Ravi kumar
committed
Merge pull request #2 from ravigadila/converter
Converter
2 parents edde0e2 + bce43c4 commit 1f567cd

7 files changed

Lines changed: 191 additions & 18 deletions

File tree

README.md

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,76 @@
1-
# forex-python
1+
forex-python
2+
============
3+
4+
Foreign exchange rates and currency conversion.
5+
6+
Features:
7+
---------
8+
- List all currency rates.
9+
- Get historical rates for any day since 1999.
10+
- Conversion rate for one Currency(ex; USD to INR).
11+
- Convert amount from one currency to other.('USD 10$' to INR)
12+
13+
Currency Source:
14+
---------------
15+
Fixer.io is a free API for current and historical foreign exchange rates published by European Central Bank.
16+
The rates are updated daily 3PM CET.
17+
18+
Installation:
19+
------------
20+
21+
Install using python package
22+
```
23+
$ pip install forex-python
24+
```
25+
26+
Or directly cloning the repo:
27+
```
28+
$ python setup.py install
29+
```
30+
31+
Examples:
32+
------------------
33+
34+
Initialize class
35+
```python
36+
>>> from forex_python.converter import CurrencyRates
37+
>>> c = CurrencyRates()
38+
```
39+
40+
list all latest currency rates for "USD"
41+
```python
42+
>>> c.get_rates('USD')
43+
{u'IDR': 13625.0, u'BGN': 1.7433, u'ILS': 3.8794, u'GBP': 0.68641, u'DKK': 6.6289, u'CAD': 1.3106, u'JPY': 110.36, u'HUF': 282.36, u'RON': 4.0162, u'MYR': 4.081, u'SEK': 8.3419, u'SGD': 1.3815, u'HKD': 7.7673, u'AUD': 1.3833, u'CHF': 0.99144, u'KRW': 1187.3, u'CNY': 6.5475, u'TRY': 2.9839, u'HRK': 6.6731, u'NZD': 1.4777, u'THB': 35.73, u'EUR': 0.89135, u'NOK': 8.3212, u'RUB': 66.774, u'INR': 67.473, u'MXN': 18.41, u'CZK': 24.089, u'BRL': 3.5473, u'PLN': 3.94, u'PHP': 46.775, u'ZAR': 15.747}
44+
```
45+
46+
Get Conversion rate from USD to INR
47+
```python
48+
>>> c.get_rate('USD', 'INR')
49+
67.473
50+
```
51+
52+
Convert amount from USD to INR:
53+
```python
54+
>>> c.convert('USD', 'INR', 10)
55+
674.73
56+
```
57+
58+
Convert amount from USD to INR based on 2010-03-01 rates
59+
```python
60+
>>> import datetime
61+
>>> date_obj = datetime.datetime.strptime('2010-05-10', "%Y-%m-%d").date()
62+
>>> c.convert('EUR', 'USD', 10, date_obj)
63+
12.969
64+
```
65+
66+
RatesNotAvailableError for invalid currency codes and missing currency code from source:
67+
```python
68+
>>> c.get_rate('XYZ', 'INR')
69+
Traceback (most recent call last):
70+
RatesNotAvailableError: Currency XYZ => INR rate not available for Date latest.
71+
```
72+
73+
Compleate [Documentation](http://forex-python.readthedocs.org/en/latest/?badge=latest)
74+
75+
We welcome your feedback and support. found bug raise github issue.
76+

forex_python/__init__.py

Whitespace-only changes.
Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,6 @@
22
import datetime
33

44

5-
class RateNotFoundError(Exception):
6-
"""
7-
Custom exception when conversion rate not found for given Country
8-
"""
9-
pass
10-
11-
125
class RatesNotAvailableError(Exception):
136
"""
147
Custome Exception when http://fixer.io/ is Down are not available for currency rates
@@ -24,20 +17,20 @@ def __init__(self):
2417
def _source_url(self):
2518
return "http://api.fixer.io/"
2619

27-
def _get_date_string(self, date_str):
28-
if date_str is None:
20+
def _get_date_string(self, date_obj):
21+
if date_obj is None:
2922
return 'latest'
3023
try:
31-
datetime.datetime.strptime(date_str, '%Y-%m-%d')
24+
date_str = date_obj.strftime('%Y-%m-%d')
3225
return date_str
3326
except ValueError:
34-
raise ValueError("Incorrect date String, date_str should be YYYY-MM-DD")
27+
raise ValueError("Incorrect date String, date should be YYYY-MM-DD")
3528

3629

3730
class CurrencyRates(Common):
3831

39-
def get_rates(self, base_cur, date_str=None):
40-
date_str = self._get_date_string(date_str)
32+
def get_rates(self, base_cur, date_obj=None):
33+
date_str = self._get_date_string(date_obj)
4134
payload = {'base': base_cur}
4235
source_url = self._source_url() + date_str
4336
response = requests.get(source_url, params=payload)
@@ -46,8 +39,8 @@ def get_rates(self, base_cur, date_str=None):
4639
return rates
4740
raise RatesNotAvailableError("Currency Rates Source Not Ready")
4841

49-
def get_rate(self, base_cur, dest_cur, date_str=None):
50-
date_str = self._get_date_string(date_str)
42+
def get_rate(self, base_cur, dest_cur, date_obj=None):
43+
date_str = self._get_date_string(date_obj)
5144
payload = {'base': base_cur, 'symbols': dest_cur}
5245
source_url = self._source_url() + date_str
5346
response = requests.get(source_url, params=payload)
@@ -59,8 +52,8 @@ def get_rate(self, base_cur, dest_cur, date_str=None):
5952
return rate
6053
raise RatesNotAvailableError("Currency Rates Source Not Ready")
6154

62-
def convert(self, base_cur, dest_cur, amount, date_str=None):
63-
date_str = self._get_date_string(date_str)
55+
def convert(self, base_cur, dest_cur, amount, date_obj=None):
56+
date_str = self._get_date_string(date_obj)
6457
payload = {'base': base_cur, 'symbols': dest_cur}
6558
source_url = self._source_url() + date_str
6659
response = requests.get(source_url, params=payload)

setup.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from setuptools import setup, find_packages
2+
3+
VERSION = 0.1
4+
5+
with open('README.md') as fl:
6+
LONG_DESCRIPTION = fl.read()
7+
8+
with open('LICENSE') as fl:
9+
LICENSE = fl.read()
10+
11+
setup(
12+
name='forex-python',
13+
version=VERSION,
14+
author='Micro Pyramid Informatic Pvt. Ltd.',
15+
author_email='hello@micropyramid.com',
16+
url='https://github.com/MicroPyramid/forex-python',
17+
description='Foreign exchange rates and currency conversion.',
18+
long_description=LONG_DESCRIPTION,
19+
license=LICENSE,
20+
packages=find_packages(exclude=['tests', 'tests.*']),
21+
include_package_data=True,
22+
install_requires=[
23+
'requests',
24+
],
25+
classifiers=[
26+
'Intended Audience :: Developers',
27+
'Operating System :: OS Independent',
28+
'License :: OSI Approved :: MIT License',
29+
'Programming Language :: Python',
30+
'Programming Language :: Python :: 2.7',
31+
'Programming Language :: Python :: 3',
32+
'Programming Language :: Python :: 3.2',
33+
'Programming Language :: Python :: 3.3',
34+
'Programming Language :: Python :: 3.4',
35+
'Topic :: Software Development :: Internationalization',
36+
],
37+
)

tests/__init__.py

Whitespace-only changes.

tests/test.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
from unittest import TestCase
2+
from forex_python.converter import CurrencyRates
3+
4+
5+
class TestBase(TestCase):
6+
def setUp(self):
7+
c = CurrencyRates()
8+
9+
10+
class TestGetRates(TestBase):
11+
"""
12+
Test get_rates with valid(ex: USD) and invalid(ex: XYZ) currency code
13+
"""
14+
def test_get_rates_valid_code(self):
15+
all_rates = c.get_rates('USD')
16+
17+
# Check if return value of get_rates dictionary
18+
self.assertTrue(isinstance(all_rates, dict))
19+
20+
# Test at least one rate value returned
21+
self.assertTrue(len(all_rates.keys()))
22+
23+
# Test one rate in returned dict is float value
24+
self.assertTrue(isinstance(all_rates.get('INR'), float))
25+
26+
def test_get_rates_invalid_code(self):
27+
all_rates = c.get_rates('XYZ')
28+
29+
# Check if return value of get_rates dictionary
30+
self.assertTrue(isinstance(all_rates, dict))
31+
32+
# Test no values in dict(empty dict)
33+
self.assertFalse(len(all_rates.keys()))
34+
35+
# Test one rate in returned dict is not float value
36+
self.assertFalse(isinstance(all_rates.get('INR'), float))
37+
38+
39+
class TestGetRate(TestBase):
40+
"""
41+
Test get_rate function using valid and invalid currency codes
42+
"""
43+
44+
def test_get_rate_with_valid_codes(self):
45+
rate = c.get_rate(self, 'USD', 'INR')
46+
47+
# check if return value is float
48+
self.assertTrue(isinstance(rate, float))
49+
50+
def test_get_rate_with_invalid_codes(self):
51+
# raise exception for invalid currency codes
52+
self.assertRaises(RatesNotAvailableError, c.get_rate(self, 'ABCD', 'XYZ'))
53+
54+
55+
class TestAmountConvert(TestBase):
56+
"""
57+
test amount conversion from one currency to other
58+
"""
59+
60+
def test_amount_convert_valid_currency(self):
61+
amount = c.convert('USD', 'INR', 10)
62+
63+
# test if amount returned in float
64+
self.assertTrue(isinstance(amount, float))
65+
66+
def test_amount_convert_valid_currency(self):
67+
# test if amount returned in float
68+
self.assertRaises(RateNotFoundError, c.convert('ABC, 'XYZ', 10))

0 commit comments

Comments
 (0)