Completed
Push — master ( 72b331...d4b7d2 )
by Steffen
02:14
created

kuon.bitskins.bitskins.BitSkins.__init__()   A

Complexity

Conditions 5

Size

Total Lines 28
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 15
dl 0
loc 28
rs 9.1832
c 0
b 0
f 0
cc 5
nop 3
1
#!/usr/bin/python
2
# -*- coding: utf-8 -*-
3
import os
4
5
# covered by python-dotenv
6
# noinspection PyPackageRequirements
7
import dotenv
8
import pyotp
9
import requests
10
11
from kuon.api_response import APIResponse
12
from kuon.bitskins.api.exceptions import *
13
from kuon.selenium_helper import SeleniumHelper
14
15
16
class BitSkins(object):
17
    _selenium_helper = None
18
19
    def __init__(self, api_key=None, secret=None):
20
        """Initializing function
21
        According to the API documentation (https://bitskins.com/api/python#totp_code) they
22
        require OTPs and the API key so we verify the API key and the secret and generate the OTPs with a property
23
24
        :type api_key: string
25
        :type secret: string
26
        """
27
        dotenv_path = os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir, '.env')
28
        dotenv.load_dotenv(dotenv_path)
29
30
        self._api_key = api_key
31
        self._secret = secret
32
33
        if not api_key:
34
            self._api_key = os.environ.get('BITSKINS_API_KEY')
35
36
        if not secret:
37
            self._secret = os.environ.get('BITSKINS_2FA_SECRET')
38
39
        if not self._api_key:
40
            raise NoAPIKeyProvidedException('Please provide an API key via .env or as argument')
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable NoAPIKeyProvidedException does not seem to be defined.
Loading history...
41
42
        if not self._secret:
43
            raise NoSecretProvidedException('Please provide a secret to generate One Time Passwords for the API usage')
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable NoSecretProvidedException does not seem to be defined.
Loading history...
44
45
        self._pyotp = pyotp.TOTP(self._secret)
46
        self.validate_api_key()
47
48
    def api_request(self, api_url, params=None, headers=None):
49
        """Insert API key and OTP code to the payload and return the parsed response
50
51
        :param api_url:
52
        :param params:
53
        :param headers:
54
        :return:
55
        """
56
        if headers is None:
57
            headers = {}
58
        if params is None:
59
            params = {}
60
61
        params['api_key'] = self._api_key
62
        params['code'] = self.secret
63
64
        link = requests.get(url=api_url, params=params, headers=headers)
65
66
        return APIResponse(link.text)
67
68
    def validate_api_key(self):
69
        """Validate the api key and the 2 FA secret
70
71
        :return:
72
        """
73
        api_url = "https://bitskins.com/api/v1/get_account_balance/"
74
        response = self.api_request(api_url=api_url)
75
76
        if response.status != "success":
77
            raise InvalidOrWrongApiKeyException('Please provide a valid API key and 2 FA secret')
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable InvalidOrWrongApiKeyException does not seem to be defined.
Loading history...
78
79
    @property
80
    def selenium_helper(self):
81
        """Use property to make this lazy since it takes 3-4 seconds to load
82
83
        :return:
84
        """
85
        if not self._selenium_helper:
86
            self._selenium_helper = SeleniumHelper()
87
        return self._selenium_helper
88
89
    @property
90
    def secret(self):
91
        """Getter for One Time Passwords based on the given secret
92
93
        :return:
94
        """
95
        return self._pyotp.now()
96