<commit_before># -*- coding: utf-8 -*-
""" COINCHECK API wrapper """

"""
AUTHOR: @jimako1989
GITHUB: github.com/jimako1989/coincheckpy
LICENSE: MIT
"""

import json,time,hmac,hashlib,requests,datetime
import pandas as pd
from decimal import *
getcontext().prec = 8

"""EndpointsMixin provides a mixin for the API instance """
class EndpointsMixin(object):

    """Public API"""
    def ticker(self, **params):
        """ Get a tick
        Docs: https://coincheck.jp/documents/exchange/api#ticker
        """
        endpoint = 'api/ticker'
        return self.request(endpoint, auth=False, params=params)

    def public_trades(self, **params):
        """ Get public trades
        Docs: https://coincheck.jp/documents/exchange/api#public-trades
        """
        endpoint = 'api/trades'
        return self.request(endpoint, auth=False, params=params)

    def order_book(self, **params):
        """ Get order books
        Docs: https://coincheck.jp/documents/exchange/api#order-book
        """
        endpoint = 'api/order_books'
        return self.request(endpoint, auth=False, params=params)

    """ Private API """
    """ Order """
    def order_new(self, pair, order_type, **params):
        """ Create a new order
        Docs: https://coincheck.jp/documents/exchange/api#order-new
        """
        params['pair'] = pair
        params['order_type'] = order_type

        if (order_type == "buy" or order_type == "sell") and 'rate' not in params and 'amount' not in params:
            raise InputError(['rate', 'amount'], order_type)
        if order_type == "market_buy" and 'market_buy_amount' not in params:
            raise InputError('market_buy_amount', order_type)
        if (order_type == "market_sell" or order_type == "leverage_buy" or order_type == "leverage_sell") and 'amount' not in params:
            raise InputError('amount', order_type)
        if (order_type == "close_long" or order_type == "close_short") and 'amount' not in params and 'positions' not in params:
            raise InputError(['amount', 'positions'], order_type)

        endpoint = 'api/exchange/orders'
        return self.request(endpoint, method='POST', params=params)

    def order_opens(self, **params):
        """ Get open orders
        Docs: https://coincheck.jp/documents/exchange/api#order-opens
        """
        endpoint = 'api/exchange/orders/opens'
        return self.request(endpoint, params=params)

    def order_cancel(self, order_id, **params):
        """ Cancel an order
        Docs: https://coincheck.jp/documents/exchange/api#order-cancel
        """
        params['id'] = order_id
        endpoint = 'api/exchange/orders/'+str(order_id)
        return self.request(endpoint, method='DELETE', params=params)

    def order_transactions(self, **params):
        """ Get your transactions
        Docs: https://coincheck.jp/documents/exchange/api#order-transactions
        """
        endpoint = 'api/exchange/orders/transactions'
        return self.request(endpoint, params=params)

    def order_positions(self, **params):
        """ Get your leverage position list
        Docs: https://coincheck.jp/documents/exchange/api#order-positions
        """
        endpoint = '/api/exchange/leverage/positions'
        return self.request(endpoint, params=params)

    """ Account """
    def account_balance(self, **params):
        """ Check your balance
        Docs: https://coincheck.jp/documents/exchange/api#account-balance
        """
        endpoint = 'api/accounts/balance'
        return self.request(endpoint, params=params)

    def account_leverage_balance(self, **params):
        """ Check your leverage balance
        Docs: https://coincheck.jp/documents/exchange/api#account-leverage-balance
        """
        endpoint = 'api/accounts/leverage_balance'
        return self.request(endpoint, params=params)

    def account_sendmoney(self, address, amount, **params):
        """ Send money
        Docs: https://coincheck.jp/documents/exchange/api#account-sendmoney
        """
        params['address'] = address
        params['amount'] = amount
        endpoint = 'api/send_money'
        return self.request(endpoint,method='POST', params=params)

    def account_sends(self, currency, **params):
        """ Get the history of sent money
        Docs: https://coincheck.jp/documents/exchange/api#account-sends
        """
        params['currency'] = currency
        endpoint = 'api/send_money'
        return self.request(endpoint, params=params)

    def account_deposits(self, currency, **params):
        """ Get the history of deposit money
        Docs: https://coincheck.jp/documents/exchange/api#account-deposits
        """
        params['currency'] = currency
        endpoint = 'api/deposit_money'
        return self.request(endpoint, params=params)

    def account_deposits_fast(self, order_id, **params):
        """ Fast withdrawal
        Docs: https://coincheck.jp/documents/exchange/api#account-deposits-fast
        """
        params['id'] = order_id
        endpoint = 'api/deposit_money/'+str(order_id)+'/fast'
        return self.request(endpoint, method='POST', params=params)

    def account_info(self, **params):
        """ Get account info.
        Docs: https://coincheck.jp/documents/exchange/api#account-info
        """
        endpoint = 'api/accounts'
        return self.request(endpoint, params=params)

    """ Withdrawal """
    def bank_accounts(self, **params):
        """ Get bank accounts
        Docs: https://coincheck.jp/documents/exchange/api#bank-accounts
        """
        endpoint = 'api/bank_accounts'
        return self.request(endpoint, params=params)

    def bank_accounts_create(self, bank_name, branch_name, bank_account_type, number, name, **params):
        """ Create a bank account
        Docs: https://coincheck.jp/documents/exchange/api#bank-accounts-create
        """
        endpoint = 'api/bank_accounts'
        return self.request(endpoint, method='POST', params=params)

    def bank_accounts_destroy(self, bank_id, **params):
        """ Destroy a bank account
        Docs: https://coincheck.jp/documents/exchange/api#bank-accounts-destroy
        """
        endpoint = 'api/bank_accounts/'+str(bank_id)
        return self.request(endpoint, method='DELETE', params=params)

    def withdraws(self, **params):
        """ Get the history of withdraws
        Docs: https://coincheck.jp/documents/exchange/api#withdraws
        """
        endpoint = 'api/withdraws'
        return self.request(endpoint, params=params)

    def withdraws_create(self, bank_account_id, amount, currency, is_fast=False, **params):
        """ Apply the withdrawal
        Docs: https://coincheck.jp/documents/exchange/api#withdraws-create
        """
        params['bank_account_id'] = bank_account_id
        params['amount'] = amount
        params['currency'] = currency
        params['is_fast'] = is_fast
        endpoint = 'api/withdraws'
        return self.request(endpoint, method='POST', params=params)

    def withdraws_destroy(self, withdrawal_id, **params):
        """ Destroy a withdrawal
        Docs: https://coincheck.jp/documents/exchange/api#withdraws-destroy
        """
        params['id'] = withdrawal_id
        endpoint = 'api/withdraws'+str(withdrawal_id)
        return self.request(endpoint, method='DELETE', params=params)

    """ Borrow """
    def create_borrow(self, amount, currency, **params):
        """ Create a borrow
        Docs: https://coincheck.jp/documents/exchange/api#create-borrow
        """
        params['amount'] = amount
        params['currency'] = currency
        endpoint = 'api/lending/borrows'
        return self.request(endpoint, method='POST', params=params)

    def read_borrow_matches(self, **params):
        """ Get the list of borrows
        Docs: https://coincheck.jp/documents/exchange/api#read-borrow-matches
        """
        endpoint = 'api/lending/borrows/matches'
        return self.request(endpoint, params=params)

    def create_repay(self, repay_id, **params):
        """ Repayment
        Docs: https://coincheck.jp/documents/exchange/api#create-repay
        """
        params['id'] = repay_id
        endpoint = 'api/lending/borrows/'+str(repay_id)+'/repay'
        return self.request(endpoint, method='POST', params=params)

    """ Transfer """
    def transfers_to_leverage(self, amount, currency, **params):
        """ Transfers to your leverage account from your spot account.
        Docs: https://coincheck.jp/documents/exchange/api#transfers-to-leverage
        """
        params['amount'] = amount
        params['currency'] = currency
        endpoint = 'api/exchange/transfers/to_leverage'
        return self.request(endpoint, method='POST', params=params)

    def transfers_from_leverage(self, amount, currency, **params):
        """ Transfers to your spot account from your leverage account.
        Docs: https://coincheck.jp/documents/exchange/api#transfers-from-leverage
        """
        params['amount'] = amount
        params['currency'] = currency
        endpoint = 'api/exchange/transfers/from_leverage'
        return self.request(endpoint, method='POST', params=params)

    """ Get the historical prices of JPY/BTC """
    def get_prices(self, term):
        response = requests.get("https://coincheck.jp/exchange/chart.json?line=true&term="+str(term)).json()['chart']
        datetimeIndex = [pd.Timestamp(datetime.datetime.fromtimestamp(r[0]/1000.0)) for r in response]
        rates = [int(r[1]) for r in response]
        series = pd.Series(rates, index=datetimeIndex)
        return(series)

    """ Get the depth of BTC trading """
    def get_depth(self):
        response = requests.get("https://coincheck.jp/exchange/depth_chart.json").json()['chart']
        return(response['buy'], response['sell'])

