コード例 #1
0
    def __init__(self, value=36, min_val=None, max_val=None):
        """
        Constructor. To filter by a specific value, set value to a number.
        To filter by a range, set value to None, and set min_val and max_val
        to integers.

        :param value: int - exact term value (default: 36)
        :param min_val: int - minimum term value (inclusive) (default: None)
        :param max_val: int - maximum term value (inclusive) (default: None)
        """
        if value is not None and (min_val is not None or max_val is not None):
            fstr = "value and min_val, max_val are mutually exclusive"
            details = "value: {}".format(value)
            if min_val is not None:
                details += ", min_val: {}".format(min_val)
            if max_val is not None:
                details += ", max_val: {}".format(max_val)
            raise LCError(fstr, details=details)

        if min_val is not None and max_val is not None:
            if max_val > min_val:
                fstr = "max_val cannot be greater than min_val"
                raise LCError(fstr)
        elif value is None and (min_val is None or max_val is None):
            fstr = "invalid specification on the values"
            hint = "either value or min_val + max_val combo should be specified"
            raise LCError(fstr, hint=hint)

        self._value = value
        self._min_value = min_val
        self._max_value = max_val
コード例 #2
0
ファイル: transfer.py プロジェクト: thangduong/lendingclub2
def add(investor_id,
        amount,
        frequency=TransferFrequency.NOW,
        start_date=None,
        end_date=None):
    """
    Add fund to the account

    :param investor_id: int - the investor account id
    :param amount: float - amount to withdraw
    :param frequency: member of lendingclub2.config.TransferFrequency
                      (default: TransferFrequency.NOW)
    :param start_date: instance of datetime.datetime - required if frequency
                       is not TransferFrequency.NOW (default: None)
    :param end_date: instance of datetime.datetime - optional (default: None)
    :returns: instance of lendingclub2.response.Response
    """
    url = DNS + ENDPOINTS['transfer'].format(version=API_VERSION,
                                             investor_id=investor_id)
    if not isinstance(frequency, TransferFrequency):
        fstr = "frequency parameter is not instance of TransferFrequency"
        raise LCError(fstr)

    if frequency != TransferFrequency.NOW:
        if start_date is None:
            fstr = "please specify start_date to transfer fund"
            hint = "start_date needs to be specified for future or recurring " \
                   "transfer"
            raise LCError(fstr, hint=hint)
        elif not isinstance(start_date, datetime.datetime):
            fstr = "start_date parameter needs to be an instance of datetime"
            raise LCError(fstr)

    if end_date is not None and not isinstance(end_date, datetime.datetime):
        fstr = "end_date parameter needs to be an instance of datetime"
        raise LCError(fstr)

    if amount <= 0.0:
        fstr = "amount has to be a positive number for transfer"
        raise LCError(fstr)

    payload = {
        'transferFrequency': frequency.value,
        'amount': amount,
    }
    if start_date is not None:
        payload['startDate'] = start_date.isoformat()
    if end_date is not None:
        payload['endDate'] = end_date.isoformat()

    return Response(request.post(url, json=payload))
コード例 #3
0
ファイル: loan.py プロジェクト: thangduong/lendingclub2
    def search(self, filter_id=None, show_all=None):
        """
        Apply filters and search for loans matching the specifications
        """
        url = DNS + ENDPOINTS['loans'].format(version=API_VERSION)

        criteria = list()
        if filter_id is not None:
            criteria.append('filterId={}'.format(filter_id))
        if show_all is not None:
            if show_all:
                criteria.append('showAll=true')
            else:
                criteria.append('showAll=false')

        if criteria:
            url += '?' + '&'.join(criteria)

        headers = {'X-LC-LISTING-VERSION': LISTING_VERSION}
        response = Response(request.get(url, headers=headers))
        if not response.successful:
            fstr = "cannot search for any loans"
            raise LCError(fstr, details=json.dumps(response.json, indent=2))

        # Reset the stored loans whenever we search again as long as the
        # latest request was successful
        self.loans = list()
        for loan_json in response.json['loans']:
            loan = Loan(loan_json)
            self.loans.append(loan)
コード例 #4
0
ファイル: transfer.py プロジェクト: thangduong/lendingclub2
def pending(investor_id):
    """
    Retrieve the pending transfers

    :param investor_id: int - the investor account id
    :returns: iterable of instance of lendingclub2.response.transfer.Transaction
    """
    url = DNS + ENDPOINTS['pending_transfer'].format(version=API_VERSION,
                                                     investor_id=investor_id)

    response = Response(request.get(url))
    if not response.successful:
        fstr = "cannot find list of pending transactions"
        raise LCError(fstr, details=json.dumps(response.json, indent=2))

    transactions = list()
    total_transactions = 0
    try:
        total_transactions = response.json['transfers']
    except KeyError:
        pass

    for key in range(total_transactions):
        transactions.append(Transaction(response.json[key]))
    return transactions
