From ec505d744f6eab3721a09db52998b1e895939804 Mon Sep 17 00:00:00 2001 From: Jinyoung Kim Date: Sat, 15 Dec 2018 00:14:14 +0900 Subject: [PATCH 1/8] add json before return b' postfix and It is raw string. after return json --- cnio_api.py | 52 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/cnio_api.py b/cnio_api.py index 458c44f..dc7135b 100644 --- a/cnio_api.py +++ b/cnio_api.py @@ -9,44 +9,75 @@ https://changenow.io/api/v1///?=&=... Read the docs at https://changenow.io/api/docs for more information. ''' - +import json import requests +import logging + + #import socketio #from aiohttp import web class cnio(): + config = None def __init__(self): - self.key = str() + self.key = str() self.api = "https://changenow.io/api/v1/" + def _get(self, url, headers=None, data=None, params=None): + req = requests.get(url, headers=headers, data=data, params=params) + if req.status_code not in [200, 201]: + logging.error('get(%s) failed(%d)' % (url, req.status_code)) + if req.text is not None: + logging.error('req: %s' % req.text) + raise Exception('request.get() failed(%s)' % req.text) + raise Exception( + 'request.get() failed(status_code:%d)' % req.status_code) + return json.loads(req.text) + + def _post(self, url, headers=None, data=None): + req = requests.post(url, headers=headers, data=data) + if req.status_code not in [200, 201]: + logging.error('post(%s) failed(%d)' % (url, req.status_code)) + if req.text is not None: + raise Exception('request.post() failed(%s)' % req.text) + raise Exception( + 'request.post() failed(status_code:%d)' % req.status_code) + return json.loads(req.text) + + + def get_pair(self): + query = str('/market-info/available-pairs/') + endpoint = str(self.api + query) + return self._get(url=endpoint) + def currencies(self, active): # this method returns the list of supported currencies # use optional param "active" to get only currently active currencies. This should be provided as a bool value query = str("?active=" + str(active)) endpoint = "currencies" endpoint = str(self.api + endpoint + query) - return requests.get(url=endpoint).content + return self._get(url=endpoint) def min_amount(self, send, receive): # this method returns the minimum amount required to make an exchange. # you MUST provide the currency pair that you are looking to trade endpoint = str("min-amount/" + send + "_" + receive) endpoint = str(self.api + endpoint) - return requests.get(endpoint).content + return self._get(endpoint) def est_exchange_rate(self, send_amount, send, receive): # this method returns the amount of currency you will get for the provided amount of currency # you MUST provide the amount you intend to send, the currency to be sent and the currency to be recieved endpoint = str("exchange-amount/" + str(send_amount) + "/" + send + "_" + receive) endpoint = str(self.api + endpoint) - return requests.get(endpoint).content + return self._get(endpoint) def isitscam(self, url): # this endpoint just checks if the provided crypto site URL is valid or some type of scam # I am not sure how accurate the returned information will be endpoint = str("scam-check/" + url) endpoint = str(self.api + endpoint) - return requests.get(endpoint).content + return self._get(endpoint) # use this method to set an API key to work with for the duration of the instance # call it before calling any methods that require an API key @@ -63,7 +94,7 @@ def create_transaction(self, send_amount, send, receive, addr, extra_id=""): "&amount=" + str(send_amount) + "&extraId=" + extra_id) endpoint = str("transactions/" + self.key) endpoint = str(self.api + endpoint + query) - return requests.post(endpoint).content + return self._post(endpoint) def list_transactions(self, send="", receive="", status="", limit="", offset=""): # this method returns a list of transactions that were started using the API key @@ -75,14 +106,14 @@ def list_transactions(self, send="", receive="", status="", limit="", offset="") query = str("?from=" + send + "&to=" + receive + "&status=" + status + "&limit=" + limit + "&offset=" + offset) endpoint = str("transactions/" + self.key) endpoint = str(self.api + endpoint + query) - return requests.get(endpoint).content + return self._get(endpoint) def get_transaction_status(self, cnio_transaction_id): # this method returns the transaction status of a transaction. A transaction id # from list_transactions() or create_transaction() MUST be provided. endpoint = str("transactions/" + cnio_transaction_id + "/" + self.key) endpoint = str(self.api + endpoint) - return requests.get(endpoint).content + return self._get(endpoint) ''' def live_tx_updates_socketio(self): @@ -90,6 +121,3 @@ def live_tx_updates_socketio(self): # you are probably going to need to call this on a separate thread # TODO: implement sockets.io connection and data subscription ''' - -if __name__ != '__main__': - cnio() From bef31ded951e7a6dc3c605f6890ba6f1eb1712c2 Mon Sep 17 00:00:00 2001 From: Jinyoung Kim Date: Sat, 15 Dec 2018 00:15:33 +0900 Subject: [PATCH 2/8] remove whitespace --- cnio_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cnio_api.py b/cnio_api.py index dc7135b..296e8d8 100644 --- a/cnio_api.py +++ b/cnio_api.py @@ -20,7 +20,7 @@ class cnio(): config = None def __init__(self): - self.key = str() + self.key = str() self.api = "https://changenow.io/api/v1/" def _get(self, url, headers=None, data=None, params=None): From 1db778f2413559f89f758f5c6e78f0804b5fba38 Mon Sep 17 00:00:00 2001 From: Jinyoung Kim Date: Sat, 15 Dec 2018 00:16:56 +0900 Subject: [PATCH 3/8] Update cnio_api.py --- cnio_api.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cnio_api.py b/cnio_api.py index 296e8d8..889aae6 100644 --- a/cnio_api.py +++ b/cnio_api.py @@ -18,7 +18,6 @@ #from aiohttp import web class cnio(): - config = None def __init__(self): self.key = str() self.api = "https://changenow.io/api/v1/" @@ -121,3 +120,6 @@ def live_tx_updates_socketio(self): # you are probably going to need to call this on a separate thread # TODO: implement sockets.io connection and data subscription ''' + +if __name__ != '__main__': + cnio() From 2f646e24fcb2939c5ac70e567d3aaa467ebe483b Mon Sep 17 00:00:00 2001 From: mister-monster <38917788+mister-monster@users.noreply.github.com> Date: Wed, 10 Jul 2019 13:04:06 -0500 Subject: [PATCH 4/8] added tests for new endpoints Also removed string parsing for the transaction status list since JSON is handled in the API now. --- test.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/test.py b/test.py index 9d74242..7a52cc3 100644 --- a/test.py +++ b/test.py @@ -1,12 +1,11 @@ import cnio_api -import json import time cnio = cnio_api.cnio() # test parameters -key = str() -recieve_address = str() +key = str("baa822014e8c99942f6afbacbc52ec23b43ffabc768f33a2ad2e65d24675355d") +recieve_address = str("0x5736db83d42a64C278ECe5D61C8bA8A821A76785") extra_id = None # set the API key for the cnio_api instance for all methods that need it @@ -23,9 +22,14 @@ print(cnio.min_amount("BTC", "ETH")) print("===") # -print(cnio.currencies(active=True)) +print(cnio.currencies(active=True, fixed_rate=False)) print("===") # +print(cnio.currencies_to(ticker="btc", fixed_rate=False)) +print("===") +# +print(cnio.specific_currency_info(ticker="btc")) +# print(cnio.est_exchange_rate("1","BTC","ETH")) print("===") # @@ -41,12 +45,7 @@ print(transactions_list) print("===") -transactions_list = str(transactions_list).replace("b'[","") -transactions_list = transactions_list.replace("]'","") -transactions_list = transactions_list.replace("},{","} , {") -transactions_list = transactions_list.split(" , ") + for i in transactions_list: - i = json.loads(i) - # print(cnio.get_transaction_status(i["id"])) time.sleep(1) From 816910c23a940a61a65de30b728c95c5f733ea96 Mon Sep 17 00:00:00 2001 From: mister-monster <38917788+mister-monster@users.noreply.github.com> Date: Wed, 10 Jul 2019 13:06:52 -0500 Subject: [PATCH 5/8] added fixed rate methods, new endpoints Added endpoints for specific currency info, currency specific trade pairs (currencies-to), added fixed rate transaction methods. --- cnio_api.py | 81 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 25 deletions(-) diff --git a/cnio_api.py b/cnio_api.py index 889aae6..0120c76 100644 --- a/cnio_api.py +++ b/cnio_api.py @@ -13,10 +13,6 @@ import requests import logging - -#import socketio -#from aiohttp import web - class cnio(): def __init__(self): self.key = str() @@ -43,20 +39,33 @@ def _post(self, url, headers=None, data=None): 'request.post() failed(status_code:%d)' % req.status_code) return json.loads(req.text) - def get_pair(self): - query = str('/market-info/available-pairs/') - endpoint = str(self.api + query) + endpoint = str('/market-info/available-pairs/') + endpoint = str(self.api + endpoint) return self._get(url=endpoint) - def currencies(self, active): + def currencies(self, active, fixed_rate): # this method returns the list of supported currencies - # use optional param "active" to get only currently active currencies. This should be provided as a bool value - query = str("?active=" + str(active)) + # Both params should be provided as a bool value + query = str("?active=" + str(active) + "&fixedRate=" + str(fixed_rate)) endpoint = "currencies" endpoint = str(self.api + endpoint + query) return self._get(url=endpoint) + def currencies_to(self, ticker, fixed_rate): + # this method returns a list of currencies that have trade pairs with the provided currency ticker + # query param "fixed_rate" should be provided as a bool value + query = str("?fixedRate=" + str(fixed_rate)) + endpoint = str("currencies-to/" + ticker) + endpoint = str(self.api + endpoint + query) + return self._get(url=endpoint) + + def specific_currency_info(self, ticker): + # this method returns information on a specific currency + endpoint = str("currencies/" + ticker) + endpoint = str(self.api + endpoint) + return self._get(url=endpoint) + def min_amount(self, send, receive): # this method returns the minimum amount required to make an exchange. # you MUST provide the currency pair that you are looking to trade @@ -84,17 +93,52 @@ def api_key(self, key): self.key = key # ALL OF THE FOLLOWING ENDPOINTS REQUIRE PROVISION OF AN API KEY - def create_transaction(self, send_amount, send, receive, addr, extra_id=""): + # THE FOLLOWING ARE STANDARD FLOW (VARIABLE RATE NO LIMIT) API ENDPOINTS + def create_transaction(self, send_amount, send, receive, addr, extra_id="", refund_address=""): # this endpoint creates a transaction # You must provide quite a bit of information. namely, send currency, recieve currency # the address you want the recieve currency sent to, the amount you will send, # and an "extra ID" for currencies that need it (eg. transaction ID for XMP) query = str("?from=" + send + "&to=" + receive + "&address=" + addr + - "&amount=" + str(send_amount) + "&extraId=" + extra_id) + "&amount=" + str(send_amount) + "&extraId=" + extra_id + "&refundAddress=" + refund_address) endpoint = str("transactions/" + self.key) endpoint = str(self.api + endpoint + query) return self._post(endpoint) + # THE FOLLOWING ARE THE FIXED RATE API ENDPOINTS + def available_fixed_markets(self): + # this method returns the available keypairs that can be exchanged at a fixed rate + endpoint = str("market-info/fixed-rate/" + self.key) + endpoint = str(self.api + endpoint) + return self._get(endpoint) + + def estimate_fixed_rate_exchange_amount(self, send_amount, send, receive): + # this method returns the amount of currency you will get for the provided amount of currency + # you MUST provide the amount you intend to send, the currency to be sent and the currency to be recieved + query = str("?api_key=" + self.key) + endpoint = str("exchange-amount/fixed_rate/" + str(send_amount) + "/" + send + "_" + receive) + endpoint = str(self.api + endpoint + query) + return self._get(endpoint) + + def create_fixed_rate_transaction(self, send_amount, send, receive, addr, extra_id="", refund_address=""): + # this endpoint creates a transaction + # You must provide quite a bit of information. namely, send currency, recieve currency + # the address you want the recieve currency sent to, the amount you will send, + # and an "extra ID" for currencies that need it (eg. transaction ID for XMP) + query = str("?from=" + send + "&to=" + receive + "&address=" + addr + + "&amount=" + str(send_amount) + "&extraId=" + extra_id + "&refundAddress=" + refund_address) + endpoint = str("transactions/fixed_rate/" + self.key) + endpoint = str(self.api + endpoint + query) + return self._post(endpoint) + + # THE FOLLOWING CAN BE USED FOR VARIABLE AND FIXED RATE TRANSACTIONS + def get_transaction_status(self, cnio_transaction_id): + # this method returns the transaction status of a transaction. A transaction id + # from list_transactions() or create_transaction() MUST be provided. + endpoint = str("transactions/" + cnio_transaction_id + "/" + self.key) + endpoint = str(self.api + endpoint) + return self._get(endpoint) + def list_transactions(self, send="", receive="", status="", limit="", offset=""): # this method returns a list of transactions that were started using the API key # All query parameters are optional, they are: sent currency, recieved currency, transaction status (for a @@ -107,19 +151,6 @@ def list_transactions(self, send="", receive="", status="", limit="", offset="") endpoint = str(self.api + endpoint + query) return self._get(endpoint) - def get_transaction_status(self, cnio_transaction_id): - # this method returns the transaction status of a transaction. A transaction id - # from list_transactions() or create_transaction() MUST be provided. - endpoint = str("transactions/" + cnio_transaction_id + "/" + self.key) - endpoint = str(self.api + endpoint) - return self._get(endpoint) - -''' - def live_tx_updates_socketio(self): - # this method interfaces with the socket.io websockets endpoint and gets live transaction updates - # you are probably going to need to call this on a separate thread - # TODO: implement sockets.io connection and data subscription -''' if __name__ != '__main__': cnio() From 7edd7362bd13b0f7a6227acc15cb4fbee46ed556 Mon Sep 17 00:00:00 2001 From: mister-monster <38917788+mister-monster@users.noreply.github.com> Date: Wed, 10 Jul 2019 13:07:17 -0500 Subject: [PATCH 6/8] Update test.py --- test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test.py b/test.py index 7a52cc3..fa56630 100644 --- a/test.py +++ b/test.py @@ -4,8 +4,8 @@ cnio = cnio_api.cnio() # test parameters -key = str("baa822014e8c99942f6afbacbc52ec23b43ffabc768f33a2ad2e65d24675355d") -recieve_address = str("0x5736db83d42a64C278ECe5D61C8bA8A821A76785") +key = str() +recieve_address = str() extra_id = None # set the API key for the cnio_api instance for all methods that need it From 31cd088f78d808101cb862d4b0e5306c40c8587e Mon Sep 17 00:00:00 2001 From: mister-monster <38917788+mister-monster@users.noreply.github.com> Date: Sat, 28 Sep 2019 10:17:39 -0500 Subject: [PATCH 7/8] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 47d2c79..14b7b22 100644 --- a/README.md +++ b/README.md @@ -7,4 +7,4 @@ a query url to the api looks like this: "https://changenow.io/api/v1/endpoint/param1/param2?=&=..." Read the docs at https://changenow.io/api/docs for more information. -This module depends on requests, socketio and aiohttp. +This module depends on requests, json and logging Python modules from the standard library. From 6f4fead536e20c2018affda88d0b7bab875dbaac Mon Sep 17 00:00:00 2001 From: mister-monster <38917788+mister-monster@users.noreply.github.com> Date: Mon, 6 Sep 2021 16:15:55 -0400 Subject: [PATCH 8/8] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 14b7b22..13e5ac6 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +DEPRACATED: changenow.io now maintains a python library that provides this functionality and is kept up to date with API changes. It can be found here https://gitlab.com/changenow-s-library-catalogue/changenow-api-python and it is recommended to use this library rather than mine. + +This repository will no longer be maintained. + # cnio-api-py This library passes requests to the changenow.io API located at https://changenow.io/api/v1 (version hardcoded for now) Every API endpoint must be called using a PHP style http_build_query, and returns a JSON object