""" Provides functionality for access to core COINCHECK API calls """

class API(EndpointsMixin, object):
    def __init__(self, environment='live', key=None, secret_key=None):
        """ Instantiates an instance of CoincheckPy's API wrapper """

        if environment == 'live':
            self.api_url = 'https://coincheck.jp'
        else:
            # for future, access to a demo account.
            pass

        self.key = key
        self.secret_key = bytes(secret_key, 'ascii')

        self.client = requests.Session()

    def request(self, endpoint, method='GET', auth=True, params=None):
        """ Returns dict of response from Coincheck's open API """

        self.nonce = str(int(time.time() * 10000))

        url = '%s/%s' % ( self.api_url, endpoint)

        request_args = {}

        method = method.lower()
        params = params or {}

        if 'amount' in params:
            params['amount'] = str(params['amount'])
        if 'rate' in params:
            params['rate'] = str(params['rate'])

        request_args['headers'] = params
        if method == 'get' or method == 'post':
            if type(params) is dict:
                url_endpoint = "?"
            for (key, value) in params.items():
                url_endpoint += str(key) + "=" + str(value) + "&"
            url += url_endpoint[:-1]
        elif method == 'delete':
            pass

        if auth:
            message = bytes(self.nonce + url, 'ascii')
            signature = hmac.new(self.secret_key, msg=message, digestmod=hashlib.sha256).hexdigest()
            headers = {
                "Content-Type":"application/json",\
                "ACCESS-KEY":self.key,\
                "ACCESS-NONCE":self.nonce,\
                "ACCESS-SIGNATURE":signature
            }
            request_args['headers'].update(headers)

        func = getattr(self.client, method)
        try:
            response = func(url, **request_args)
        except requests.RequestException as e:
            print (str(e))

        content = response.json()

        # error message
        if response.status_code >= 400:
            raise CoincheckError(response.status_code,content)

        return content

"""HTTPS Streaming"""
class Streamer():
    """ Provides functionality for HTTPS Streaming """

    def __init__(self, environment='live', heartbeat=1.0):
        """ Instantiates an instance of CoincheckPy's streaming API wrapper. """

        if environment == 'live':
            self.api_url = 'https://coincheck.jp/api/ticker'
        else:
            # for future, access to a demo account.
            pass

        self.heartbeat = heartbeat

        self.client = requests.Session()

    def start(self, **params):
        """ Starts the stream with the given parameters """
        self.connected = True

        request_args = {}

        content_ = {'last':None,'bid':None,'volume':None,'ask':None,'low':None,'high':None}

        while self.connected:
            response = self.client.get(self.api_url, **request_args)
            content = response.content.decode('ascii')
            content = json.loads(content)

            if response.status_code != 200:
                self.on_error(content)

            self.on_success(content)

            time.sleep(self.heartbeat)

    def on_success(self, content):
        """ Called when data is successfully retrieved from the stream """
        print(content)
        return True

    def on_error(self, content):
        """ Called when stream returns non-200 status code
        Override this to handle your streaming data.
        """
        self.connected = False
        return

""" Contains COINCHECK exception """
class CoincheckError(Exception):
    """ Generic error class, catches coincheck response errors
    """

    def __init__(self, status_code, error_response):
        msg = "COINCHECK API returned error code %s (%s) " % (status_code, error_response['error'])

        super(CoincheckError, self).__init__(msg)

""" Parameter input exception """
class InputError(Exception):
    def __init__(self, must_parameters, order_type):
        self.must_parameters = must_parameters
        self.order_type = order_type
    def __str__(self):
        if type(must_parameters) == str:
            return "Parameter: %s is needed if the order type is %s."%(must_parameters, order_type)
        elif type(must_parameters) == list:
            return "Parameters: %s are needed if the order type is %s."%(str(must_parameters), order_type)
<commit_msg>tiny modify.<commit_after># -*- coding: utf-8 -*-
""" COINCHECK API wrapper """

"""
AUTHOR: @jimako1989
GITHUB: github.com/jimako1989/coincheckpy
LICENSE: MIT
"""

import json,time,hmac,hashlib,requests,datetime
import pandas as pd
from decimal import *
getcontext().prec = 8

