|
| 1 | +from decimal import Decimal |
| 2 | +from pathlib import Path |
| 3 | +from typing import Union |
| 4 | + |
| 5 | +from capitalist.exceptions import ResponseException |
| 6 | +from capitalist.models import Account, CurrencyRate |
| 7 | +from .auth import Authenticator, Signer |
| 8 | +from .exceptions import RequestException, ImproperlyConfigured |
| 9 | +from .request_executor import RequestExecutor |
| 10 | +from .utils import retry |
| 11 | + |
| 12 | + |
| 13 | +class Capitalist: |
| 14 | + def __init__( |
| 15 | + self, |
| 16 | + login, |
| 17 | + password, |
| 18 | + request_executor_class=RequestExecutor, |
| 19 | + authenticator_class=Authenticator, |
| 20 | + signer_class=Signer, |
| 21 | + private_key: Union[bytes, Path] = None, |
| 22 | + ): |
| 23 | + self.login = login |
| 24 | + self.request_executor = request_executor_class() |
| 25 | + self.authenticator = authenticator_class(self.request_executor, login, password) |
| 26 | + self.signer = None |
| 27 | + if private_key is not None: |
| 28 | + if isinstance(private_key, Path): |
| 29 | + private_key = private_key.read_bytes() |
| 30 | + self.signer = signer_class(private_key) |
| 31 | + |
| 32 | + @retry((RequestException,)) |
| 33 | + def secure_request(self, operation, data=None, **kwargs): |
| 34 | + if data is None: |
| 35 | + data = {} |
| 36 | + data.update({ |
| 37 | + 'operation': operation, |
| 38 | + 'login': self.login, |
| 39 | + 'token': self.authenticator.token, |
| 40 | + 'encrypted_password': self.authenticator.encrypted_password.password, |
| 41 | + }) |
| 42 | + kwargs['data'] = data |
| 43 | + response_json = self.request_executor.request(**kwargs) |
| 44 | + code = response_json['code'] |
| 45 | + if code != 0: |
| 46 | + raise ResponseException(code, response_json['message']) |
| 47 | + return response_json |
| 48 | + |
| 49 | + def accounts(self): |
| 50 | + json_data = self.secure_request('get_accounts') |
| 51 | + return [Account.parse_json(acc_json) for acc_json in json_data['data']['accounts']] |
| 52 | + |
| 53 | + def currency_rates(self): |
| 54 | + json_data = self.secure_request('currency_rates')['data']['rates'] |
| 55 | + rates = [] |
| 56 | + for type_ in CurrencyRate.TYPES: |
| 57 | + for rate_data in json_data[type_]: |
| 58 | + rates.append(CurrencyRate.parse_json(rate_data, type_=type_)) |
| 59 | + return rates |
| 60 | + |
| 61 | + def import_batch_advanced(self, payments, account_rur, account_usd, account_eur, account_btc): |
| 62 | + if self.signer is None: |
| 63 | + raise ImproperlyConfigured('Provide private key and/or passphrase to be able to sign data.') |
| 64 | + |
| 65 | + payment_data = '\n'.join([payment.as_batch_record() for payment in payments]) |
| 66 | + data = { |
| 67 | + 'batch': payment_data, |
| 68 | + 'verification_type': 'SIGNATURE', |
| 69 | + 'verification_data': self.signer.sign(payment_data.encode('utf-8')), |
| 70 | + 'account_RUR': account_rur, |
| 71 | + 'account_USD': account_usd, |
| 72 | + 'account_EUR': account_eur, |
| 73 | + 'account_BTC': account_btc, |
| 74 | + } |
| 75 | + return self.secure_request('import_batch_advanced', data) |
| 76 | + |
| 77 | + def get_document_fee( |
| 78 | + self, document_type: str, source_account: str, amount: Decimal, dest_account: str = None, |
| 79 | + wiretag: str = None): |
| 80 | + data = { |
| 81 | + 'document_type': document_type, |
| 82 | + 'source_account': source_account, |
| 83 | + 'amount': amount, |
| 84 | + } |
| 85 | + if dest_account: |
| 86 | + data['dest_account'] = dest_account |
| 87 | + if wiretag: |
| 88 | + data['wiretag'] = wiretag |
| 89 | + return self.secure_request('get_document_fee', data) |
0 commit comments