コード例 #5
0
ファイル: order.py プロジェクト: ddr-capital/lendingclub2
    def __init__(self, loan_id, amount, portfolio_id=None):
        """
        Constructor

        :param loan_id: int
        :param amount: float - must be greater than 0 (usually 25)
        :param portfolio_id: int - portfolio ID which the note will be
                             assigned to if the order is submitted successfully
        """
        if amount <= 0:
            fstr = "amount should be a positive number"
            raise LCError(fstr)
        if amount % 25 != 0:
            fstr = "amount needs to be a multiple of $25"
            raise LCError(fstr)

        self._loan_id = loan_id
        self._amount = amount
        self._portfolio_id = portfolio_id
コード例 #6
0
    def __init__(self, percentage):
        """
        Constructor.

        :param percentage: float (between 0 and 100 inclusive)
        """
        if percentage < 0.0 or percentage > 100.0:
            fstr = "percentage needs to be between 0 and 100 (inclusive)"
            raise LCError(fstr)

        self._percentage = percentage
コード例 #7
0
    def invest(self, *order_notes):
        """
        Invest to loans as specified.

        :param order_notes: iterable of instance of
                            :py:class:`~lendingclub2.response.order.OrderNote`.
        """
        order = Order(self.id(), *order_notes)
        if not order.successful:
            fstr = "could not complete the request completely"
            raise LCError(fstr)
コード例 #8
0
def get_config_content():
    """
    Read the configuration file content.

    :returns: instance of :py:class:`configparser.ConfigParser`.
    """
    fpath = get_config_fpath()
    if not os.path.exists(fpath):
        fstr = "expected configuration path doesn't exist: " + fpath
        raise LCError(fstr)

    config = ConfigParser()
    with open(fpath) as fin:
        config.read_file(fin)
    return config
コード例 #9
0
    def __init__(self, traits):
        """
        Constructor

        :param traits: instance of lendingclub2.filter.BorrowerTrait
                       or iterable of instance of
                       lendingclub2.filter.BorrowerTrait
        """
        if isinstance(traits, collections.Iterable):
            self._specs = traits
        elif isinstance(traits, BorrowerTrait):
            self._specs = (traits, )
        else:
            fstr = "invalid traits type for {}".format(self.__class__.__name__)
            raise LCError(fstr)
コード例 #10
0
    def __init__(self):
        """
        Constructor
        """
        if Authorization._CODE is not None:
            return

        if os.getenv(API_KEY_ENV):
            Authorization._CODE = os.getenv(API_KEY_ENV)
        else:
            config = utils.get_config_content()
            try:
                Authorization._CODE = config['access']['api_key']
            except KeyError as exc:
                fstr = "configuration file doesn't have info about api_key"
                raise LCError(fstr) from exc
コード例 #11
0
    def id(cls):
        """
        Get the account ID.

        :returns: string
        """
        if cls._ID is None:
            if os.getenv(INVESTOR_ID_ENV):
                cls._ID = os.getenv(INVESTOR_ID_ENV)
            else:
                config = utils.get_config_content()
                try:
                    cls._ID = config['account']['investor_id']
                except KeyError as exc:
                    fstr = "cannot find the information of the investor ID"
                    raise LCError(fstr, hint=str(exc))
        return cls._ID
コード例 #12
0
ファイル: transfer.py プロジェクト: thangduong/lendingclub2
def withdraw(investor_id, amount):
    """
    Withdraw the account

    :param investor_id: int - the investor account id
    :param amount: float - amount to withdraw
    :returns: instance of lendingclub2.response.Response
    """
    url = DNS + ENDPOINTS['withdraw'].format(version=API_VERSION,
                                             investor_id=investor_id)

    if amount <= 0.0:
        fstr = "amount has to be a positive number for withdrawal"
        raise LCError(fstr)

    payload = {'amount': amount}
    return Response(request.post(url, json=payload))
コード例 #13
0
def post(*args, **kwargs):
    """
    Wrapper around :py:func:`requests.post` function.

    :param args: tuple - positional arguments for :py:func:`requests.post`.
    :param kwargs: dict - keyword arguments for :py:func:`requests.post`.
    :returns: instance of :py:class:`requests.Response`.
    """
    global __LAST_REQUEST_TIMESTAMP
    __add_headers_to_kwargs(kwargs)
    __wait_request()
    try:
        response = requests.post(*args, **kwargs)
        __LAST_REQUEST_TIMESTAMP = datetime.datetime.now()
        return response
    except requests.ConnectionError as exc:
        fstr = "Cannot connect correctly"
        raise LCError(fstr) from exc
コード例 #14
0
def get(*args, **kwargs):
    """
    Wrapper around requests.get function.

    :param args: tuple - positional arguments for requests.get
    :param kwargs: dict - keyword arguments for requests.get
    :returns: instance of requests.Response
    """
    global __LAST_REQUEST_TIMESTAMP
    __add_headers_to_kwargs(kwargs)
    __wait_request()
    try:
        response = requests.get(*args, **kwargs)
        __LAST_REQUEST_TIMESTAMP = datetime.datetime.now()
        return response
    except requests.ConnectionError as exc:
        fstr = "Cannot connect correctly"
        raise LCError(fstr, details=str(exc))