"""EndpointsMixin provides a mixin for the API instance """
class EndpointsMixin(object):

    """Public API"""
    def ticker(self, **params):
        """ Get a tick
        Docs: https://coincheck.jp/documents/exchange/api#ticker
        """
        endpoint = 'api/ticker'
        return self.request(endpoint, auth=False, params=params)

    def public_trades(self, **params):
        """ Get public trades
        Docs: https://coincheck.jp/documents/exchange/api#public-trades
        """
        endpoint = 'api/trades'
        return self.request(endpoint, auth=False, params=params)

    def order_book(self, **params):
        """ Get order books
        Docs: https://coincheck.jp/documents/exchange/api#order-book
        """
        endpoint = 'api/order_books'
        return self.request(endpoint, auth=False, params=params)

    """ Private API """
    """ Order """
    def order_new(self, pair, order_type, **params):
        """ Create a new order
        Docs: https://coincheck.jp/documents/exchange/api#order-new
        """
        params['pair'] = pair
        params['order_type'] = order_type

        if (order_type == "buy" or order_type == "sell") and 'rate' not in params and 'amount' not in params:
            raise InputError(['rate', 'amount'], order_type)
        if order_type == "market_buy" and 'market_buy_amount' not in params:
            raise InputError('market_buy_amount', order_type)
        if (order_type == "market_sell" or order_type == "leverage_buy" or order_type == "leverage_sell") and 'amount' not in params:
            raise InputError('amount', order_type)
        if (order_type == "close_long" or order_type == "close_short") and 'amount' not in params and 'positions' not in params:
            raise InputError(['amount', 'positions'], order_type)

        endpoint = 'api/exchange/orders'
        return self.request(endpoint, method='POST', params=params)

    def order_opens(self, **params):
        """ Get open orders
        Docs: https://coincheck.jp/documents/exchange/api#order-opens
        """
        endpoint = 'api/exchange/orders/opens'
        return self.request(endpoint, params=params)

    def order_cancel(self, order_id, **params):
        """ Cancel an order
        Docs: https://coincheck.jp/documents/exchange/api#order-cancel
        """
        params['id'] = order_id
        endpoint = 'api/exchange/orders/'+str(order_id)
        return self.request(endpoint, method='DELETE', params=params)

    def order_transactions(self, **params):
        """ Get your transactions
        Docs: https://coincheck.jp/documents/exchange/api#order-transactions
        """
        endpoint = 'api/exchange/orders/transactions'
        return self.request(endpoint, params=params)

    def order_positions(self, **params):
        """ Get your leverage position list
        Docs: https://coincheck.jp/documents/exchange/api#order-positions
        """
        endpoint = 'api/exchange/leverage/positions'
        return self.request(endpoint ,params=params)

    """ Account """
    def account_balance(self, **params):
        """ Check your balance
        Docs: https://coincheck.jp/documents/exchange/api#account-balance
        """
        endpoint = 'api/accounts/balance'
        return self.request(endpoint, params=params)

    def account_leverage_balance(self, **params):
        """ Check your leverage balance
        Docs: https://coincheck.jp/documents/exchange/api#account-leverage-balance
        """
        endpoint = 'api/accounts/leverage_balance'
        return self.request(endpoint, params=params)

    def account_sendmoney(self, address, amount, **params):
        """ Send money
        Docs: https://coincheck.jp/documents/exchange/api#account-sendmoney
        """
        params['address'] = address
        params['amount'] = amount
        endpoint = 'api/send_money'
        return self.request(endpoint,method='POST', params=params)

    def account_sends(self, currency, **params):
        """ Get the history of sent money
        Docs: https://coincheck.jp/documents/exchange/api#account-sends
        """
        params['currency'] = currency
        endpoint = 'api/send_money'
        return self.request(endpoint, params=params)

    def account_deposits(self, currency, **params):
        """ Get the history of deposit money
        Docs: https://coincheck.jp/documents/exchange/api#account-deposits
        """
        params['currency'] = currency
        endpoint = 'api/deposit_money'
        return self.request(endpoint, params=params)

    def account_deposits_fast(self, order_id, **params):
        """ Fast withdrawal
        Docs: https://coincheck.jp/documents/exchange/api#account-deposits-fast
        """
        params['id'] = order_id
        endpoint = 'api/deposit_money/'+str(order_id)+'/fast'
        return self.request(endpoint, method='POST', params=params)

    def account_info(self, **params):
        """ Get account info.
        Docs: https://coincheck.jp/documents/exchange/api#account-info
        """
        endpoint = 'api/accounts'
        return self.request(endpoint, params=params)

    """ Withdrawal """
    def bank_accounts(self, **params):
        """ Get bank accounts
        Docs: https://coincheck.jp/documents/exchange/api#bank-accounts
        """
        endpoint = 'api/bank_accounts'
        return self.request(endpoint, params=params)

    def bank_accounts_create(self, bank_name, branch_name, bank_account_type, number, name, **params):
        """ Create a bank account
        Docs: https://coincheck.jp/documents/exchange/api#bank-accounts-create
        """
        endpoint = 'api/bank_accounts'
        return self.request(endpoint, method='POST', params=params)

    def bank_accounts_destroy(self, bank_id, **params):
        """ Destroy a bank account
        Docs: https://coincheck.jp/documents/exchange/api#bank-accounts-destroy
        """
        endpoint = 'api/bank_accounts/'+str(bank_id)
        return self.request(endpoint, method='DELETE', params=params)

    def withdraws(self, **params):
        """ Get the history of withdraws
        Docs: https://coincheck.jp/documents/exchange/api#withdraws
        """
        endpoint = 'api/withdraws'
        return self.request(endpoint, params=params)

    def withdraws_create(self, bank_account_id, amount, currency, is_fast=False, **params):
        """ Apply the withdrawal
        Docs: https://coincheck.jp/documents/exchange/api#withdraws-create
        """
        params['bank_account_id'] = bank_account_id
        params['amount'] = amount
        params['currency'] = currency
        params['is_fast'] = is_fast
        endpoint = 'api/withdraws'
        return self.request(endpoint, method='POST', params=params)

    def withdraws_destroy(self, withdrawal_id, **params):
        """ Destroy a withdrawal
        Docs: https://coincheck.jp/documents/exchange/api#withdraws-destroy
        """
        params['id'] = withdrawal_id
        endpoint = 'api/withdraws'+str(withdrawal_id)
        return self.request(endpoint, method='DELETE', params=params)

    """ Borrow """
    def create_borrow(self, amount, currency, **params):
        """ Create a borrow
        Docs: https://coincheck.jp/documents/exchange/api#create-borrow
        """
        params['amount'] = amount
        params['currency'] = currency
        endpoint = 'api/lending/borrows'
        return self.request(endpoint, method='POST', params=params)

    def read_borrow_matches(self, **params):
        """ Get the list of borrows
        Docs: https://coincheck.jp/documents/exchange/api#read-borrow-matches
        """
        endpoint = 'api/lending/borrows/matches'
        return self.request(endpoint, params=params)

    def create_repay(self, repay_id, **params):
        """ Repayment
        Docs: https://coincheck.jp/documents/exchange/api#create-repay
        """
        params['id'] = repay_id
        endpoint = 'api/lending/borrows/'+str(repay_id)+'/repay'
        return self.request(endpoint, method='POST', params=params)

    """ Transfer """
    def transfers_to_leverage(self, amount, currency, **params):
        """ Transfers to your leverage account from your spot account.
        Docs: https://coincheck.jp/documents/exchange/api#transfers-to-leverage
        """
        params['amount'] = amount
        params['currency'] = currency
        endpoint = 'api/exchange/transfers/to_leverage'
        return self.request(endpoint, method='POST', params=params)

    def transfers_from_leverage(self, amount, currency, **params):
        """ Transfers to your spot account from your leverage account.
        Docs: https://coincheck.jp/documents/exchange/api#transfers-from-leverage
        """
        params['amount'] = amount
        params['currency'] = currency
        endpoint = 'api/exchange/transfers/from_leverage'
        return self.request(endpoint, method='POST', params=params)

    """ Get the historical prices of JPY/BTC """
    def get_prices(self, term):
        response = requests.get("https://coincheck.jp/exchange/chart.json?line=true&term="+str(term)).json()['chart']
        datetimeIndex = [pd.Timestamp(datetime.datetime.fromtimestamp(r[0]/1000.0)) for r in response]
        rates = [int(r[1]) for r in response]
        series = pd.Series(rates, index=datetimeIndex)
        return(series)

    """ Get the depth of BTC trading """
    def get_depth(self):
        response = requests.get("https://coincheck.jp/exchange/depth_chart.json").json()['chart']
        return(response['buy'], response['sell'])

""" Provides functionality for access to core COINCHECK API calls """

class API(EndpointsMixin, object):
    def __init__(self, environment='live', key=None, secret_key=None):
        """ Instantiates an instance of CoincheckPy's API wrapper """

        if environment == 'live':
            self.api_url = 'https://coincheck.jp'
        else:
            # for future, access to a demo account.
            pass

        self.key = key
        self.secret_key = bytes(secret_key, 'ascii')

        self.client = requests.Session()

    def request(self, endpoint, method='GET', auth=True, params=None):
        """ Returns dict of response from Coincheck's open API """

        self.nonce = str(int(time.time() * 10000))

        url = '%s/%s' % ( self.api_url, endpoint)

        request_args = {}

        method = method.lower()
        params = params or {}

        if 'amount' in params:
            params['amount'] = str(params['amount'])
        if 'rate' in params:
            params['rate'] = str(params['rate'])

        request_args['headers'] = params
        if method == 'get' or method == 'post':
            if type(params) is dict:
                url_endpoint = "?"
            for (key, value) in params.items():
                url_endpoint += str(key) + "=" + str(value) + "&"
            url += url_endpoint[:-1]
        elif method == 'delete':
            pass

        if auth:
            message = bytes(self.nonce + url, 'ascii')
            signature = hmac.new(self.secret_key, msg=message, digestmod=hashlib.sha256).hexdigest()
            headers = {
                "Content-Type":"application/json",\
                "ACCESS-KEY":self.key,\
                "ACCESS-NONCE":self.nonce,\
                "ACCESS-SIGNATURE":signature
            }
            request_args['headers'].update(headers)

        func = getattr(self.client, method)
        try:
            response = func(url, **request_args)
        except requests.RequestException as e:
            print (str(e))

        content = response.json()

        # error message
        if response.status_code >= 400:
            raise CoincheckError(response.status_code,content)

        return content

