Source code for bitex.api.base

"""API Base Classes for BitEx."""
# Import Built-Ins
import logging
import warnings
import configparser
import time
import os

# Import Homebrew
from bitex.exceptions import IncompleteCredentialsWarning
from bitex.exceptions import IncompleteCredentialsError
from bitex.exceptions import IncompleteAPIConfigurationWarning
from bitex.exceptions import IncompleteCredentialConfigurationWarning

# Init Logging Facilities
log = logging.getLogger(__name__)


[docs]class BaseAPI: """ BaseAPI provides lowest-common-denominator methods used in all API types. It provides a nonce() method, basic configuration loading and credential validity checking method check_auth_requirements(), which should be extended in subclasses to cover any additional parameters that are necessary. """ def __init__(self, *, addr, key, secret, version, config): """ Initialize a BaseAPI instance. :param addr: str, API url :param key: str, API key :param secret: str, API secret :param version: str, version of API to request :param config: str, path to config file """ # validate inputs if key == '' or secret == '': raise ValueError("Invalid key or secret - cannot be empty string! " "Pass None instead!") self.addr = addr self.key = key if key else None self.secret = secret if secret else None self.version = version if version else None try: self.check_auth_requirements() except IncompleteCredentialsError: if config is None: warnings.warn("Incomplete Credentials were given - " "authentication may not work!", IncompleteCredentialsWarning) self.config_file = config if self.config_file: self.load_config(self.config_file)
[docs] def check_auth_requirements(self): """ Check that neither self.key nor self.secret are None. If so, this method raises an IncompleteCredentialsError. Otherwise returns None. Extend this in child classes if you need to check for further required values. :raise: IncompleteCredentialsError :return: None """ if any(attr is None for attr in (self.key, self.secret)): raise IncompleteCredentialsError else: return
[docs] def load_config(self, fname): """ Load configuration from an ini file. Return it, in case this func needs to be extended. :param fname: path to file :return: configparser.ConfigParser() Obj """ if not os.path.exists(fname): raise FileNotFoundError conf = configparser.ConfigParser(allow_no_value=True) conf.read(fname) try: self.key = conf['AUTH']['key'] except KeyError: if self.key is None: warnings.warn("Key parameter not present in config - " "authentication may not work!", IncompleteCredentialConfigurationWarning) try: self.secret = conf['AUTH']['secret'] except KeyError: if self.secret is None: warnings.warn("Secret parameter not present in config - " "authentication may not work!", IncompleteCredentialConfigurationWarning) try: self.addr = conf['API']['address'] except KeyError: if self.addr is None: warnings.warn("API address not present in config - " "requests may not work!", IncompleteAPIConfigurationWarning) try: self.version = conf['API']['version'] except KeyError: if self.version is None: warnings.warn("API version was not present in config - " "requests may not work!", IncompleteAPIConfigurationWarning) return conf
[docs] @staticmethod def nonce(): """ Create a Nonce value for signature generation. :return: Nonce as string """ return str(int(round(1000 * time.time())))