58 lines
1.6 KiB
Python
58 lines
1.6 KiB
Python
from decimal import Decimal
|
|
from contextlib import suppress
|
|
from urllib.parse import urljoin
|
|
|
|
import requests
|
|
from django.conf import settings
|
|
|
|
|
|
class CurrencyAPIClient:
|
|
CONVERT_ENDPOINT = 'currency/convert'
|
|
|
|
MAX_RETRIES = 2
|
|
|
|
def __init__(self, api_key: str):
|
|
self.api_url = 'https://api.getgeoapi.com/v2/'
|
|
self.api_key = api_key
|
|
self.session = requests.Session()
|
|
|
|
def request(self, method, url, *args, **kwargs):
|
|
params = kwargs.pop('params', {})
|
|
params.update({"api_key": self.api_key})
|
|
|
|
joined_url = urljoin(self.api_url, url)
|
|
request = requests.Request(method, joined_url, params=params, *args, **kwargs)
|
|
|
|
retries = 0
|
|
while retries < self.MAX_RETRIES:
|
|
retries += 1
|
|
prepared = self.session.prepare_request(request)
|
|
r = self.session.send(prepared)
|
|
|
|
# TODO: handle/log errors
|
|
return r
|
|
|
|
def get_rate(self, currency1: str, currency2: str, amount=1):
|
|
params = {
|
|
'from': currency1,
|
|
'to': currency2,
|
|
'amount': amount,
|
|
'format': 'json'
|
|
}
|
|
|
|
r = self.request('GET', self.CONVERT_ENDPOINT, params=params)
|
|
if not r or r.json().get('status') == 'failed':
|
|
return None
|
|
|
|
with suppress(KeyError):
|
|
rate = r.json()['rates'][currency2.upper()]['rate']
|
|
return Decimal(rate)
|
|
|
|
return None
|
|
|
|
def get_cny_rate(self):
|
|
return self.get_rate('cny', 'rub')
|
|
|
|
|
|
client = CurrencyAPIClient(settings.CURRENCY_GETGEOIP_API_KEY)
|