"""HTTPS Streaming"""
class Streamer():
    """ Provides functionality for HTTPS Streaming """

    def __init__(self, environment='live', heartbeat=1.0):
        """ Instantiates an instance of CoincheckPy's streaming API wrapper. """

        if environment == 'live':
            self.api_url = 'https://coincheck.jp/api/ticker'
        else:
            # for future, access to a demo account.
            pass

        self.heartbeat = heartbeat

        self.client = requests.Session()

    def start(self, **params):
        """ Starts the stream with the given parameters """
        self.connected = True

        request_args = {}

        content_ = {'last':None,'bid':None,'volume':None,'ask':None,'low':None,'high':None}

        while self.connected:
            response = self.client.get(self.api_url, **request_args)
            content = response.content.decode('ascii')
            content = json.loads(content)

            if response.status_code != 200:
                self.on_error(content)

            self.on_success(content)

            time.sleep(self.heartbeat)

    def on_success(self, content):
        """ Called when data is successfully retrieved from the stream """
        print(content)
        return True

    def on_error(self, content):
        """ Called when stream returns non-200 status code
        Override this to handle your streaming data.
        """
        self.connected = False
        return

""" Contains COINCHECK exception """
class CoincheckError(Exception):
    """ Generic error class, catches coincheck response errors
    """

    def __init__(self, status_code, error_response):
        msg = "COINCHECK API returned error code %s (%s) " % (status_code, error_response['error'])

        super(CoincheckError, self).__init__(msg)

""" Parameter input exception """
class InputError(Exception):
    def __init__(self, must_parameters, order_type):
        self.must_parameters = must_parameters
        self.order_type = order_type
    def __str__(self):
        if type(must_parameters) == str:
            return "Parameter: %s is needed if the order type is %s."%(must_parameters, order_type)
        elif type(must_parameters) == list:
            return "Parameters: %s are needed if the order type is %s."%(str(must_parameters), order_type)
<|endoftext|>


<commit_before>#!/usr/bin/env python

import lang
from code import process

def get_package(name):
	return ".".join(name.split(".")[:-1])

def split_name(name):
	r = name.split(".")
	return ".".join(r[:-1]), r[-1]

class component_generator(object):
	def __init__(self, name, component):
		self.name = name
		self.component = component
		self.properties = {}
		self.assignments = {}
		self.animations = {}
		self.package = get_package(name)
		self.base_type = None
		self.children = []
		self.methods = {}
		self.event_handlers = {}
		self.id = None

		for child in component.children:
			self.add_child(child)

	def collect_id(self, id_set):
		if self.id is not None:
			id_set.add(self.id)
		for g in self.assignments.itervalues():
			if type(g) is component_generator and g.id:
				g.collect_id(id_set)
		for g in self.animations.itervalues():
			if type(g) is component_generator and g.id:
				g.collect_id(id_set)
		for g in self.children:
			g.collect_id(id_set)

	def assign(self, target, value):
		t = type(value)
		if t is lang.Component:
			value = component_generator(self.package + ".<anonymous>", value)
		self.assignments[target] = value

	def add_child(self, child):
		t = type(child)
		if t is lang.Property:
			if child.name in self.properties:
				raise Exception("duplicate property " + child.name)
			self.properties[child.name] = child.type
			if child.value is not None:
				self.assign(child.name, child.value)
		elif t is lang.Assignment:
			self.assign(child.target, child.value)
		elif t is lang.IdAssignment:
			self.id = child.name
			self.assign("id", child.name)
		elif t is lang.Component:
			self.children.append(component_generator(self.package + ".<anonymous>", child))
		elif t is lang.Behavior:
			if child.target in self.animations:
				raise Exception("duplicate animation on property " + child.target);
			self.animations[child.target] = component_generator(self.package + ".<anonymous-animation>", child.animation)
		elif t is lang.Method:
			name, code = child.name, child.code
			if len(name) > 2 and name.startswith("on") and name[2].isupper(): #onXyzzy
				name = name[2].lower() + name[3:]
				if name in self.event_handlers:
					raise Exception("duplicate event handler " + child.name)
				self.event_handlers[name] = code
			else:
				if name in self.methods:
					raise Exception("duplicate " + name + " method")
				self.methods[name] = code
		elif t is lang.Event:
			pass
		else:
			print "unhandled", child

	def generate_properties(self):
		r = []
		for name, type in self.properties.iteritems():
			r.append("\tcore.addProperty(this, '%s', '%s');" %(type, name))
		return "\n".join(r)

	def generate_ctor(self, registry):
		return "\texports.%s.apply(this, arguments);\n" %(registry.find_component(self.package, self.component.name))

	def generate(self, registry):
		ctor  = "\texports.%s = function() {\n%s\n%s\n%s\n\tcore._bootstrap(this, '%s');\n}\n" %(self.name, self.generate_ctor(registry), self.generate_properties(), self.generate_creator(registry, "this"), self.name)
		return ctor

	def generate_animations(self, registry, parent):
		r = []
		for name, animation in self.animations.iteritems():
			var = "behavior_on_" + name
			r.append("\tvar %s = new _globals.%s(%s);" %(var, registry.find_component(self.package, animation.component.name), parent))
			r.append(self.wrap_creator(var, animation.generate_creator(registry, var, 2)))
			r.append("\tthis.setAnimation('%s', %s);\n" %(name, var))
		return "\n".join(r)

	def wrap_creator(self, var, code):
		return "\tfunction setup_%s () {\n%s\n\t}\n\tsetup_%s.call(%s)" %(var, code, var, var)

	def generate_creator(self, registry, parent, ident = 1):
		r = []
		ident = "\t" * ident
		for target, value in self.assignments.iteritems():
			t = type(value)
			#print self.name, target, value
			if target == "id":
				if "." in value:
					raiseException("expected identifier, not expression")
				r.append("%sthis._setId('%s')" %(ident, value))
			elif target.endswith(".id"):
				raise Exception("setting id of the remote object is prohibited")
			elif t is str:
				r.append("%sthis.%s = %s;" %(ident, target, value))
			elif t is component_generator:
				var = "this.%s" %target
				r.append("\t%s = new _globals.%s(%s);" %(var, registry.find_component(value.package, value.component.name), parent))
				r.append(value.generate_creator(registry, var, 2))
			else:
				raise Exception("skip assignment %s = %s" %(target, value))
		idx = 0
		for gen in self.children:
			var = "%s_child%d" %(parent, idx)
			component = registry.find_component(self.package, gen.component.name)
			r.append("\tvar %s = new _globals.%s(%s);" %(var, component, parent))
			r.append(self.wrap_creator(var, gen.generate_creator(registry, var, 2)))
			r.append("\tthis.children.push(%s);" %var);
			r.append("")
			idx += 1
		for name, code in self.methods.iteritems():
			code = process(code, registry)
			r.append("%sthis.%s = (function() %s ).bind(this);" %(ident, name, code))
		for name, code in self.event_handlers.iteritems():
			code = process(code, registry)
			r.append("%sthis.on('%s', (function() %s ).bind(this));" %(ident, name, code))
		r.append(self.generate_animations(registry, parent))
		return "\n".join(r)

