From 9b6d2e0783943719a1cb38cbebf986af3806fa25 Mon Sep 17 00:00:00 2001 From: Jeff Sherlock Date: Sun, 15 Oct 2017 14:15:34 +0100 Subject: [PATCH 1/8] Added simple 24 hour caching to forex-python. --- forex_python/converter.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/forex_python/converter.py b/forex_python/converter.py index 6a9a818..f3be79f 100644 --- a/forex_python/converter.py +++ b/forex_python/converter.py @@ -2,6 +2,8 @@ from decimal import Decimal import simplejson as json import requests +import requests_cache +requests_cache.install_cache('forex_rates', backend='sqlite', expire_after=86400) class RatesNotAvailableError(Exception): From 03ee199c087cad2dbb3a64ea4be59af49e8ac0d9 Mon Sep 17 00:00:00 2001 From: Jeff Sherlock Date: Tue, 5 Jun 2018 01:40:46 +0000 Subject: [PATCH 2/8] Fixed source for conversion rates. --- forex_python/converter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forex_python/converter.py b/forex_python/converter.py index f9e3148..6e415e4 100644 --- a/forex_python/converter.py +++ b/forex_python/converter.py @@ -26,7 +26,7 @@ def __init__(self, force_decimal=False): self._force_decimal = force_decimal def _source_url(self): - return "http://ratesapi.io/api/" + return "http://ratesapi.io/api/latest/" def _get_date_string(self, date_obj): if date_obj is None: From fa7c64979ff9b0c5a2d3ca971ab827da2535427f Mon Sep 17 00:00:00 2001 From: Jeff Sherlock Date: Tue, 5 Jun 2018 01:49:44 +0000 Subject: [PATCH 3/8] Fixed source for conversion rates. With Https. --- forex_python/converter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forex_python/converter.py b/forex_python/converter.py index 6e415e4..213d8d0 100644 --- a/forex_python/converter.py +++ b/forex_python/converter.py @@ -26,7 +26,7 @@ def __init__(self, force_decimal=False): self._force_decimal = force_decimal def _source_url(self): - return "http://ratesapi.io/api/latest/" + return "https://ratesapi.io/api/latest/" def _get_date_string(self, date_obj): if date_obj is None: From b841cc6289ef694e19bc9e0d3a53b9ff90301eed Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 6 Jun 2018 10:10:54 -0600 Subject: [PATCH 4/8] Fixed issues with retrieving latest exchange rates from forex-python. --- .gitignore | 3 +++ forex_python/converter.py | 4 ++-- tests/test.py | 5 +++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 02d0b6e..b283fc2 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,6 @@ target/ #Ipython Notebook .ipynb_checkpoints env +*.xml +*.iml +*.sqlite diff --git a/forex_python/converter.py b/forex_python/converter.py index 213d8d0..cb5e4e6 100644 --- a/forex_python/converter.py +++ b/forex_python/converter.py @@ -26,11 +26,11 @@ def __init__(self, force_decimal=False): self._force_decimal = force_decimal def _source_url(self): - return "https://ratesapi.io/api/latest/" + return "https://ratesapi.io/api/" def _get_date_string(self, date_obj): if date_obj is None: - return 'latest' + return 'latest/' date_str = date_obj.strftime('%Y-%m-%d') return date_str diff --git a/tests/test.py b/tests/test.py index 610657a..b6d7caf 100644 --- a/tests/test.py +++ b/tests/test.py @@ -1,5 +1,6 @@ import datetime from decimal import Decimal +import unittest from unittest import TestCase from forex_python.converter import (get_rates, get_rate, convert, get_symbol, get_currency_name, RatesNotAvailableError, @@ -187,3 +188,7 @@ def test_with_valid_currency_code(self): def test_with_invalid_currency_code(self): self.assertFalse(get_currency_name('XYZ')) + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file From 1222496c04d88c555ab6f580595ca8454357992d Mon Sep 17 00:00:00 2001 From: Jeff Sherlock Date: Sun, 15 Oct 2017 14:15:34 +0100 Subject: [PATCH 5/8] Added simple 24 hour caching to forex-python. --- forex_python/converter.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/forex_python/converter.py b/forex_python/converter.py index 6717d6d..a8879e0 100644 --- a/forex_python/converter.py +++ b/forex_python/converter.py @@ -2,6 +2,8 @@ from decimal import Decimal import simplejson as json import requests +import requests_cache +requests_cache.install_cache('forex_rates', backend='sqlite', expire_after=86400) class RatesNotAvailableError(Exception): From 22562f2e5eaf471d28a1f4372111e34f7b18c136 Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 6 Jun 2018 10:10:54 -0600 Subject: [PATCH 6/8] Fixed issues with retrieving latest exchange rates from forex-python. --- .gitignore | 3 +++ forex_python/converter.py | 2 +- tests/test.py | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 02d0b6e..b283fc2 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,6 @@ target/ #Ipython Notebook .ipynb_checkpoints env +*.xml +*.iml +*.sqlite diff --git a/forex_python/converter.py b/forex_python/converter.py index a8879e0..6161c3d 100644 --- a/forex_python/converter.py +++ b/forex_python/converter.py @@ -30,7 +30,7 @@ def _source_url(self): def _get_date_string(self, date_obj): if date_obj is None: - return 'latest' + return 'latest/' date_str = date_obj.strftime('%Y-%m-%d') return date_str diff --git a/tests/test.py b/tests/test.py index 610657a..b6d7caf 100644 --- a/tests/test.py +++ b/tests/test.py @@ -1,5 +1,6 @@ import datetime from decimal import Decimal +import unittest from unittest import TestCase from forex_python.converter import (get_rates, get_rate, convert, get_symbol, get_currency_name, RatesNotAvailableError, @@ -187,3 +188,7 @@ def test_with_valid_currency_code(self): def test_with_invalid_currency_code(self): self.assertFalse(get_currency_name('XYZ')) + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file From 8193879660ca703572c789bf402225b5b4277a39 Mon Sep 17 00:00:00 2001 From: Jeff Sherlock Date: Mon, 5 Jul 2021 11:57:15 -0600 Subject: [PATCH 7/8] Fixed endpoint for exchange rates --- forex_python/converter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forex_python/converter.py b/forex_python/converter.py index 6e377f2..c3f0dcb 100644 --- a/forex_python/converter.py +++ b/forex_python/converter.py @@ -26,7 +26,7 @@ def __init__(self, force_decimal=False): self._force_decimal = force_decimal def _source_url(self): - return "https://theforexapi.com/api/" + return "https://theforexapi.com/api/latest" def _get_date_string(self, date_obj): if date_obj is None: From bf5739a168a019cac35c12a27fc8d469c21de896 Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 5 Jul 2021 12:43:39 -0600 Subject: [PATCH 8/8] A few fixes. --- forex_python/converter.py | 14 ++++++++------ setup.py | 1 + 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/forex_python/converter.py b/forex_python/converter.py index c3f0dcb..e95f632 100644 --- a/forex_python/converter.py +++ b/forex_python/converter.py @@ -3,7 +3,7 @@ import simplejson as json import requests import requests_cache -requests_cache.install_cache('forex_rates', backend='sqlite', expire_after=86400) +requests_cache.install_cache('forex_rates', backend='redis', namespace='forex', expire_after=86400) class RatesNotAvailableError(Exception): @@ -26,11 +26,11 @@ def __init__(self, force_decimal=False): self._force_decimal = force_decimal def _source_url(self): - return "https://theforexapi.com/api/latest" + return "https://theforexapi.com/api/" def _get_date_string(self, date_obj): if date_obj is None: - return 'latest/' + return 'latest' date_str = date_obj.strftime('%Y-%m-%d') return date_str @@ -39,6 +39,7 @@ def _decode_rates(self, response, use_decimal=False, date_str=None): decoded_data = json.loads(response.text, use_decimal=True) else: decoded_data = response.json() + if (date_str and date_str != 'latest' and date_str != decoded_data.get('date')): raise RatesNotAvailableError("Currency Rates Source Not Ready") @@ -55,7 +56,7 @@ class CurrencyRates(Common): def get_rates(self, base_cur, date_obj=None): date_str = self._get_date_string(date_obj) - payload = {'base': base_cur, 'rtype': 'fpy'} + payload = {'base': base_cur} source_url = self._source_url() + date_str response = requests.get(source_url, params=payload) if response.status_code == 200: @@ -69,7 +70,7 @@ def get_rate(self, base_cur, dest_cur, date_obj=None): return Decimal(1) return 1. date_str = self._get_date_string(date_obj) - payload = {'base': base_cur, 'symbols': dest_cur, 'rtype': 'fpy'} + payload = {'base': base_cur, 'symbols': dest_cur} source_url = self._source_url() + date_str response = requests.get(source_url, params=payload) if response.status_code == 200: @@ -92,7 +93,7 @@ def convert(self, base_cur, dest_cur, amount, date_obj=None): return float(amount) date_str = self._get_date_string(date_obj) - payload = {'base': base_cur, 'symbols': dest_cur, 'rtype': 'fpy'} + payload = {'base': base_cur, 'symbols': dest_cur} source_url = self._source_url() + date_str response = requests.get(source_url, params=payload) if response.status_code == 200: @@ -106,6 +107,7 @@ def convert(self, base_cur, dest_cur, amount, date_obj=None): return converted_amount except TypeError: raise DecimalFloatMismatchError("convert requires amount parameter is of type Decimal when force_decimal=True") + raise RatesNotAvailableError("Currency Rates Source Not Ready") diff --git a/setup.py b/setup.py index de66932..8762426 100644 --- a/setup.py +++ b/setup.py @@ -32,6 +32,7 @@ install_requires=[ 'requests', 'simplejson', + 'requests_cache' ], classifiers=[ 'Intended Audience :: Developers',