class generator(object):
	def __init__(self):
		self.components = {}
		self.imports = {}
		self.packages = {}
		self.startup = []
		self.id_set = set()
		self.startup.append("qml._imports['core/core.js'].Context.prototype = Object.create(qml.core.Item.prototype);")
		self.startup.append("qml._imports['core/core.js'].Context.prototype.constructor = qml._imports['core/core.js'].Context.Context;")
		self.startup.append("qml._context = new qml._imports['core/core.js'].Context();")
		self.startup.append("qml._imports['core/core.js']._setup(qml._context);")

	def add_component(self, name, component, declaration):
		if name in self.components:
			raise Exception("duplicate component " + name)

		package, component_name = split_name(name)

		if not declaration:
			name = "%s.Ui%s" %(package, component_name[0].upper() + component_name[1:])
			self.startup.append("qml._context.start(qml.%s)" %name)

		if package not in self.packages:
			self.packages[package] = set()
		self.packages[package].add(component_name)

		gen = component_generator(name, component)
		self.components[name] = gen

	def add_js(self, name, data):
		if name in self.imports:
			raise Exception("duplicate js name " + name)
		self.imports[name] = data

	def add_components(self, name, components, declaration):
		for component in components:
			self.add_component(name, component, declaration)

	def wrap(self, code):
		return "(function() {\nvar exports = {};\n%s\nreturn exports;\n} )" %code

	def find_component(self, package, name):
		if name == "Object":
			return "core.Object"

		if package in self.packages and name in self.packages[package]:
			return "%s.%s" %(package, name)
		for package_name, components in self.packages.iteritems():
			if name in components:
				return "%s.%s" %(package_name, name)
		raise Exception("component %s was not found" %name)

	def generate_components(self):
		r, deps = [], []
		for package in sorted(self.packages.keys()):
			r.append("if (!exports.%s) exports.%s = {};" %(package, package))

		for gen in self.components.itervalues():
			gen.collect_id(self.id_set)

		for name, gen in self.components.iteritems():
			code = "//=====[component %s]=====================\n\n" %name
			code += gen.generate(self)
			base_type = self.find_component(gen.package, gen.component.name)

			for i in xrange(0, len(deps)):
				t, b = deps[i]
				if base_type == t: #my base class, append after
					deps.insert(i + 1, (name, base_type))
					break
				if name == b: #me is base class, prepend before
					deps.insert(i, (name, base_type))
					break
			else:
				deps.append((name, base_type))

			r.append(code)

		for type, base_type in deps:
			code = ""
			code += "\texports.%s.prototype = Object.create(exports.%s.prototype);\n" %(type, base_type)
			code += "\texports.%s.prototype.constructor = exports.%s;\n" %(type, type)
			r.append(code)

		return "\n".join(r)

	def generate_imports(self):
		r = []
		for name, code in self.imports.iteritems():
			code = "//=====[import %s]=====================\n\n" %name + code
			r.append("'%s': %s()" %(name, self.wrap(code)))
		return ", ".join(r)

	def generate(self, ns):
		text = ""
		text += "var _globals = exports;\n"
		text += "var imports = { %s };\n" %self.generate_imports()
		text += "_globals._imports = imports;\n"
		text += "//========================================\n\n"
		text += "var core = imports['core/core.js'];\n"
		text += "%s\n" %self.generate_components()
		return "%s = %s();\n" %(ns, self.wrap(text))

	def generate_startup(self):
		return "\n".join(self.startup)
<commit_msg>explicitly market 'renderer' as public id<commit_after>#!/usr/bin/env python

import lang
from code import process

def get_package(name):
	return ".".join(name.split(".")[:-1])

def split_name(name):
	r = name.split(".")
	return ".".join(r[:-1]), r[-1]

class component_generator(object):
	def __init__(self, name, component):
		self.name = name
		self.component = component
		self.properties = {}
		self.assignments = {}
		self.animations = {}
		self.package = get_package(name)
		self.base_type = None
		self.children = []
		self.methods = {}
		self.event_handlers = {}
		self.id = None

		for child in component.children:
			self.add_child(child)

	def collect_id(self, id_set):
		if self.id is not None:
			id_set.add(self.id)
		for g in self.assignments.itervalues():
			if type(g) is component_generator and g.id:
				g.collect_id(id_set)
		for g in self.animations.itervalues():
			if type(g) is component_generator and g.id:
				g.collect_id(id_set)
		for g in self.children:
			g.collect_id(id_set)

	def assign(self, target, value):
		t = type(value)
		if t is lang.Component:
			value = component_generator(self.package + ".<anonymous>", value)
		self.assignments[target] = value

	def add_child(self, child):
		t = type(child)
		if t is lang.Property:
			if child.name in self.properties:
				raise Exception("duplicate property " + child.name)
			self.properties[child.name] = child.type
			if child.value is not None:
				self.assign(child.name, child.value)
		elif t is lang.Assignment:
			self.assign(child.target, child.value)
		elif t is lang.IdAssignment:
			self.id = child.name
			self.assign("id", child.name)
		elif t is lang.Component:
			self.children.append(component_generator(self.package + ".<anonymous>", child))
		elif t is lang.Behavior:
			if child.target in self.animations:
				raise Exception("duplicate animation on property " + child.target);
			self.animations[child.target] = component_generator(self.package + ".<anonymous-animation>", child.animation)
		elif t is lang.Method:
			name, code = child.name, child.code
			if len(name) > 2 and name.startswith("on") and name[2].isupper(): #onXyzzy
				name = name[2].lower() + name[3:]
				if name in self.event_handlers:
					raise Exception("duplicate event handler " + child.name)
				self.event_handlers[name] = code
			else:
				if name in self.methods:
					raise Exception("duplicate " + name + " method")
				self.methods[name] = code
		elif t is lang.Event:
			pass
		else:
			print "unhandled", child

	def generate_properties(self):
		r = []
		for name, type in self.properties.iteritems():
			r.append("\tcore.addProperty(this, '%s', '%s');" %(type, name))
		return "\n".join(r)

	def generate_ctor(self, registry):
		return "\texports.%s.apply(this, arguments);\n" %(registry.find_component(self.package, self.component.name))

	def generate(self, registry):
		ctor  = "\texports.%s = function() {\n%s\n%s\n%s\n\tcore._bootstrap(this, '%s');\n}\n" %(self.name, self.generate_ctor(registry), self.generate_properties(), self.generate_creator(registry, "this"), self.name)
		return ctor

	def generate_animations(self, registry, parent):
		r = []
		for name, animation in self.animations.iteritems():
			var = "behavior_on_" + name
			r.append("\tvar %s = new _globals.%s(%s);" %(var, registry.find_component(self.package, animation.component.name), parent))
			r.append(self.wrap_creator(var, animation.generate_creator(registry, var, 2)))
			r.append("\tthis.setAnimation('%s', %s);\n" %(name, var))
		return "\n".join(r)

	def wrap_creator(self, var, code):
		return "\tfunction setup_%s () {\n%s\n\t}\n\tsetup_%s.call(%s)" %(var, code, var, var)

	def generate_creator(self, registry, parent, ident = 1):
		r = []
		ident = "\t" * ident
		for target, value in self.assignments.iteritems():
			t = type(value)
			#print self.name, target, value
			if target == "id":
				if "." in value:
					raiseException("expected identifier, not expression")
				r.append("%sthis._setId('%s')" %(ident, value))
			elif target.endswith(".id"):
				raise Exception("setting id of the remote object is prohibited")
			elif t is str:
				r.append("%sthis.%s = %s;" %(ident, target, value))
			elif t is component_generator:
				var = "this.%s" %target
				r.append("\t%s = new _globals.%s(%s);" %(var, registry.find_component(value.package, value.component.name), parent))
				r.append(value.generate_creator(registry, var, 2))
			else:
				raise Exception("skip assignment %s = %s" %(target, value))
		idx = 0
		for gen in self.children:
			var = "%s_child%d" %(parent, idx)
			component = registry.find_component(self.package, gen.component.name)
			r.append("\tvar %s = new _globals.%s(%s);" %(var, component, parent))
			r.append(self.wrap_creator(var, gen.generate_creator(registry, var, 2)))
			r.append("\tthis.children.push(%s);" %var);
			r.append("")
			idx += 1
		for name, code in self.methods.iteritems():
			code = process(code, registry)
			r.append("%sthis.%s = (function() %s ).bind(this);" %(ident, name, code))
		for name, code in self.event_handlers.iteritems():
			code = process(code, registry)
			r.append("%sthis.on('%s', (function() %s ).bind(this));" %(ident, name, code))
		r.append(self.generate_animations(registry, parent))
		return "\n".join(r)

class generator(object):
	def __init__(self):
		self.components = {}
		self.imports = {}
		self.packages = {}
		self.startup = []
		self.id_set = set(['renderer'])
		self.startup.append("qml._imports['core/core.js'].Context.prototype = Object.create(qml.core.Item.prototype);")
		self.startup.append("qml._imports['core/core.js'].Context.prototype.constructor = qml._imports['core/core.js'].Context.Context;")
		self.startup.append("qml._context = new qml._imports['core/core.js'].Context();")
		self.startup.append("qml._imports['core/core.js']._setup(qml._context);")

	def add_component(self, name, component, declaration):
		if name in self.components:
			raise Exception("duplicate component " + name)

		package, component_name = split_name(name)

		if not declaration:
			name = "%s.Ui%s" %(package, component_name[0].upper() + component_name[1:])
			self.startup.append("qml._context.start(qml.%s)" %name)

		if package not in self.packages:
			self.packages[package] = set()
		self.packages[package].add(component_name)

		gen = component_generator(name, component)
		self.components[name] = gen

	def add_js(self, name, data):
		if name in self.imports:
			raise Exception("duplicate js name " + name)
		self.imports[name] = data

	def add_components(self, name, components, declaration):
		for component in components:
			self.add_component(name, component, declaration)

	def wrap(self, code):
		return "(function() {\nvar exports = {};\n%s\nreturn exports;\n} )" %code

	def find_component(self, package, name):
		if name == "Object":
			return "core.Object"

		if package in self.packages and name in self.packages[package]:
			return "%s.%s" %(package, name)
		for package_name, components in self.packages.iteritems():
			if name in components:
				return "%s.%s" %(package_name, name)
		raise Exception("component %s was not found" %name)

	def generate_components(self):
		r, deps = [], []
		for package in sorted(self.packages.keys()):
			r.append("if (!exports.%s) exports.%s = {};" %(package, package))

		for gen in self.components.itervalues():
			gen.collect_id(self.id_set)

		for name, gen in self.components.iteritems():
			code = "//=====[component %s]=====================\n\n" %name
			code += gen.generate(self)
			base_type = self.find_component(gen.package, gen.component.name)

			for i in xrange(0, len(deps)):
				t, b = deps[i]
				if base_type == t: #my base class, append after
					deps.insert(i + 1, (name, base_type))
					break
				if name == b: #me is base class, prepend before
					deps.insert(i, (name, base_type))
					break
			else:
				deps.append((name, base_type))

			r.append(code)

		for type, base_type in deps:
			code = ""
			code += "\texports.%s.prototype = Object.create(exports.%s.prototype);\n" %(type, base_type)
			code += "\texports.%s.prototype.constructor = exports.%s;\n" %(type, type)
			r.append(code)

		return "\n".join(r)

	def generate_imports(self):
		r = []
		for name, code in self.imports.iteritems():
			code = "//=====[import %s]=====================\n\n" %name + code
			r.append("'%s': %s()" %(name, self.wrap(code)))
		return ", ".join(r)

	def generate(self, ns):
		text = ""
		text += "var _globals = exports;\n"
		text += "var imports = { %s };\n" %self.generate_imports()
		text += "_globals._imports = imports;\n"
		text += "//========================================\n\n"
		text += "var core = imports['core/core.js'];\n"
		text += "%s\n" %self.generate_components()
		return "%s = %s();\n" %(ns, self.wrap(text))

	def generate_startup(self):
		return "\n".join(self.startup)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
""" COINCHECK API wrapper """

"""
AUTHOR: @jimako1989
GITHUB: github.com/jimako1989/coincheckpy
LICENSE: MIT
"""

import json,time,hmac,hashlib,requests

"""EndpointsMixin provides a mixin for the API instance """
class EndpointsMixin(object):

    """Public API"""
    def ticker(self, **params):
        """ Get a tick
        Docs: https://coincheck.jp/documents/exchange/api#ticker
        """
        endpoint = 'api/ticker'
        return self.request(endpoint, auth=False, params=params)

    def public_trades(self, **params):
        """ Get public trades
        Docs: https://coincheck.jp/documents/exchange/api#public-trades
        """
        endpoint = 'api/trades'
        return self.request(endpoint, auth=False, params=params)

    def order_book(self, **params):
        """ Get order books
        Docs: https://coincheck.jp/documents/exchange/api#order-book
        """
        endpoint = 'api/order_books'
        return self.request(endpoint, auth=False, params=params)

    """ Private API """
    """ Order """
    def order_new(self, pair, order_type, **params):
        """ Create a new order
        Docs: https://coincheck.jp/documents/exchange/api#order-new
        """
        params['pair'] = pair
        params['order_type'] = order_type
        endpoint = 'api/exchange/orders'
        return self.request(endpoint, params=params)

    def order_opens(self, **params):
        """ Get open orders
        Docs: https://coincheck.jp/documents/exchange/api#order-opens
        """
        endpoint = 'api/exchange/orders/opens'
        return self.request(endpoint, params=params)

    def order_cancel(self, order_id, **params):
        """ Cancel an order
        Docs: https://coincheck.jp/documents/exchange/api#order-cancel
        """
        params['id'] = order_id
        endpoint = 'api/exchange/orders/'+str(order_id)
        return self.request(endpoint, params=params)

    def order_transactions(self, **params):
        """ Get my transactions
        Docs: https://coincheck.jp/documents/exchange/api#order-transactions
        """
        endpoint = 'api/exchange/orders/transactions'
        return self.request(endpoint, params=params)

    """ Account """
    def account_balance(self, **params):
        """ Check the balance
        Docs: https://coincheck.jp/documents/exchange/api#account-balance
        """
        endpoint = 'api/accounts/balance'
        return self.request(endpoint, params=params)

    def account_sendmoney(self, address, amount, **params):
        """ Send money
        Docs: https://coincheck.jp/documents/exchange/api#account-sendmoney
        """
        params['address'] = address
        params['amount'] = amount
        endpoint = 'api/send_money'
        return self.request(endpoint, params=params)

    def account_sends(self, currency, **params):
        """ Get the history of sent money
        Docs: https://coincheck.jp/documents/exchange/api#account-sends
        """
        params['currency'] = currency
        endpoint = 'api/send_money'
        return self.request(endpoint, params=params)

    def account_deposits(self, currency, **params):
        """ Get the history of deposit money
        Docs: https://coincheck.jp/documents/exchange/api#account-deposits
        """
        params['currency'] = currency
        endpoint = 'api/deposit_money'
        return self.request(endpoint, params=params)

    def account_deposits_fast(self, order_id, **params):
        """ Fast withdrawal
        Docs: https://coincheck.jp/documents/exchange/api#account-deposits-fast
        """
        params['id'] = order_id
        endpoint = 'api/deposit_money/'+str(order_id)+'/fast'
        return self.request(endpoint, params=params)

    def account_info(self, **params):
        """ Get account info.
        Docs: https://coincheck.jp/documents/exchange/api#account-info
        """
        endpoint = 'api/accounts'
        return self.request(endpoint, params=params)

    """ Withdrawal """
    def bank_accounts(self, **params):
        """ Get bank accounts
        Docs: https://coincheck.jp/documents/exchange/api#bank-accounts
        """
        endpoint = 'api/bank_accounts'
        return self.request(endpoint, params=params)

    def bank_accounts_create(self, bank_name, branch_name, bank_account_type, number, name, **params):
        """ Create a bank account
        Docs: https://coincheck.jp/documents/exchange/api#bank-accounts-create
        """
        endpoint = 'api/bank_accounts'
        return self.request(endpoint, params=params)

    def bank_accounts_destroy(self, bank_id, **params):
        """ Destroy a bank account
        Docs: https://coincheck.jp/documents/exchange/api#bank-accounts-destroy
        """
        endpoint = 'api/bank_accounts/'+str(bank_id)
        return self.request(endpoint, params=params)

    def withdraws(self, **params):
        """ Get the history of withdraws
        Docs: https://coincheck.jp/documents/exchange/api#withdraws
        """
        endpoint = 'api/withdraws'
        return self.request(endpoint, params=params)

    def withdraws_create(self, bank_account_id, amount, currency, is_fast=False, **params):
        """ Apply the withdrawal
        Docs: https://coincheck.jp/documents/exchange/api#withdraws-create
        """
        params['bank_account_id'] = bank_account_id
        params['amount'] = amount
        params['currency'] = currency
        params['is_fast'] = is_fast
        endpoint = 'api/withdraws'
        return self.request(endpoint, params=params)

    def withdraws_destroy(self, withdrawal_id, **params):
        """ Destroy a withdrawal
        Docs: https://coincheck.jp/documents/exchange/api#withdraws-destroy
        """
        params['id'] = withdrawal_id
        endpoint = 'api/withdraws'+str(withdrawal_id)
        return self.request(endpoint, params=params)

    """ Borrow """
    def create_borrow(self, amount, currency, **params):
        """ Create a borrow
        Docs: https://coincheck.jp/documents/exchange/api#create-borrow
        """
        params['amount'] = amount
        params['currency'] = currency
        endpoint = 'api/lending/borrows'
        return self.request(endpoint, params=params)

    def read_borrow_matches(self, **params):
        """ Get the list of borrows
        Docs: https://coincheck.jp/documents/exchange/api#read-borrow-matches
        """
        endpoint = 'api/lending/borrows/matches'
        return self.request(endpoint, params=params)

    def create_repay(self, repay_id, **params):
        """ Repayment
        Docs: https://coincheck.jp/documents/exchange/api#create-repay
        """
        params['id'] = repay_id
        endpoint = 'api/lending/borrows/'+str(repay_id)+'/repay'
        return self.request(endpoint, params=params)

    """ Lend """
    def create_lend(self, amount, currency, **params):
        """ Create lend (=loan)
        Docs: https://coincheck.jp/documents/exchange/api#create-lend
        """
        params['amount'] = amount
        params['currency'] = currency
        endpoint = 'api/lending/lends'
        return self.request(endpoint, params=params)

    def read_lend(self, **params):
        """ Get the list of lend (=loan)
        Docs: https://coincheck.jp/documents/exchange/api#read-lend
        """
        endpoint = 'api/lending/lends'
        return self.request(endpoint, params=params)

    def cancel_lend(self, loan_id, **params):
        """ Cancel a lend (=loan)
        Docs: https://coincheck.jp/documents/exchange/api#cancel-lend
        """
        params['id']=loan_id
        endpoint = 'api/lending/lends/'+str(loan_id)+'/cancel'
        return self.request(endpoint, params=params)

    def read_lend_matches(self, **params):
        """ Get the list of used lend (=loan)
        Docs: https://coincheck.jp/documents/exchange/api#read-lend-matches
        """
        endpoint = 'api/lending/lends/matches'
        return self.request(endpoint, params=params)

""" Provides functionality for access to core COINCHECK API calls """

class API(EndpointsMixin, object):
    def __init__(self, environment='live', key=None, secret_key=None):
        """ Instantiates an instance of CoincheckPy's API wrapper """

        if environment == 'live':
            self.api_url = 'https://coincheck.jp'
        else:
            # for future, access to a demo account.
            pass

        self.key = key
        self.secret_key = secret_key.encode('utf-8')
        self.nonce = str(int(time.time()))

        self.client = requests.Session()

    def request(self, endpoint, method='GET', auth=True, params=None):
        """ Returns dict of response from Coincheck's open API """

        url = '%s/%s' % ( self.api_url, endpoint)

        request_args = {}

        method = method.lower()
        params = params or {}

        func = getattr(self.client, method)

        if method == 'get':
            request_args['headers'] = params
        else:
            request_args['data'] = params

        url_endpoint = ""
        if type(params) is dict:
            url_endpoint = "?"
        for tup in params.items():
            url_endpoint += str(tup[0]) + "=" + str(tup[1]) + "&"
        url += url_endpoint[:-1]

        if auth:
            message = (self.nonce + url).encode('utf-8')
            signature = hmac.new(self.secret_key, msg=message, digestmod=hashlib.sha256).hexdigest()

            headers = {"ACCESS-KEY":self.key,"ACCESS-NONCE":self.nonce,"ACCESS-SIGNATURE":signature}
            request_args['headers'].update(headers)

        try:
            response = func(url, **request_args)
        except requests.RequestException as e:
            print (str(e))
        content = response.content.decode('utf-8')

        content = json.loads(content)

        # error message
        if response.status_code >= 400:
            raise CoincheckError(response.status_code,content)

        return content

"""HTTPS Streaming"""
class Streamer():
    """ Provides functionality for HTTPS Streaming """

    def __init__(self, environment='live', heartbeat=1.0):
        """ Instantiates an instance of CoincheckPy's streaming API wrapper. """

        if environment == 'live':
            self.api_url = 'https://coincheck.jp/api/ticker'
        else:
            # for future, access to a demo account.
            pass

        self.heartbeat = heartbeat

        self.client = requests.Session()

    def start(self, **params):
        """ Starts the stream with the given parameters """
        self.connected = True

        request_args = {}

        content_ = {'last':None,'bid':None,'volume':None,'ask':None,'low':None,'high':None}

        while self.connected:
            response = self.client.get(self.api_url, **request_args)
            content = response.content.decode('utf-8')
            content = json.loads(content)

            if response.status_code != 200:
                self.on_error(content)

            if any([content[key] != content_[key] for key in ['last', 'bid', 'volume', 'ask', 'low', 'high']]):
                self.on_success(content)
                content_ = content

            time.sleep(self.heartbeat)

    def on_success(self, content):
        """ Called when data is successfully retrieved from the stream """
        print(content)
        return True

    def on_error(self, content):
        """ Called when stream returns non-200 status code
        Override this to handle your streaming data.
        """
        self.connected = False
        return

""" Contains COINCHECK exception """
class CoincheckError(Exception):
    """ Generic error class, catches coincheck response errors
    """

    def __init__(self, status_code, error_response):
        msg = "COINCHECK API returned error code %s (%s) " % (status_code, error_response['error'])

        super(CoincheckError, self).__init__(msg)
<commit_msg>Implement some POST methods<commit_after># -*- coding: utf-8 -*-
""" COINCHECK API wrapper """

"""
AUTHOR: @jimako1989
GITHUB: github.com/jimako1989/coincheckpy
LICENSE: MIT
"""

import json,time,hmac,hashlib,requests

"""EndpointsMixin provides a mixin for the API instance """
class EndpointsMixin(object):

    """Public API"""
    def ticker(self, **params):
        """ Get a tick
        Docs: https://coincheck.jp/documents/exchange/api#ticker
        """
        endpoint = 'api/ticker'
        return self.request(endpoint, auth=False, params=params)

    def public_trades(self, **params):
        """ Get public trades
        Docs: https://coincheck.jp/documents/exchange/api#public-trades
        """
        endpoint = 'api/trades'
        return self.request(endpoint, auth=False, params=params)

    def order_book(self, **params):
        """ Get order books
        Docs: https://coincheck.jp/documents/exchange/api#order-book
        """
        endpoint = 'api/order_books'
        return self.request(endpoint, auth=False, params=params)

    """ Private API """
    """ Order """
    def order_new(self, pair, order_type, **params):
        """ Create a new order
        Docs: https://coincheck.jp/documents/exchange/api#order-new
        """
        params['pair'] = pair
        params['order_type'] = order_type
        endpoint = 'api/exchange/orders'
        return self.request(endpoint, params=params)

    def order_opens(self, **params):
        """ Get open orders
        Docs: https://coincheck.jp/documents/exchange/api#order-opens
        """
        endpoint = 'api/exchange/orders/opens'
        return self.request(endpoint, params=params)

    def order_cancel(self, order_id, **params):
        """ Cancel an order
        Docs: https://coincheck.jp/documents/exchange/api#order-cancel
        """
        params['id'] = order_id
        endpoint = 'api/exchange/orders/'+str(order_id)
        return self.request(endpoint, params=params)

    def order_transactions(self, **params):
        """ Get my transactions
        Docs: https://coincheck.jp/documents/exchange/api#order-transactions
        """
        endpoint = 'api/exchange/orders/transactions'
        return self.request(endpoint, params=params)

    """ Account """
    def account_balance(self, **params):
        """ Check the balance
        Docs: https://coincheck.jp/documents/exchange/api#account-balance
        """
        endpoint = 'api/accounts/balance'
        return self.request(endpoint, params=params)

    def account_sendmoney(self, address, amount, **params):
        """ Send money
        Docs: https://coincheck.jp/documents/exchange/api#account-sendmoney
        """
        params['address'] = address
        params['amount'] = amount
        endpoint = 'api/send_money'
        return self.request(endpoint,method='POST', params=params)

    def account_sends(self, currency, **params):
        """ Get the history of sent money
        Docs: https://coincheck.jp/documents/exchange/api#account-sends
        """
        params['currency'] = currency
        endpoint = 'api/send_money'
        return self.request(endpoint, params=params)

    def account_deposits(self, currency, **params):
        """ Get the history of deposit money
        Docs: https://coincheck.jp/documents/exchange/api#account-deposits
        """
        params['currency'] = currency
        endpoint = 'api/deposit_money'
        return self.request(endpoint, params=params)

    def account_deposits_fast(self, order_id, **params):
        """ Fast withdrawal
        Docs: https://coincheck.jp/documents/exchange/api#account-deposits-fast
        """
        params['id'] = order_id
        endpoint = 'api/deposit_money/'+str(order_id)+'/fast'
        return self.request(endpoint, method='POST', params=params)

    def account_info(self, **params):
        """ Get account info.
        Docs: https://coincheck.jp/documents/exchange/api#account-info
        """
        endpoint = 'api/accounts'
        return self.request(endpoint, params=params)

    """ Withdrawal """
    def bank_accounts(self, **params):
        """ Get bank accounts
        Docs: https://coincheck.jp/documents/exchange/api#bank-accounts
        """
        endpoint = 'api/bank_accounts'
        return self.request(endpoint, params=params)

    def bank_accounts_create(self, bank_name, branch_name, bank_account_type, number, name, **params):
        """ Create a bank account
        Docs: https://coincheck.jp/documents/exchange/api#bank-accounts-create
        """
        endpoint = 'api/bank_accounts'
        return self.request(endpoint, method='POST', params=params)

    def bank_accounts_destroy(self, bank_id, **params):
        """ Destroy a bank account
        Docs: https://coincheck.jp/documents/exchange/api#bank-accounts-destroy
        """
        endpoint = 'api/bank_accounts/'+str(bank_id)
        return self.request(endpoint, params=params)

    def withdraws(self, **params):
        """ Get the history of withdraws
        Docs: https://coincheck.jp/documents/exchange/api#withdraws
        """
        endpoint = 'api/withdraws'
        return self.request(endpoint, params=params)

    def withdraws_create(self, bank_account_id, amount, currency, is_fast=False, **params):
        """ Apply the withdrawal
        Docs: https://coincheck.jp/documents/exchange/api#withdraws-create
        """
        params['bank_account_id'] = bank_account_id
        params['amount'] = amount
        params['currency'] = currency
        params['is_fast'] = is_fast
        endpoint = 'api/withdraws'
        return self.request(endpoint, method='POST', params=params)

    def withdraws_destroy(self, withdrawal_id, **params):
        """ Destroy a withdrawal
        Docs: https://coincheck.jp/documents/exchange/api#withdraws-destroy
        """
        params['id'] = withdrawal_id
        endpoint = 'api/withdraws'+str(withdrawal_id)
        return self.request(endpoint, params=params)

    """ Borrow """
    def create_borrow(self, amount, currency, **params):
        """ Create a borrow
        Docs: https://coincheck.jp/documents/exchange/api#create-borrow
        """
        params['amount'] = amount
        params['currency'] = currency
        endpoint = 'api/lending/borrows'
        return self.request(endpoint, method='POST', params=params)

    def read_borrow_matches(self, **params):
        """ Get the list of borrows
        Docs: https://coincheck.jp/documents/exchange/api#read-borrow-matches
        """
        endpoint = 'api/lending/borrows/matches'
        return self.request(endpoint, params=params)

    def create_repay(self, repay_id, **params):
        """ Repayment
        Docs: https://coincheck.jp/documents/exchange/api#create-repay
        """
        params['id'] = repay_id
        endpoint = 'api/lending/borrows/'+str(repay_id)+'/repay'
        return self.request(endpoint, method='POST', params=params)

    """ Lend """
    def create_lend(self, amount, currency, **params):
        """ Create lend (=loan)
        Docs: https://coincheck.jp/documents/exchange/api#create-lend
        """
        params['amount'] = amount
        params['currency'] = currency
        endpoint = 'api/lending/lends'
        return self.request(endpoint, method='POST', params=params)

    def read_lend(self, **params):
        """ Get the list of lend (=loan)
        Docs: https://coincheck.jp/documents/exchange/api#read-lend
        """
        endpoint = 'api/lending/lends'
        return self.request(endpoint, params=params)

    def cancel_lend(self, loan_id, **params):
        """ Cancel a lend (=loan)
        Docs: https://coincheck.jp/documents/exchange/api#cancel-lend
        """
        params['id']=loan_id
        endpoint = 'api/lending/lends/'+str(loan_id)+'/cancel'
        return self.request(endpoint, method='POST', params=params)

    def read_lend_matches(self, **params):
        """ Get the list of used lend (=loan)
        Docs: https://coincheck.jp/documents/exchange/api#read-lend-matches
        """
        endpoint = 'api/lending/lends/matches'
        return self.request(endpoint, params=params)

""" Provides functionality for access to core COINCHECK API calls """

class API(EndpointsMixin, object):
    def __init__(self, environment='live', key=None, secret_key=None):
        """ Instantiates an instance of CoincheckPy's API wrapper """

        if environment == 'live':
            self.api_url = 'https://coincheck.jp'
        else:
            # for future, access to a demo account.
            pass

        self.key = key
        self.secret_key = secret_key.encode('utf-8')
        self.nonce = str(int(time.time()))

        self.client = requests.Session()

    def request(self, endpoint, method='GET', auth=True, params=None):
        """ Returns dict of response from Coincheck's open API """

        url = '%s/%s' % ( self.api_url, endpoint)

        request_args = {}

        method = method.lower()
        params = params or {}

        func = getattr(self.client, method)

        if method == 'get':
            request_args['headers'] = params
        else:
            request_args['data'] = params

        url_endpoint = ""
        if type(params) is dict:
            url_endpoint = "?"
        for tup in params.items():
            url_endpoint += str(tup[0]) + "=" + str(tup[1]) + "&"
        url += url_endpoint[:-1]

        if auth:
            message = (self.nonce + url).encode('utf-8')
            signature = hmac.new(self.secret_key, msg=message, digestmod=hashlib.sha256).hexdigest()

            headers = {"ACCESS-KEY":self.key,"ACCESS-NONCE":self.nonce,"ACCESS-SIGNATURE":signature}
            request_args['headers'].update(headers)

        try:
            response = func(url, **request_args)
        except requests.RequestException as e:
            print (str(e))
        content = response.content.decode('utf-8')

        content = json.loads(content)

        # error message
        if response.status_code >= 400:
            raise CoincheckError(response.status_code,content)

        return content

"""HTTPS Streaming"""
class Streamer():
    """ Provides functionality for HTTPS Streaming """

    def __init__(self, environment='live', heartbeat=1.0):
        """ Instantiates an instance of CoincheckPy's streaming API wrapper. """

        if environment == 'live':
            self.api_url = 'https://coincheck.jp/api/ticker'
        else:
            # for future, access to a demo account.
            pass

        self.heartbeat = heartbeat

        self.client = requests.Session()

    def start(self, **params):
        """ Starts the stream with the given parameters """
        self.connected = True

        request_args = {}

        content_ = {'last':None,'bid':None,'volume':None,'ask':None,'low':None,'high':None}

        while self.connected:
            response = self.client.get(self.api_url, **request_args)
            content = response.content.decode('utf-8')
            content = json.loads(content)

            if response.status_code != 200:
                self.on_error(content)

            if any([content[key] != content_[key] for key in ['last', 'bid', 'volume', 'ask', 'low', 'high']]):
                self.on_success(content)
                content_ = content

            time.sleep(self.heartbeat)

    def on_success(self, content):
        """ Called when data is successfully retrieved from the stream """
        print(content)
        return True

    def on_error(self, content):
        """ Called when stream returns non-200 status code
        Override this to handle your streaming data.
        """
        self.connected = False
        return

""" Contains COINCHECK exception """
class CoincheckError(Exception):
    """ Generic error class, catches coincheck response errors
    """

    def __init__(self, status_code, error_response):
        msg = "COINCHECK API returned error code %s (%s) " % (status_code, error_response['error'])

        super(CoincheckError, self).__init__(msg)
<|endoftext|>