From d04c87f996c64dceb1546cd6e1a34b8ebc98df2e Mon Sep 17 00:00:00 2001 From: Gabriel Baldao Date: Wed, 19 Feb 2020 17:22:39 -0300 Subject: [PATCH 01/21] initial structure, client and auth class --- src/omnitrade_api/auth.py | 31 +++++++++++++++++++++ src/omnitrade_api/client.py | 54 +++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 src/omnitrade_api/auth.py create mode 100644 src/omnitrade_api/client.py diff --git a/src/omnitrade_api/auth.py b/src/omnitrade_api/auth.py new file mode 100644 index 0000000..053177b --- /dev/null +++ b/src/omnitrade_api/auth.py @@ -0,0 +1,31 @@ +import hashlib +import time +import urllib + +class Auth(object): + def __init__(self, access_key, secret_key): + self.access_key = access_key + self.secret_key = secret_key + + def signed_challenge(self, challenge): + signature = hashlib.pbkdf2_hmac('sha256', self.secret_key,"{access_key}{challenge}".format(access_key = self.access_key, challenge = challenge), 100000 ) + + return { 'auth': { 'access_key': self.access_key, 'answer': signature } } + + def signed_params(self, verb, path, params = {}): + params = self.format_params(params) + signature = self.sign(verb, path, params)#urllib.unquote(params.to_query)) + signature = 'asdasdasdas' + params['signature'] = signature + return params + + def sign(self, verb, path, params): + return hashlib.pbkdf2_hmac('sha256', self.secret_key, self.payload(verb, path, params), 100000) + + def payload(self, verb, path, params): + return "#{verb}|#{path}|#{params}".format(verb = verb.upper(), path = path, params = params) + + def format_params(self, params): + params['access_key'] = self.access_key + params['tonce'] = int(time.time()) * 1000 + return params diff --git a/src/omnitrade_api/client.py b/src/omnitrade_api/client.py new file mode 100644 index 0000000..b71eb0c --- /dev/null +++ b/src/omnitrade_api/client.py @@ -0,0 +1,54 @@ +import requests +import json +from auth import Auth + +OMNITRADE_URL = 'https://omnitrade.io' +class Client(object): + def __init__(self, options={}): + global OMNITRADE_URL + self.setup_auth_keys(options) + + self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else OMNITRADE_URL + self.timeout = options['timeout'] if 'timeout' in options.keys() else 60 + + def get_public(self, path, params={}): + uri = self.parameters('GET',path, params) + + return self.get_request(uri, params) + + + def get(self, path, params={}): + self.check_auth() + + uri, params = self.parameters('GET',path, params) + return self.get_request(uri, params) + + def post(self, path, params={}): + self.check_auth() + + uri, params = self.parameters('POST', path, params) + return self.post_request(uri, params) + + def setup_auth_keys(self, options): + if not('access_key' in options.keys() and 'secret_key' in options.keys()): + return + + self.access_key = options['access_key'] + self.secret_key = options['secret_key'] + self.auth = Auth(self.access_key, self.secret_key) + + + def check_auth(self): + if self.auth == None: + raise Exception('Missing access key and/or secret key') + + def get_request(self, uri, params): + return requests.get(uri,data = params).json() + + def post_request(self, uri, params): + return requests.post(uri,data = params).json() + + def parameters(self, action, path, params): + uri = '{endpoint}{path}'.format(endpoint=self.endpoint, path=path) + params = self.auth.signed_params(action, path, params) if self.auth else params + return uri, params From 4f9e27d2b9b090d796949667b6c11960d8df6631 Mon Sep 17 00:00:00 2001 From: Gabriel Baldao Date: Thu, 20 Feb 2020 11:32:21 -0300 Subject: [PATCH 02/21] ordering parameters --- src/omnitrade_api/auth.py | 6 +++--- src/omnitrade_api/client.py | 19 ++++++++++++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/omnitrade_api/auth.py b/src/omnitrade_api/auth.py index 053177b..98b1e08 100644 --- a/src/omnitrade_api/auth.py +++ b/src/omnitrade_api/auth.py @@ -14,9 +14,9 @@ def signed_challenge(self, challenge): def signed_params(self, verb, path, params = {}): params = self.format_params(params) - signature = self.sign(verb, path, params)#urllib.unquote(params.to_query)) - signature = 'asdasdasdas' - params['signature'] = signature + + signature = self.sign(verb, path, urllib.urlencode(params)) + params['signature'] = signature #TODO FIX THIS SIGNATURE return params def sign(self, verb, path, params): diff --git a/src/omnitrade_api/client.py b/src/omnitrade_api/client.py index b71eb0c..5e44034 100644 --- a/src/omnitrade_api/client.py +++ b/src/omnitrade_api/client.py @@ -1,18 +1,21 @@ import requests import json +import urllib +from collections import OrderedDict from auth import Auth OMNITRADE_URL = 'https://omnitrade.io' class Client(object): def __init__(self, options={}): global OMNITRADE_URL + self.auth = None self.setup_auth_keys(options) self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else OMNITRADE_URL self.timeout = options['timeout'] if 'timeout' in options.keys() else 60 def get_public(self, path, params={}): - uri = self.parameters('GET',path, params) + uri, params = self.parameters('GET',path, params) return self.get_request(uri, params) @@ -43,12 +46,18 @@ def check_auth(self): raise Exception('Missing access key and/or secret key') def get_request(self, uri, params): - return requests.get(uri,data = params).json() + return requests.get(uri, params = urllib.urlencode(params)) def post_request(self, uri, params): - return requests.post(uri,data = params).json() + return requests.post(uri, params = json.dumps(params)) def parameters(self, action, path, params): uri = '{endpoint}{path}'.format(endpoint=self.endpoint, path=path) - params = self.auth.signed_params(action, path, params) if self.auth else params - return uri, params + dict_params = self.auth.signed_params(action, path, params) if self.auth != None else params + list_params = map(lambda key,value: (key, value), dict_params.keys(), dict_params.values()) + list_params.sort(key=self.take_key) + + return uri, list_params + + def take_key(self, item): + return item[0] From 15798801ee1a71c4afccddbeba8488cff93caa59 Mon Sep 17 00:00:00 2001 From: Gabriel Baldao Date: Thu, 20 Feb 2020 16:24:58 -0300 Subject: [PATCH 03/21] set private methods --- src/omnitrade_api/auth.py | 14 ++++++------ src/omnitrade_api/client.py | 43 +++++++++++++++++-------------------- 2 files changed, 27 insertions(+), 30 deletions(-) diff --git a/src/omnitrade_api/auth.py b/src/omnitrade_api/auth.py index 98b1e08..436c2a6 100644 --- a/src/omnitrade_api/auth.py +++ b/src/omnitrade_api/auth.py @@ -13,19 +13,19 @@ def signed_challenge(self, challenge): return { 'auth': { 'access_key': self.access_key, 'answer': signature } } def signed_params(self, verb, path, params = {}): - params = self.format_params(params) + params = self.__format_params(params) - signature = self.sign(verb, path, urllib.urlencode(params)) + signature = self.__sign(verb, path, urllib.urlencode(params)) params['signature'] = signature #TODO FIX THIS SIGNATURE return params - def sign(self, verb, path, params): - return hashlib.pbkdf2_hmac('sha256', self.secret_key, self.payload(verb, path, params), 100000) + def __sign(self, verb, path, params): + return hashlib.pbkdf2_hmac('sha256', self.secret_key, self.__payload(verb, path, params), 100000) - def payload(self, verb, path, params): + def __payload(self, verb, path, params): return "#{verb}|#{path}|#{params}".format(verb = verb.upper(), path = path, params = params) - def format_params(self, params): + def __format_params(self, params): params['access_key'] = self.access_key - params['tonce'] = int(time.time()) * 1000 + params['tonce'] = int(time.time()) * 10000 return params diff --git a/src/omnitrade_api/client.py b/src/omnitrade_api/client.py index 5e44034..d16a26c 100644 --- a/src/omnitrade_api/client.py +++ b/src/omnitrade_api/client.py @@ -1,38 +1,38 @@ import requests import json import urllib -from collections import OrderedDict from auth import Auth +from ordered_dict import ordered_dict -OMNITRADE_URL = 'https://omnitrade.io' +OMNITRADE_URL = 'http://localhost:5000/' #'https://omnitrade.io' class Client(object): def __init__(self, options={}): global OMNITRADE_URL self.auth = None - self.setup_auth_keys(options) + self.__setup_auth_keys(options) - self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else OMNITRADE_URL - self.timeout = options['timeout'] if 'timeout' in options.keys() else 60 + self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else OMNITRADE_URL + self.timeout = options['timeout'] if 'timeout' in options.keys() else 60 def get_public(self, path, params={}): - uri, params = self.parameters('GET',path, params) + uri, params = self.__parameters('GET',path, params) - return self.get_request(uri, params) + return self.__get_request(uri, params) def get(self, path, params={}): - self.check_auth() + self.__check_auth() - uri, params = self.parameters('GET',path, params) - return self.get_request(uri, params) + uri, params = self.__parameters('GET',path, params) + return self.__get_request(uri, params) def post(self, path, params={}): - self.check_auth() + self.__check_auth() - uri, params = self.parameters('POST', path, params) - return self.post_request(uri, params) + uri, params = self.__parameters('POST', path, params) + return self.__post_request(uri, params) - def setup_auth_keys(self, options): + def __setup_auth_keys(self, options): if not('access_key' in options.keys() and 'secret_key' in options.keys()): return @@ -41,23 +41,20 @@ def setup_auth_keys(self, options): self.auth = Auth(self.access_key, self.secret_key) - def check_auth(self): + def __check_auth(self): if self.auth == None: raise Exception('Missing access key and/or secret key') - def get_request(self, uri, params): + def __get_request(self, uri, params): return requests.get(uri, params = urllib.urlencode(params)) - def post_request(self, uri, params): + def __post_request(self, uri, params): return requests.post(uri, params = json.dumps(params)) - def parameters(self, action, path, params): + def __parameters(self, action, path, params): uri = '{endpoint}{path}'.format(endpoint=self.endpoint, path=path) dict_params = self.auth.signed_params(action, path, params) if self.auth != None else params - list_params = map(lambda key,value: (key, value), dict_params.keys(), dict_params.values()) - list_params.sort(key=self.take_key) - return uri, list_params + return uri, ordered_dict(dict_params) - def take_key(self, item): - return item[0] + From 05f22367401d41cc89a3555fa026ada7f74e1d83 Mon Sep 17 00:00:00 2001 From: Gabriel Baldao Date: Thu, 20 Feb 2020 17:12:53 -0300 Subject: [PATCH 04/21] start write specs and start write streaming client --- src/omnitrade_api/__init__.py | 24 ++++++++++++++ src/omnitrade_api/ordered_dict.py | 8 +++++ src/omnitrade_api/streaming_client.py | 45 +++++++++++++++++++++++++++ src/tests/test_auth.py | 20 ++++++++++++ src/tests/test_client.py | 18 +++++++++++ src/tests/test_ordered_dict.py | 10 ++++++ 6 files changed, 125 insertions(+) create mode 100644 src/omnitrade_api/__init__.py create mode 100644 src/omnitrade_api/ordered_dict.py create mode 100644 src/omnitrade_api/streaming_client.py create mode 100644 src/tests/test_auth.py create mode 100644 src/tests/test_client.py create mode 100644 src/tests/test_ordered_dict.py diff --git a/src/omnitrade_api/__init__.py b/src/omnitrade_api/__init__.py new file mode 100644 index 0000000..878c53c --- /dev/null +++ b/src/omnitrade_api/__init__.py @@ -0,0 +1,24 @@ +from client import Client +import json + + +cl = Client() +# print(type(cl)) +# print(json.dumps(cl.get_public('/api/v2/markets'))) +access_key = 'FUkESEYRJmO42MfqXcgJfm73GfIMw61qogExtcX7' + +cl1 = Client({'access_key': access_key,'secret_key': '123456'}) +# print(cl1.get('api/v2/markets', {'market': 'btcbrl','price': '10','side': 'buy','tonce': 123,'volume': 1}).url) +# print(cl1.get('api/v2/markets', {'market': 'btcbrl','price': '10','side': 'buy','tonce': 123,'volume': 1}).json()) +# order = { +# 'total': 10, +# 'type': "bid", +# 'volume': 10 +# } + +# print(cl.get_public('/api/v2/order_markets', order).url) +# print(cl.get_public('/api/v2/order_markets', order).json()) +# # print(cl1.get('api/v2/orders/multi', {'market': 'btcbrl','price': '10','side': 'buy','tonce': 123,'volume': 1}).url) + + + diff --git a/src/omnitrade_api/ordered_dict.py b/src/omnitrade_api/ordered_dict.py new file mode 100644 index 0000000..292a903 --- /dev/null +++ b/src/omnitrade_api/ordered_dict.py @@ -0,0 +1,8 @@ +def ordered_dict(dict_params): + params = map(lambda key,value: (key, value), dict_params.keys(), dict_params.values()) + params.sort(key=take_key) + + return params + +def take_key(item): + return item[0] diff --git a/src/omnitrade_api/streaming_client.py b/src/omnitrade_api/streaming_client.py new file mode 100644 index 0000000..c0594c1 --- /dev/null +++ b/src/omnitrade_api/streaming_client.py @@ -0,0 +1,45 @@ +import websocket +try: + import thread +except ImportError: + import _thread as thread +import time +from client import Client + +class StreamingClient(Client): + def __init__(self, options = {}): + # super + self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else 'wss://omnitrade.com:8080' + self.logger = options['logger'] if 'logger' in options.keys() else 'Logger' #Logger(STDOUT) + websocket.enableTrace(True) + self.ws = websocket.WebSocketApp("ws://localhost:8765/", + on_message = self.on_message, + on_error = self.on_error, + on_close = self.on_close) + self.ws.on_open = self.on_open + self.ws.run_forever() + + def on_message(self, message): + print(message) + + def on_error(self, error): + print(error) + + def on_close(self): + print("### closed ###") + + def on_open(self): + def run(*args): + for i in range(3): + time.sleep(1) + self.ws.send("Hello %d" % i) + time.sleep(1) + # self.ws.close() + print("thread terminating...") + thread.start_new_thread(run, ()) + + + +sc = StreamingClient({'endpoint': 'ws://localhost:8765'}) +sc.on_message('asd') + diff --git a/src/tests/test_auth.py b/src/tests/test_auth.py new file mode 100644 index 0000000..a56a37c --- /dev/null +++ b/src/tests/test_auth.py @@ -0,0 +1,20 @@ +import unittest +from omnitrade_api.auth import Auth + +ACCESS_KEY = '123456' +SECRET_KEY = '123456' +class TestAuthMethods(unittest.TestCase): + def test_signed_challenge(self): + auth = Auth(ACCESS_KEY, SECRET_KEY) + + subject = auth.signed_challenge('challenge') + + self.assertEqual(subject.keys(), ['auth']) + self.assertEqual(subject['auth'].keys(), ['access_key', 'answer']) + + def test_signed_params(self): + auth = Auth(ACCESS_KEY, SECRET_KEY) + + subject = auth.signed_params('GET', 'api/v2/order_markets', { "volume": 0, "total": 0 }) + + self.assertEqual(subject.keys(), ['volume', 'access_key', 'tonce', 'total', 'signature']) diff --git a/src/tests/test_client.py b/src/tests/test_client.py new file mode 100644 index 0000000..ce3f046 --- /dev/null +++ b/src/tests/test_client.py @@ -0,0 +1,18 @@ +import unittest +import json +from nose.tools import assert_is_none, assert_list_equal +from mock import patch, Mock + +from omnitrade_api.client import Client + +OMNITRADE_URL = 'https://omnitrade.io' +class TestClientMethods(unittest.TestCase): + + def test_get_public_valid_request(self): + public_client = Client() + market_path = '/api/v2/markets' + markets = [{"id": "btcbrl", "name": "BTC/BRL"}, {"id": "ltcbrl", "name": "LTC/BRL"}, {"id": "bchbrl", "name": "BCH/BRL"}, {"id": "btgbrl", "name": "BTG/BRL"}, {"id": "ethbrl", "name": "ETH/BRL"}, {"id": "dashbrl", "name": "DASH/BRL"}, {"id": "dcrbrl", "name": "DCR/BRL"}, {"id": "ltcbtc", "name": "LTC/BTC"}, {"id": "bchbtc", "name": "BCH/BTC"}, {"id": "btgbtc", "name": "BTG/BTC"}, {"id": "ethbtc", "name": "ETH/BTC"}, {"id": "dashbtc", "name": "DASH/BTC"}, {"id": "dcrbtc", "name": "DCR/BTC"}, {"id": "ltceth", "name": "LTC/ETH"}, {"id": "bcheth", "name": "BCH/ETH"}, {"id": "btgeth", "name": "BTG/ETH"}, {"id": "dasheth", "name": "DASH/ETH"}, {"id": "dcreth", "name": "DCR/ETH"}, {"id": "xrpbrl", "name": "XRP/BRL"}, {"id": "xrpbtc", "name": "XRP/BTC"}, {"id": "xrpeth", "name": "XRP/ETH"}, {"id": "mftbrl", "name": "MFT/BRL"}, {"id": "mftbtc", "name": "MFT/BTC"}, {"id": "mfteth", "name": "MFT/ETH"}, {"id": "btcusdc", "name": "BTC/USDC"}, {"id": "ltcusdc", "name": "LTC/USDC"}, {"id": "bchusdc", "name": "BCH/USDC"}, {"id": "btgusdc", "name": "BTG/USDC"}, {"id": "ethusdc", "name": "ETH/USDC"}, {"id": "dashusdc", "name": "DASH/USDC"}, {"id": "dcrusdc", "name": "DCR/USDC"}, {"id": "xrpusdc", "name": "XRP/USDC"}, {"id": "bnbbtc", "name": "BNB/BTC"}, {"id": "bnbusdc", "name": "BNB/USDC"}] + + response = public_client.get_public(market_path) + + self.assertEqual(response.json(), markets) diff --git a/src/tests/test_ordered_dict.py b/src/tests/test_ordered_dict.py new file mode 100644 index 0000000..3d5a9e2 --- /dev/null +++ b/src/tests/test_ordered_dict.py @@ -0,0 +1,10 @@ +import unittest +from omnitrade_api.ordered_dict import ordered_dict + +class TestOrderedDictMethods(unittest.TestCase): + + def test_ordered_dict(self): + dictionary = { 'a': 1, 'b': 2, 'c': 3} + + self.assertEqual(ordered_dict(dictionary), [('a', 1),('b', 2),('c', 3)]) + From 88a4fff9db997c857f6c5cbcc8c84d6346c7bb5a Mon Sep 17 00:00:00 2001 From: Gabriel Baldao Date: Thu, 20 Feb 2020 17:23:08 -0300 Subject: [PATCH 05/21] fix url --- src/omnitrade_api/client.py | 2 +- src/omnitrade_api/streaming_client.py | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/omnitrade_api/client.py b/src/omnitrade_api/client.py index d16a26c..cce0158 100644 --- a/src/omnitrade_api/client.py +++ b/src/omnitrade_api/client.py @@ -4,7 +4,7 @@ from auth import Auth from ordered_dict import ordered_dict -OMNITRADE_URL = 'http://localhost:5000/' #'https://omnitrade.io' +OMNITRADE_URL = 'https://omnitrade.io' class Client(object): def __init__(self, options={}): global OMNITRADE_URL diff --git a/src/omnitrade_api/streaming_client.py b/src/omnitrade_api/streaming_client.py index c0594c1..d8b13d0 100644 --- a/src/omnitrade_api/streaming_client.py +++ b/src/omnitrade_api/streaming_client.py @@ -12,7 +12,7 @@ def __init__(self, options = {}): self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else 'wss://omnitrade.com:8080' self.logger = options['logger'] if 'logger' in options.keys() else 'Logger' #Logger(STDOUT) websocket.enableTrace(True) - self.ws = websocket.WebSocketApp("ws://localhost:8765/", + self.ws = websocket.WebSocketApp(self.endpoint, on_message = self.on_message, on_error = self.on_error, on_close = self.on_close) @@ -39,7 +39,3 @@ def run(*args): thread.start_new_thread(run, ()) - -sc = StreamingClient({'endpoint': 'ws://localhost:8765'}) -sc.on_message('asd') - From fcc9b069b82d0e17a91a35f59771426ea73c1706 Mon Sep 17 00:00:00 2001 From: Gabriel Baldao Date: Thu, 20 Feb 2020 17:32:08 -0300 Subject: [PATCH 06/21] removing current __init__ py --- src/omnitrade_api/__init__.py | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 src/omnitrade_api/__init__.py diff --git a/src/omnitrade_api/__init__.py b/src/omnitrade_api/__init__.py deleted file mode 100644 index 878c53c..0000000 --- a/src/omnitrade_api/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -from client import Client -import json - - -cl = Client() -# print(type(cl)) -# print(json.dumps(cl.get_public('/api/v2/markets'))) -access_key = 'FUkESEYRJmO42MfqXcgJfm73GfIMw61qogExtcX7' - -cl1 = Client({'access_key': access_key,'secret_key': '123456'}) -# print(cl1.get('api/v2/markets', {'market': 'btcbrl','price': '10','side': 'buy','tonce': 123,'volume': 1}).url) -# print(cl1.get('api/v2/markets', {'market': 'btcbrl','price': '10','side': 'buy','tonce': 123,'volume': 1}).json()) -# order = { -# 'total': 10, -# 'type': "bid", -# 'volume': 10 -# } - -# print(cl.get_public('/api/v2/order_markets', order).url) -# print(cl.get_public('/api/v2/order_markets', order).json()) -# # print(cl1.get('api/v2/orders/multi', {'market': 'btcbrl','price': '10','side': 'buy','tonce': 123,'volume': 1}).url) - - - From 1a82e60440409dd4c3fbbe18c3de9506bd6ea2dd Mon Sep 17 00:00:00 2001 From: Gabriel Baldao Date: Thu, 20 Feb 2020 18:12:21 -0300 Subject: [PATCH 07/21] fix post requests --- src/omnitrade_api/auth.py | 2 +- src/omnitrade_api/client.py | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/omnitrade_api/auth.py b/src/omnitrade_api/auth.py index 436c2a6..047883c 100644 --- a/src/omnitrade_api/auth.py +++ b/src/omnitrade_api/auth.py @@ -27,5 +27,5 @@ def __payload(self, verb, path, params): def __format_params(self, params): params['access_key'] = self.access_key - params['tonce'] = int(time.time()) * 10000 + params['tonce'] = int(time.time()) * 1000 return params diff --git a/src/omnitrade_api/client.py b/src/omnitrade_api/client.py index cce0158..23e0326 100644 --- a/src/omnitrade_api/client.py +++ b/src/omnitrade_api/client.py @@ -4,7 +4,7 @@ from auth import Auth from ordered_dict import ordered_dict -OMNITRADE_URL = 'https://omnitrade.io' +OMNITRADE_URL = 'http://localhost:5000'#'https://omnitrade.io' class Client(object): def __init__(self, options={}): global OMNITRADE_URL @@ -49,10 +49,14 @@ def __get_request(self, uri, params): return requests.get(uri, params = urllib.urlencode(params)) def __post_request(self, uri, params): - return requests.post(uri, params = json.dumps(params)) + print(uri) + print(params) + return requests.post(uri, params = urllib.urlencode(params)) def __parameters(self, action, path, params): uri = '{endpoint}{path}'.format(endpoint=self.endpoint, path=path) + print('Com auth\n') + print(self.auth.signed_params(action, path, params)) dict_params = self.auth.signed_params(action, path, params) if self.auth != None else params return uri, ordered_dict(dict_params) From ba113eb559002b427cfeee3cef107cbf43d0ccbe Mon Sep 17 00:00:00 2001 From: Gabriel Baldao Date: Fri, 21 Feb 2020 11:08:47 -0300 Subject: [PATCH 08/21] improve straming client --- src/omnitrade_api/auth.py | 2 +- src/omnitrade_api/client.py | 9 ++----- src/omnitrade_api/streaming_client.py | 37 +++++++++++++++------------ 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/omnitrade_api/auth.py b/src/omnitrade_api/auth.py index 047883c..8829bac 100644 --- a/src/omnitrade_api/auth.py +++ b/src/omnitrade_api/auth.py @@ -16,7 +16,7 @@ def signed_params(self, verb, path, params = {}): params = self.__format_params(params) signature = self.__sign(verb, path, urllib.urlencode(params)) - params['signature'] = signature #TODO FIX THIS SIGNATURE + params['signature'] = signature return params def __sign(self, verb, path, params): diff --git a/src/omnitrade_api/client.py b/src/omnitrade_api/client.py index 23e0326..0fc0401 100644 --- a/src/omnitrade_api/client.py +++ b/src/omnitrade_api/client.py @@ -1,12 +1,12 @@ import requests -import json import urllib from auth import Auth from ordered_dict import ordered_dict -OMNITRADE_URL = 'http://localhost:5000'#'https://omnitrade.io' +OMNITRADE_URL = 'https://omnitrade.io' class Client(object): def __init__(self, options={}): + print("Initialize") global OMNITRADE_URL self.auth = None self.__setup_auth_keys(options) @@ -16,7 +16,6 @@ def __init__(self, options={}): def get_public(self, path, params={}): uri, params = self.__parameters('GET',path, params) - return self.__get_request(uri, params) @@ -49,14 +48,10 @@ def __get_request(self, uri, params): return requests.get(uri, params = urllib.urlencode(params)) def __post_request(self, uri, params): - print(uri) - print(params) return requests.post(uri, params = urllib.urlencode(params)) def __parameters(self, action, path, params): uri = '{endpoint}{path}'.format(endpoint=self.endpoint, path=path) - print('Com auth\n') - print(self.auth.signed_params(action, path, params)) dict_params = self.auth.signed_params(action, path, params) if self.auth != None else params return uri, ordered_dict(dict_params) diff --git a/src/omnitrade_api/streaming_client.py b/src/omnitrade_api/streaming_client.py index d8b13d0..437fff3 100644 --- a/src/omnitrade_api/streaming_client.py +++ b/src/omnitrade_api/streaming_client.py @@ -3,14 +3,18 @@ import thread except ImportError: import _thread as thread -import time +import logging +import json +import ast from client import Client +logging.basicConfig(level=logging.INFO) + class StreamingClient(Client): def __init__(self, options = {}): - # super + super(StreamingClient, self).__init__(options) self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else 'wss://omnitrade.com:8080' - self.logger = options['logger'] if 'logger' in options.keys() else 'Logger' #Logger(STDOUT) + self.logger = options['logger'] if 'logger' in options.keys() else logging websocket.enableTrace(True) self.ws = websocket.WebSocketApp(self.endpoint, on_message = self.on_message, @@ -20,22 +24,23 @@ def __init__(self, options = {}): self.ws.run_forever() def on_message(self, message): - print(message) + msg = ast.literal_eval(message.decode()) + + key = msg.keys()[0] + data = msg[key] + if data != None and key == 'challenge': + self.ws.send(str(self.auth.signed_challenge(data)).encode()) + else: + try: + except Exception as e: + self.logger.error("Failed to process message: {error}".format(error=e)) def on_error(self, error): - print(error) + self.logger.info(error) def on_close(self): - print("### closed ###") + self.ws.close() + self.logger.info("### closed ###") def on_open(self): - def run(*args): - for i in range(3): - time.sleep(1) - self.ws.send("Hello %d" % i) - time.sleep(1) - # self.ws.close() - print("thread terminating...") - thread.start_new_thread(run, ()) - - + self.logger.info("Connected") From 29a38bf316759924f2820d92be58cd5eca8d73e5 Mon Sep 17 00:00:00 2001 From: Gabriel Baldao Date: Fri, 21 Feb 2020 15:03:47 -0300 Subject: [PATCH 09/21] add setup.py --- .../omnitradeClient/__init__.py | 2 + .../omnitradeClient}/auth.py | 1 - .../omnitradeClient}/client.py | 1 - .../omnitradeClient}/ordered_dict.py | 0 .../omnitradeClient}/streaming_client.py | 8 +-- .../omnitrade_api/__init__.py | 2 + .../omnitrade_api/auth.py | 30 ++++++++++ .../omnitrade_api/client.py | 58 +++++++++++++++++++ .../omnitrade_api/ordered_dict.py | 8 +++ .../omnitrade_api/streaming_client.py | 44 ++++++++++++++ build/lib/omnitrade_api/__init__.py | 2 + build/lib/omnitrade_api/auth.py | 29 ++++++++++ build/lib/omnitrade_api/client.py | 58 +++++++++++++++++++ build/lib/omnitrade_api/ordered_dict.py | 8 +++ build/lib/omnitrade_api/streaming_client.py | 44 ++++++++++++++ requirements.txt | 5 ++ setup.py | 21 +++++++ src/omnitradeClient/__init__.py | 2 + src/omnitradeClient/auth.py | 30 ++++++++++ src/omnitradeClient/client.py | 58 +++++++++++++++++++ src/omnitradeClient/ordered_dict.py | 8 +++ src/omnitradeClient/streaming_client.py | 44 ++++++++++++++ src/tests/test_client.py | 15 +++++ 23 files changed, 471 insertions(+), 7 deletions(-) create mode 100644 build/lib.linux-x86_64-2.7/omnitradeClient/__init__.py rename {src/omnitrade_api => build/lib.linux-x86_64-2.7/omnitradeClient}/auth.py (98%) rename {src/omnitrade_api => build/lib.linux-x86_64-2.7/omnitradeClient}/client.py (98%) rename {src/omnitrade_api => build/lib.linux-x86_64-2.7/omnitradeClient}/ordered_dict.py (100%) rename {src/omnitrade_api => build/lib.linux-x86_64-2.7/omnitradeClient}/streaming_client.py (92%) create mode 100644 build/lib.linux-x86_64-2.7/omnitrade_api/__init__.py create mode 100644 build/lib.linux-x86_64-2.7/omnitrade_api/auth.py create mode 100644 build/lib.linux-x86_64-2.7/omnitrade_api/client.py create mode 100644 build/lib.linux-x86_64-2.7/omnitrade_api/ordered_dict.py create mode 100644 build/lib.linux-x86_64-2.7/omnitrade_api/streaming_client.py create mode 100644 build/lib/omnitrade_api/__init__.py create mode 100644 build/lib/omnitrade_api/auth.py create mode 100644 build/lib/omnitrade_api/client.py create mode 100644 build/lib/omnitrade_api/ordered_dict.py create mode 100644 build/lib/omnitrade_api/streaming_client.py create mode 100644 requirements.txt create mode 100755 setup.py create mode 100644 src/omnitradeClient/__init__.py create mode 100644 src/omnitradeClient/auth.py create mode 100644 src/omnitradeClient/client.py create mode 100644 src/omnitradeClient/ordered_dict.py create mode 100644 src/omnitradeClient/streaming_client.py diff --git a/build/lib.linux-x86_64-2.7/omnitradeClient/__init__.py b/build/lib.linux-x86_64-2.7/omnitradeClient/__init__.py new file mode 100644 index 0000000..df616da --- /dev/null +++ b/build/lib.linux-x86_64-2.7/omnitradeClient/__init__.py @@ -0,0 +1,2 @@ +from client import Client +from streaming_client import StreamingClient diff --git a/src/omnitrade_api/auth.py b/build/lib.linux-x86_64-2.7/omnitradeClient/auth.py similarity index 98% rename from src/omnitrade_api/auth.py rename to build/lib.linux-x86_64-2.7/omnitradeClient/auth.py index 8829bac..142bb68 100644 --- a/src/omnitrade_api/auth.py +++ b/build/lib.linux-x86_64-2.7/omnitradeClient/auth.py @@ -1,5 +1,4 @@ import hashlib -import time import urllib class Auth(object): diff --git a/src/omnitrade_api/client.py b/build/lib.linux-x86_64-2.7/omnitradeClient/client.py similarity index 98% rename from src/omnitrade_api/client.py rename to build/lib.linux-x86_64-2.7/omnitradeClient/client.py index 0fc0401..dd164a8 100644 --- a/src/omnitrade_api/client.py +++ b/build/lib.linux-x86_64-2.7/omnitradeClient/client.py @@ -6,7 +6,6 @@ OMNITRADE_URL = 'https://omnitrade.io' class Client(object): def __init__(self, options={}): - print("Initialize") global OMNITRADE_URL self.auth = None self.__setup_auth_keys(options) diff --git a/src/omnitrade_api/ordered_dict.py b/build/lib.linux-x86_64-2.7/omnitradeClient/ordered_dict.py similarity index 100% rename from src/omnitrade_api/ordered_dict.py rename to build/lib.linux-x86_64-2.7/omnitradeClient/ordered_dict.py diff --git a/src/omnitrade_api/streaming_client.py b/build/lib.linux-x86_64-2.7/omnitradeClient/streaming_client.py similarity index 92% rename from src/omnitrade_api/streaming_client.py rename to build/lib.linux-x86_64-2.7/omnitradeClient/streaming_client.py index 437fff3..bb8facc 100644 --- a/src/omnitrade_api/streaming_client.py +++ b/build/lib.linux-x86_64-2.7/omnitradeClient/streaming_client.py @@ -1,8 +1,4 @@ import websocket -try: - import thread -except ImportError: - import _thread as thread import logging import json import ast @@ -11,11 +7,12 @@ logging.basicConfig(level=logging.INFO) class StreamingClient(Client): - def __init__(self, options = {}): + def __init__(self, callback, options = {}): super(StreamingClient, self).__init__(options) self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else 'wss://omnitrade.com:8080' self.logger = options['logger'] if 'logger' in options.keys() else logging websocket.enableTrace(True) + self.callback = callback self.ws = websocket.WebSocketApp(self.endpoint, on_message = self.on_message, on_error = self.on_error, @@ -32,6 +29,7 @@ def on_message(self, message): self.ws.send(str(self.auth.signed_challenge(data)).encode()) else: try: + self.callback(msg) except Exception as e: self.logger.error("Failed to process message: {error}".format(error=e)) diff --git a/build/lib.linux-x86_64-2.7/omnitrade_api/__init__.py b/build/lib.linux-x86_64-2.7/omnitrade_api/__init__.py new file mode 100644 index 0000000..df616da --- /dev/null +++ b/build/lib.linux-x86_64-2.7/omnitrade_api/__init__.py @@ -0,0 +1,2 @@ +from client import Client +from streaming_client import StreamingClient diff --git a/build/lib.linux-x86_64-2.7/omnitrade_api/auth.py b/build/lib.linux-x86_64-2.7/omnitrade_api/auth.py new file mode 100644 index 0000000..142bb68 --- /dev/null +++ b/build/lib.linux-x86_64-2.7/omnitrade_api/auth.py @@ -0,0 +1,30 @@ +import hashlib +import urllib + +class Auth(object): + def __init__(self, access_key, secret_key): + self.access_key = access_key + self.secret_key = secret_key + + def signed_challenge(self, challenge): + signature = hashlib.pbkdf2_hmac('sha256', self.secret_key,"{access_key}{challenge}".format(access_key = self.access_key, challenge = challenge), 100000 ) + + return { 'auth': { 'access_key': self.access_key, 'answer': signature } } + + def signed_params(self, verb, path, params = {}): + params = self.__format_params(params) + + signature = self.__sign(verb, path, urllib.urlencode(params)) + params['signature'] = signature + return params + + def __sign(self, verb, path, params): + return hashlib.pbkdf2_hmac('sha256', self.secret_key, self.__payload(verb, path, params), 100000) + + def __payload(self, verb, path, params): + return "#{verb}|#{path}|#{params}".format(verb = verb.upper(), path = path, params = params) + + def __format_params(self, params): + params['access_key'] = self.access_key + params['tonce'] = int(time.time()) * 1000 + return params diff --git a/build/lib.linux-x86_64-2.7/omnitrade_api/client.py b/build/lib.linux-x86_64-2.7/omnitrade_api/client.py new file mode 100644 index 0000000..dd164a8 --- /dev/null +++ b/build/lib.linux-x86_64-2.7/omnitrade_api/client.py @@ -0,0 +1,58 @@ +import requests +import urllib +from auth import Auth +from ordered_dict import ordered_dict + +OMNITRADE_URL = 'https://omnitrade.io' +class Client(object): + def __init__(self, options={}): + global OMNITRADE_URL + self.auth = None + self.__setup_auth_keys(options) + + self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else OMNITRADE_URL + self.timeout = options['timeout'] if 'timeout' in options.keys() else 60 + + def get_public(self, path, params={}): + uri, params = self.__parameters('GET',path, params) + return self.__get_request(uri, params) + + + def get(self, path, params={}): + self.__check_auth() + + uri, params = self.__parameters('GET',path, params) + return self.__get_request(uri, params) + + def post(self, path, params={}): + self.__check_auth() + + uri, params = self.__parameters('POST', path, params) + return self.__post_request(uri, params) + + def __setup_auth_keys(self, options): + if not('access_key' in options.keys() and 'secret_key' in options.keys()): + return + + self.access_key = options['access_key'] + self.secret_key = options['secret_key'] + self.auth = Auth(self.access_key, self.secret_key) + + + def __check_auth(self): + if self.auth == None: + raise Exception('Missing access key and/or secret key') + + def __get_request(self, uri, params): + return requests.get(uri, params = urllib.urlencode(params)) + + def __post_request(self, uri, params): + return requests.post(uri, params = urllib.urlencode(params)) + + def __parameters(self, action, path, params): + uri = '{endpoint}{path}'.format(endpoint=self.endpoint, path=path) + dict_params = self.auth.signed_params(action, path, params) if self.auth != None else params + + return uri, ordered_dict(dict_params) + + diff --git a/build/lib.linux-x86_64-2.7/omnitrade_api/ordered_dict.py b/build/lib.linux-x86_64-2.7/omnitrade_api/ordered_dict.py new file mode 100644 index 0000000..292a903 --- /dev/null +++ b/build/lib.linux-x86_64-2.7/omnitrade_api/ordered_dict.py @@ -0,0 +1,8 @@ +def ordered_dict(dict_params): + params = map(lambda key,value: (key, value), dict_params.keys(), dict_params.values()) + params.sort(key=take_key) + + return params + +def take_key(item): + return item[0] diff --git a/build/lib.linux-x86_64-2.7/omnitrade_api/streaming_client.py b/build/lib.linux-x86_64-2.7/omnitrade_api/streaming_client.py new file mode 100644 index 0000000..bb8facc --- /dev/null +++ b/build/lib.linux-x86_64-2.7/omnitrade_api/streaming_client.py @@ -0,0 +1,44 @@ +import websocket +import logging +import json +import ast +from client import Client + +logging.basicConfig(level=logging.INFO) + +class StreamingClient(Client): + def __init__(self, callback, options = {}): + super(StreamingClient, self).__init__(options) + self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else 'wss://omnitrade.com:8080' + self.logger = options['logger'] if 'logger' in options.keys() else logging + websocket.enableTrace(True) + self.callback = callback + self.ws = websocket.WebSocketApp(self.endpoint, + on_message = self.on_message, + on_error = self.on_error, + on_close = self.on_close) + self.ws.on_open = self.on_open + self.ws.run_forever() + + def on_message(self, message): + msg = ast.literal_eval(message.decode()) + + key = msg.keys()[0] + data = msg[key] + if data != None and key == 'challenge': + self.ws.send(str(self.auth.signed_challenge(data)).encode()) + else: + try: + self.callback(msg) + except Exception as e: + self.logger.error("Failed to process message: {error}".format(error=e)) + + def on_error(self, error): + self.logger.info(error) + + def on_close(self): + self.ws.close() + self.logger.info("### closed ###") + + def on_open(self): + self.logger.info("Connected") diff --git a/build/lib/omnitrade_api/__init__.py b/build/lib/omnitrade_api/__init__.py new file mode 100644 index 0000000..df616da --- /dev/null +++ b/build/lib/omnitrade_api/__init__.py @@ -0,0 +1,2 @@ +from client import Client +from streaming_client import StreamingClient diff --git a/build/lib/omnitrade_api/auth.py b/build/lib/omnitrade_api/auth.py new file mode 100644 index 0000000..fecdb5b --- /dev/null +++ b/build/lib/omnitrade_api/auth.py @@ -0,0 +1,29 @@ +import urllib + +class Auth(object): + def __init__(self, access_key, secret_key): + self.access_key = access_key + self.secret_key = secret_key + + def signed_challenge(self, challenge): + signature = 'signature'#hashlib.pbkdf2_hmac('sha256', self.secret_key,"{access_key}{challenge}".format(access_key = self.access_key, challenge = challenge), 100000 ) + + return { 'auth': { 'access_key': self.access_key, 'answer': signature } } + + def signed_params(self, verb, path, params = {}): + params = self.__format_params(params) + + signature = self.__sign(verb, path, urllib.urlencode(params)) + params['signature'] = signature + return params + + def __sign(self, verb, path, params): + return 'signature'#hashlib.pbkdf2_hmac('sha256', self.secret_key, self.__payload(verb, path, params), 100000) + + def __payload(self, verb, path, params): + return "#{verb}|#{path}|#{params}".format(verb = verb.upper(), path = path, params = params) + + def __format_params(self, params): + params['access_key'] = self.access_key + params['tonce'] = int(time.time()) * 1000 + return params diff --git a/build/lib/omnitrade_api/client.py b/build/lib/omnitrade_api/client.py new file mode 100644 index 0000000..dd164a8 --- /dev/null +++ b/build/lib/omnitrade_api/client.py @@ -0,0 +1,58 @@ +import requests +import urllib +from auth import Auth +from ordered_dict import ordered_dict + +OMNITRADE_URL = 'https://omnitrade.io' +class Client(object): + def __init__(self, options={}): + global OMNITRADE_URL + self.auth = None + self.__setup_auth_keys(options) + + self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else OMNITRADE_URL + self.timeout = options['timeout'] if 'timeout' in options.keys() else 60 + + def get_public(self, path, params={}): + uri, params = self.__parameters('GET',path, params) + return self.__get_request(uri, params) + + + def get(self, path, params={}): + self.__check_auth() + + uri, params = self.__parameters('GET',path, params) + return self.__get_request(uri, params) + + def post(self, path, params={}): + self.__check_auth() + + uri, params = self.__parameters('POST', path, params) + return self.__post_request(uri, params) + + def __setup_auth_keys(self, options): + if not('access_key' in options.keys() and 'secret_key' in options.keys()): + return + + self.access_key = options['access_key'] + self.secret_key = options['secret_key'] + self.auth = Auth(self.access_key, self.secret_key) + + + def __check_auth(self): + if self.auth == None: + raise Exception('Missing access key and/or secret key') + + def __get_request(self, uri, params): + return requests.get(uri, params = urllib.urlencode(params)) + + def __post_request(self, uri, params): + return requests.post(uri, params = urllib.urlencode(params)) + + def __parameters(self, action, path, params): + uri = '{endpoint}{path}'.format(endpoint=self.endpoint, path=path) + dict_params = self.auth.signed_params(action, path, params) if self.auth != None else params + + return uri, ordered_dict(dict_params) + + diff --git a/build/lib/omnitrade_api/ordered_dict.py b/build/lib/omnitrade_api/ordered_dict.py new file mode 100644 index 0000000..292a903 --- /dev/null +++ b/build/lib/omnitrade_api/ordered_dict.py @@ -0,0 +1,8 @@ +def ordered_dict(dict_params): + params = map(lambda key,value: (key, value), dict_params.keys(), dict_params.values()) + params.sort(key=take_key) + + return params + +def take_key(item): + return item[0] diff --git a/build/lib/omnitrade_api/streaming_client.py b/build/lib/omnitrade_api/streaming_client.py new file mode 100644 index 0000000..bb8facc --- /dev/null +++ b/build/lib/omnitrade_api/streaming_client.py @@ -0,0 +1,44 @@ +import websocket +import logging +import json +import ast +from client import Client + +logging.basicConfig(level=logging.INFO) + +class StreamingClient(Client): + def __init__(self, callback, options = {}): + super(StreamingClient, self).__init__(options) + self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else 'wss://omnitrade.com:8080' + self.logger = options['logger'] if 'logger' in options.keys() else logging + websocket.enableTrace(True) + self.callback = callback + self.ws = websocket.WebSocketApp(self.endpoint, + on_message = self.on_message, + on_error = self.on_error, + on_close = self.on_close) + self.ws.on_open = self.on_open + self.ws.run_forever() + + def on_message(self, message): + msg = ast.literal_eval(message.decode()) + + key = msg.keys()[0] + data = msg[key] + if data != None and key == 'challenge': + self.ws.send(str(self.auth.signed_challenge(data)).encode()) + else: + try: + self.callback(msg) + except Exception as e: + self.logger.error("Failed to process message: {error}".format(error=e)) + + def on_error(self, error): + self.logger.info(error) + + def on_close(self): + self.ws.close() + self.logger.info("### closed ###") + + def on_open(self): + self.logger.info("Connected") diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..ebdcf71 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +ast +logging +websocket +# hashlib +requests diff --git a/setup.py b/setup.py new file mode 100755 index 0000000..fd4847f --- /dev/null +++ b/setup.py @@ -0,0 +1,21 @@ + +from setuptools import find_packages +from setuptools import setup +# from distutils.core import setup + +setup( + name="omnitradeClient", + version="0.1", + license="MIT license", + description="Python client for Omnitrade API", + author="Omnitrade", + author_email="@codeminer42.com", + url="https://github.com/OmniTrade/client-py", + packages=find_packages("src"), + package_dir={"": "src/"}, + include_package_data=True, + zip_safe=False, + keywords=["omnitrade", "api"], + install_requires=open("requirements.txt").readlines(), + extras_require={} +) diff --git a/src/omnitradeClient/__init__.py b/src/omnitradeClient/__init__.py new file mode 100644 index 0000000..df616da --- /dev/null +++ b/src/omnitradeClient/__init__.py @@ -0,0 +1,2 @@ +from client import Client +from streaming_client import StreamingClient diff --git a/src/omnitradeClient/auth.py b/src/omnitradeClient/auth.py new file mode 100644 index 0000000..142bb68 --- /dev/null +++ b/src/omnitradeClient/auth.py @@ -0,0 +1,30 @@ +import hashlib +import urllib + +class Auth(object): + def __init__(self, access_key, secret_key): + self.access_key = access_key + self.secret_key = secret_key + + def signed_challenge(self, challenge): + signature = hashlib.pbkdf2_hmac('sha256', self.secret_key,"{access_key}{challenge}".format(access_key = self.access_key, challenge = challenge), 100000 ) + + return { 'auth': { 'access_key': self.access_key, 'answer': signature } } + + def signed_params(self, verb, path, params = {}): + params = self.__format_params(params) + + signature = self.__sign(verb, path, urllib.urlencode(params)) + params['signature'] = signature + return params + + def __sign(self, verb, path, params): + return hashlib.pbkdf2_hmac('sha256', self.secret_key, self.__payload(verb, path, params), 100000) + + def __payload(self, verb, path, params): + return "#{verb}|#{path}|#{params}".format(verb = verb.upper(), path = path, params = params) + + def __format_params(self, params): + params['access_key'] = self.access_key + params['tonce'] = int(time.time()) * 1000 + return params diff --git a/src/omnitradeClient/client.py b/src/omnitradeClient/client.py new file mode 100644 index 0000000..dd164a8 --- /dev/null +++ b/src/omnitradeClient/client.py @@ -0,0 +1,58 @@ +import requests +import urllib +from auth import Auth +from ordered_dict import ordered_dict + +OMNITRADE_URL = 'https://omnitrade.io' +class Client(object): + def __init__(self, options={}): + global OMNITRADE_URL + self.auth = None + self.__setup_auth_keys(options) + + self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else OMNITRADE_URL + self.timeout = options['timeout'] if 'timeout' in options.keys() else 60 + + def get_public(self, path, params={}): + uri, params = self.__parameters('GET',path, params) + return self.__get_request(uri, params) + + + def get(self, path, params={}): + self.__check_auth() + + uri, params = self.__parameters('GET',path, params) + return self.__get_request(uri, params) + + def post(self, path, params={}): + self.__check_auth() + + uri, params = self.__parameters('POST', path, params) + return self.__post_request(uri, params) + + def __setup_auth_keys(self, options): + if not('access_key' in options.keys() and 'secret_key' in options.keys()): + return + + self.access_key = options['access_key'] + self.secret_key = options['secret_key'] + self.auth = Auth(self.access_key, self.secret_key) + + + def __check_auth(self): + if self.auth == None: + raise Exception('Missing access key and/or secret key') + + def __get_request(self, uri, params): + return requests.get(uri, params = urllib.urlencode(params)) + + def __post_request(self, uri, params): + return requests.post(uri, params = urllib.urlencode(params)) + + def __parameters(self, action, path, params): + uri = '{endpoint}{path}'.format(endpoint=self.endpoint, path=path) + dict_params = self.auth.signed_params(action, path, params) if self.auth != None else params + + return uri, ordered_dict(dict_params) + + diff --git a/src/omnitradeClient/ordered_dict.py b/src/omnitradeClient/ordered_dict.py new file mode 100644 index 0000000..292a903 --- /dev/null +++ b/src/omnitradeClient/ordered_dict.py @@ -0,0 +1,8 @@ +def ordered_dict(dict_params): + params = map(lambda key,value: (key, value), dict_params.keys(), dict_params.values()) + params.sort(key=take_key) + + return params + +def take_key(item): + return item[0] diff --git a/src/omnitradeClient/streaming_client.py b/src/omnitradeClient/streaming_client.py new file mode 100644 index 0000000..bb8facc --- /dev/null +++ b/src/omnitradeClient/streaming_client.py @@ -0,0 +1,44 @@ +import websocket +import logging +import json +import ast +from client import Client + +logging.basicConfig(level=logging.INFO) + +class StreamingClient(Client): + def __init__(self, callback, options = {}): + super(StreamingClient, self).__init__(options) + self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else 'wss://omnitrade.com:8080' + self.logger = options['logger'] if 'logger' in options.keys() else logging + websocket.enableTrace(True) + self.callback = callback + self.ws = websocket.WebSocketApp(self.endpoint, + on_message = self.on_message, + on_error = self.on_error, + on_close = self.on_close) + self.ws.on_open = self.on_open + self.ws.run_forever() + + def on_message(self, message): + msg = ast.literal_eval(message.decode()) + + key = msg.keys()[0] + data = msg[key] + if data != None and key == 'challenge': + self.ws.send(str(self.auth.signed_challenge(data)).encode()) + else: + try: + self.callback(msg) + except Exception as e: + self.logger.error("Failed to process message: {error}".format(error=e)) + + def on_error(self, error): + self.logger.info(error) + + def on_close(self): + self.ws.close() + self.logger.info("### closed ###") + + def on_open(self): + self.logger.info("Connected") diff --git a/src/tests/test_client.py b/src/tests/test_client.py index ce3f046..76b7269 100644 --- a/src/tests/test_client.py +++ b/src/tests/test_client.py @@ -16,3 +16,18 @@ def test_get_public_valid_request(self): response = public_client.get_public(market_path) self.assertEqual(response.json(), markets) + + def test_post_request(self): + access_key = 'FUkESEYRJmO42MfqXcgJfm73GfIMw61qogExtcX7' #TODO improve this requests tests + + client = Client({'access_key': access_key,'secret_key': '123456'}) + response = client.post('/api/v2/orders/clear', {'side': 'sell' }) + + self.assertEqual(response.status_code, 201) + + def test_post_request(self): + access_key = 'FUkESEYRJmO42MfqXcgJfm73GfIMw61qogExtcX7' #TODO improve this requests tests + + client = Client({'access_key': access_key,'secret_key': '123456'}) + response = client.get('/api/v2/order', {'id': 1 }) + self.assertEqual(response.status_code, 404) From 37325acac280f0497c6623b31a52d9a16d52bb99 Mon Sep 17 00:00:00 2001 From: Gabriel Baldao Date: Fri, 21 Feb 2020 15:07:50 -0300 Subject: [PATCH 10/21] remove build --- .../omnitradeClient/__init__.py | 2 - .../omnitradeClient/auth.py | 30 ---------- .../omnitradeClient/client.py | 58 ------------------- .../omnitradeClient/ordered_dict.py | 8 --- .../omnitradeClient/streaming_client.py | 44 -------------- .../omnitrade_api/__init__.py | 2 - .../omnitrade_api/auth.py | 30 ---------- .../omnitrade_api/client.py | 58 ------------------- .../omnitrade_api/ordered_dict.py | 8 --- .../omnitrade_api/streaming_client.py | 44 -------------- build/lib/omnitrade_api/__init__.py | 2 - build/lib/omnitrade_api/auth.py | 29 ---------- build/lib/omnitrade_api/client.py | 58 ------------------- build/lib/omnitrade_api/ordered_dict.py | 8 --- build/lib/omnitrade_api/streaming_client.py | 44 -------------- 15 files changed, 425 deletions(-) delete mode 100644 build/lib.linux-x86_64-2.7/omnitradeClient/__init__.py delete mode 100644 build/lib.linux-x86_64-2.7/omnitradeClient/auth.py delete mode 100644 build/lib.linux-x86_64-2.7/omnitradeClient/client.py delete mode 100644 build/lib.linux-x86_64-2.7/omnitradeClient/ordered_dict.py delete mode 100644 build/lib.linux-x86_64-2.7/omnitradeClient/streaming_client.py delete mode 100644 build/lib.linux-x86_64-2.7/omnitrade_api/__init__.py delete mode 100644 build/lib.linux-x86_64-2.7/omnitrade_api/auth.py delete mode 100644 build/lib.linux-x86_64-2.7/omnitrade_api/client.py delete mode 100644 build/lib.linux-x86_64-2.7/omnitrade_api/ordered_dict.py delete mode 100644 build/lib.linux-x86_64-2.7/omnitrade_api/streaming_client.py delete mode 100644 build/lib/omnitrade_api/__init__.py delete mode 100644 build/lib/omnitrade_api/auth.py delete mode 100644 build/lib/omnitrade_api/client.py delete mode 100644 build/lib/omnitrade_api/ordered_dict.py delete mode 100644 build/lib/omnitrade_api/streaming_client.py diff --git a/build/lib.linux-x86_64-2.7/omnitradeClient/__init__.py b/build/lib.linux-x86_64-2.7/omnitradeClient/__init__.py deleted file mode 100644 index df616da..0000000 --- a/build/lib.linux-x86_64-2.7/omnitradeClient/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from client import Client -from streaming_client import StreamingClient diff --git a/build/lib.linux-x86_64-2.7/omnitradeClient/auth.py b/build/lib.linux-x86_64-2.7/omnitradeClient/auth.py deleted file mode 100644 index 142bb68..0000000 --- a/build/lib.linux-x86_64-2.7/omnitradeClient/auth.py +++ /dev/null @@ -1,30 +0,0 @@ -import hashlib -import urllib - -class Auth(object): - def __init__(self, access_key, secret_key): - self.access_key = access_key - self.secret_key = secret_key - - def signed_challenge(self, challenge): - signature = hashlib.pbkdf2_hmac('sha256', self.secret_key,"{access_key}{challenge}".format(access_key = self.access_key, challenge = challenge), 100000 ) - - return { 'auth': { 'access_key': self.access_key, 'answer': signature } } - - def signed_params(self, verb, path, params = {}): - params = self.__format_params(params) - - signature = self.__sign(verb, path, urllib.urlencode(params)) - params['signature'] = signature - return params - - def __sign(self, verb, path, params): - return hashlib.pbkdf2_hmac('sha256', self.secret_key, self.__payload(verb, path, params), 100000) - - def __payload(self, verb, path, params): - return "#{verb}|#{path}|#{params}".format(verb = verb.upper(), path = path, params = params) - - def __format_params(self, params): - params['access_key'] = self.access_key - params['tonce'] = int(time.time()) * 1000 - return params diff --git a/build/lib.linux-x86_64-2.7/omnitradeClient/client.py b/build/lib.linux-x86_64-2.7/omnitradeClient/client.py deleted file mode 100644 index dd164a8..0000000 --- a/build/lib.linux-x86_64-2.7/omnitradeClient/client.py +++ /dev/null @@ -1,58 +0,0 @@ -import requests -import urllib -from auth import Auth -from ordered_dict import ordered_dict - -OMNITRADE_URL = 'https://omnitrade.io' -class Client(object): - def __init__(self, options={}): - global OMNITRADE_URL - self.auth = None - self.__setup_auth_keys(options) - - self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else OMNITRADE_URL - self.timeout = options['timeout'] if 'timeout' in options.keys() else 60 - - def get_public(self, path, params={}): - uri, params = self.__parameters('GET',path, params) - return self.__get_request(uri, params) - - - def get(self, path, params={}): - self.__check_auth() - - uri, params = self.__parameters('GET',path, params) - return self.__get_request(uri, params) - - def post(self, path, params={}): - self.__check_auth() - - uri, params = self.__parameters('POST', path, params) - return self.__post_request(uri, params) - - def __setup_auth_keys(self, options): - if not('access_key' in options.keys() and 'secret_key' in options.keys()): - return - - self.access_key = options['access_key'] - self.secret_key = options['secret_key'] - self.auth = Auth(self.access_key, self.secret_key) - - - def __check_auth(self): - if self.auth == None: - raise Exception('Missing access key and/or secret key') - - def __get_request(self, uri, params): - return requests.get(uri, params = urllib.urlencode(params)) - - def __post_request(self, uri, params): - return requests.post(uri, params = urllib.urlencode(params)) - - def __parameters(self, action, path, params): - uri = '{endpoint}{path}'.format(endpoint=self.endpoint, path=path) - dict_params = self.auth.signed_params(action, path, params) if self.auth != None else params - - return uri, ordered_dict(dict_params) - - diff --git a/build/lib.linux-x86_64-2.7/omnitradeClient/ordered_dict.py b/build/lib.linux-x86_64-2.7/omnitradeClient/ordered_dict.py deleted file mode 100644 index 292a903..0000000 --- a/build/lib.linux-x86_64-2.7/omnitradeClient/ordered_dict.py +++ /dev/null @@ -1,8 +0,0 @@ -def ordered_dict(dict_params): - params = map(lambda key,value: (key, value), dict_params.keys(), dict_params.values()) - params.sort(key=take_key) - - return params - -def take_key(item): - return item[0] diff --git a/build/lib.linux-x86_64-2.7/omnitradeClient/streaming_client.py b/build/lib.linux-x86_64-2.7/omnitradeClient/streaming_client.py deleted file mode 100644 index bb8facc..0000000 --- a/build/lib.linux-x86_64-2.7/omnitradeClient/streaming_client.py +++ /dev/null @@ -1,44 +0,0 @@ -import websocket -import logging -import json -import ast -from client import Client - -logging.basicConfig(level=logging.INFO) - -class StreamingClient(Client): - def __init__(self, callback, options = {}): - super(StreamingClient, self).__init__(options) - self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else 'wss://omnitrade.com:8080' - self.logger = options['logger'] if 'logger' in options.keys() else logging - websocket.enableTrace(True) - self.callback = callback - self.ws = websocket.WebSocketApp(self.endpoint, - on_message = self.on_message, - on_error = self.on_error, - on_close = self.on_close) - self.ws.on_open = self.on_open - self.ws.run_forever() - - def on_message(self, message): - msg = ast.literal_eval(message.decode()) - - key = msg.keys()[0] - data = msg[key] - if data != None and key == 'challenge': - self.ws.send(str(self.auth.signed_challenge(data)).encode()) - else: - try: - self.callback(msg) - except Exception as e: - self.logger.error("Failed to process message: {error}".format(error=e)) - - def on_error(self, error): - self.logger.info(error) - - def on_close(self): - self.ws.close() - self.logger.info("### closed ###") - - def on_open(self): - self.logger.info("Connected") diff --git a/build/lib.linux-x86_64-2.7/omnitrade_api/__init__.py b/build/lib.linux-x86_64-2.7/omnitrade_api/__init__.py deleted file mode 100644 index df616da..0000000 --- a/build/lib.linux-x86_64-2.7/omnitrade_api/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from client import Client -from streaming_client import StreamingClient diff --git a/build/lib.linux-x86_64-2.7/omnitrade_api/auth.py b/build/lib.linux-x86_64-2.7/omnitrade_api/auth.py deleted file mode 100644 index 142bb68..0000000 --- a/build/lib.linux-x86_64-2.7/omnitrade_api/auth.py +++ /dev/null @@ -1,30 +0,0 @@ -import hashlib -import urllib - -class Auth(object): - def __init__(self, access_key, secret_key): - self.access_key = access_key - self.secret_key = secret_key - - def signed_challenge(self, challenge): - signature = hashlib.pbkdf2_hmac('sha256', self.secret_key,"{access_key}{challenge}".format(access_key = self.access_key, challenge = challenge), 100000 ) - - return { 'auth': { 'access_key': self.access_key, 'answer': signature } } - - def signed_params(self, verb, path, params = {}): - params = self.__format_params(params) - - signature = self.__sign(verb, path, urllib.urlencode(params)) - params['signature'] = signature - return params - - def __sign(self, verb, path, params): - return hashlib.pbkdf2_hmac('sha256', self.secret_key, self.__payload(verb, path, params), 100000) - - def __payload(self, verb, path, params): - return "#{verb}|#{path}|#{params}".format(verb = verb.upper(), path = path, params = params) - - def __format_params(self, params): - params['access_key'] = self.access_key - params['tonce'] = int(time.time()) * 1000 - return params diff --git a/build/lib.linux-x86_64-2.7/omnitrade_api/client.py b/build/lib.linux-x86_64-2.7/omnitrade_api/client.py deleted file mode 100644 index dd164a8..0000000 --- a/build/lib.linux-x86_64-2.7/omnitrade_api/client.py +++ /dev/null @@ -1,58 +0,0 @@ -import requests -import urllib -from auth import Auth -from ordered_dict import ordered_dict - -OMNITRADE_URL = 'https://omnitrade.io' -class Client(object): - def __init__(self, options={}): - global OMNITRADE_URL - self.auth = None - self.__setup_auth_keys(options) - - self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else OMNITRADE_URL - self.timeout = options['timeout'] if 'timeout' in options.keys() else 60 - - def get_public(self, path, params={}): - uri, params = self.__parameters('GET',path, params) - return self.__get_request(uri, params) - - - def get(self, path, params={}): - self.__check_auth() - - uri, params = self.__parameters('GET',path, params) - return self.__get_request(uri, params) - - def post(self, path, params={}): - self.__check_auth() - - uri, params = self.__parameters('POST', path, params) - return self.__post_request(uri, params) - - def __setup_auth_keys(self, options): - if not('access_key' in options.keys() and 'secret_key' in options.keys()): - return - - self.access_key = options['access_key'] - self.secret_key = options['secret_key'] - self.auth = Auth(self.access_key, self.secret_key) - - - def __check_auth(self): - if self.auth == None: - raise Exception('Missing access key and/or secret key') - - def __get_request(self, uri, params): - return requests.get(uri, params = urllib.urlencode(params)) - - def __post_request(self, uri, params): - return requests.post(uri, params = urllib.urlencode(params)) - - def __parameters(self, action, path, params): - uri = '{endpoint}{path}'.format(endpoint=self.endpoint, path=path) - dict_params = self.auth.signed_params(action, path, params) if self.auth != None else params - - return uri, ordered_dict(dict_params) - - diff --git a/build/lib.linux-x86_64-2.7/omnitrade_api/ordered_dict.py b/build/lib.linux-x86_64-2.7/omnitrade_api/ordered_dict.py deleted file mode 100644 index 292a903..0000000 --- a/build/lib.linux-x86_64-2.7/omnitrade_api/ordered_dict.py +++ /dev/null @@ -1,8 +0,0 @@ -def ordered_dict(dict_params): - params = map(lambda key,value: (key, value), dict_params.keys(), dict_params.values()) - params.sort(key=take_key) - - return params - -def take_key(item): - return item[0] diff --git a/build/lib.linux-x86_64-2.7/omnitrade_api/streaming_client.py b/build/lib.linux-x86_64-2.7/omnitrade_api/streaming_client.py deleted file mode 100644 index bb8facc..0000000 --- a/build/lib.linux-x86_64-2.7/omnitrade_api/streaming_client.py +++ /dev/null @@ -1,44 +0,0 @@ -import websocket -import logging -import json -import ast -from client import Client - -logging.basicConfig(level=logging.INFO) - -class StreamingClient(Client): - def __init__(self, callback, options = {}): - super(StreamingClient, self).__init__(options) - self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else 'wss://omnitrade.com:8080' - self.logger = options['logger'] if 'logger' in options.keys() else logging - websocket.enableTrace(True) - self.callback = callback - self.ws = websocket.WebSocketApp(self.endpoint, - on_message = self.on_message, - on_error = self.on_error, - on_close = self.on_close) - self.ws.on_open = self.on_open - self.ws.run_forever() - - def on_message(self, message): - msg = ast.literal_eval(message.decode()) - - key = msg.keys()[0] - data = msg[key] - if data != None and key == 'challenge': - self.ws.send(str(self.auth.signed_challenge(data)).encode()) - else: - try: - self.callback(msg) - except Exception as e: - self.logger.error("Failed to process message: {error}".format(error=e)) - - def on_error(self, error): - self.logger.info(error) - - def on_close(self): - self.ws.close() - self.logger.info("### closed ###") - - def on_open(self): - self.logger.info("Connected") diff --git a/build/lib/omnitrade_api/__init__.py b/build/lib/omnitrade_api/__init__.py deleted file mode 100644 index df616da..0000000 --- a/build/lib/omnitrade_api/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from client import Client -from streaming_client import StreamingClient diff --git a/build/lib/omnitrade_api/auth.py b/build/lib/omnitrade_api/auth.py deleted file mode 100644 index fecdb5b..0000000 --- a/build/lib/omnitrade_api/auth.py +++ /dev/null @@ -1,29 +0,0 @@ -import urllib - -class Auth(object): - def __init__(self, access_key, secret_key): - self.access_key = access_key - self.secret_key = secret_key - - def signed_challenge(self, challenge): - signature = 'signature'#hashlib.pbkdf2_hmac('sha256', self.secret_key,"{access_key}{challenge}".format(access_key = self.access_key, challenge = challenge), 100000 ) - - return { 'auth': { 'access_key': self.access_key, 'answer': signature } } - - def signed_params(self, verb, path, params = {}): - params = self.__format_params(params) - - signature = self.__sign(verb, path, urllib.urlencode(params)) - params['signature'] = signature - return params - - def __sign(self, verb, path, params): - return 'signature'#hashlib.pbkdf2_hmac('sha256', self.secret_key, self.__payload(verb, path, params), 100000) - - def __payload(self, verb, path, params): - return "#{verb}|#{path}|#{params}".format(verb = verb.upper(), path = path, params = params) - - def __format_params(self, params): - params['access_key'] = self.access_key - params['tonce'] = int(time.time()) * 1000 - return params diff --git a/build/lib/omnitrade_api/client.py b/build/lib/omnitrade_api/client.py deleted file mode 100644 index dd164a8..0000000 --- a/build/lib/omnitrade_api/client.py +++ /dev/null @@ -1,58 +0,0 @@ -import requests -import urllib -from auth import Auth -from ordered_dict import ordered_dict - -OMNITRADE_URL = 'https://omnitrade.io' -class Client(object): - def __init__(self, options={}): - global OMNITRADE_URL - self.auth = None - self.__setup_auth_keys(options) - - self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else OMNITRADE_URL - self.timeout = options['timeout'] if 'timeout' in options.keys() else 60 - - def get_public(self, path, params={}): - uri, params = self.__parameters('GET',path, params) - return self.__get_request(uri, params) - - - def get(self, path, params={}): - self.__check_auth() - - uri, params = self.__parameters('GET',path, params) - return self.__get_request(uri, params) - - def post(self, path, params={}): - self.__check_auth() - - uri, params = self.__parameters('POST', path, params) - return self.__post_request(uri, params) - - def __setup_auth_keys(self, options): - if not('access_key' in options.keys() and 'secret_key' in options.keys()): - return - - self.access_key = options['access_key'] - self.secret_key = options['secret_key'] - self.auth = Auth(self.access_key, self.secret_key) - - - def __check_auth(self): - if self.auth == None: - raise Exception('Missing access key and/or secret key') - - def __get_request(self, uri, params): - return requests.get(uri, params = urllib.urlencode(params)) - - def __post_request(self, uri, params): - return requests.post(uri, params = urllib.urlencode(params)) - - def __parameters(self, action, path, params): - uri = '{endpoint}{path}'.format(endpoint=self.endpoint, path=path) - dict_params = self.auth.signed_params(action, path, params) if self.auth != None else params - - return uri, ordered_dict(dict_params) - - diff --git a/build/lib/omnitrade_api/ordered_dict.py b/build/lib/omnitrade_api/ordered_dict.py deleted file mode 100644 index 292a903..0000000 --- a/build/lib/omnitrade_api/ordered_dict.py +++ /dev/null @@ -1,8 +0,0 @@ -def ordered_dict(dict_params): - params = map(lambda key,value: (key, value), dict_params.keys(), dict_params.values()) - params.sort(key=take_key) - - return params - -def take_key(item): - return item[0] diff --git a/build/lib/omnitrade_api/streaming_client.py b/build/lib/omnitrade_api/streaming_client.py deleted file mode 100644 index bb8facc..0000000 --- a/build/lib/omnitrade_api/streaming_client.py +++ /dev/null @@ -1,44 +0,0 @@ -import websocket -import logging -import json -import ast -from client import Client - -logging.basicConfig(level=logging.INFO) - -class StreamingClient(Client): - def __init__(self, callback, options = {}): - super(StreamingClient, self).__init__(options) - self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else 'wss://omnitrade.com:8080' - self.logger = options['logger'] if 'logger' in options.keys() else logging - websocket.enableTrace(True) - self.callback = callback - self.ws = websocket.WebSocketApp(self.endpoint, - on_message = self.on_message, - on_error = self.on_error, - on_close = self.on_close) - self.ws.on_open = self.on_open - self.ws.run_forever() - - def on_message(self, message): - msg = ast.literal_eval(message.decode()) - - key = msg.keys()[0] - data = msg[key] - if data != None and key == 'challenge': - self.ws.send(str(self.auth.signed_challenge(data)).encode()) - else: - try: - self.callback(msg) - except Exception as e: - self.logger.error("Failed to process message: {error}".format(error=e)) - - def on_error(self, error): - self.logger.info(error) - - def on_close(self): - self.ws.close() - self.logger.info("### closed ###") - - def on_open(self): - self.logger.info("Connected") From 3ba4dbea71c241da571029e21c75db094afba5cb Mon Sep 17 00:00:00 2001 From: Gabriel Baldao Date: Fri, 21 Feb 2020 15:24:49 -0300 Subject: [PATCH 11/21] update setup --- requirements.txt | 1 - setup.py | 3 +-- src/tests/test_auth.py | 2 +- src/tests/test_client.py | 2 +- src/tests/test_ordered_dict.py | 2 +- 5 files changed, 4 insertions(+), 6 deletions(-) diff --git a/requirements.txt b/requirements.txt index ebdcf71..d00e9f4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,4 @@ ast logging websocket -# hashlib requests diff --git a/setup.py b/setup.py index fd4847f..ef1a03f 100755 --- a/setup.py +++ b/setup.py @@ -1,11 +1,10 @@ from setuptools import find_packages from setuptools import setup -# from distutils.core import setup setup( name="omnitradeClient", - version="0.1", + version="0.2", license="MIT license", description="Python client for Omnitrade API", author="Omnitrade", diff --git a/src/tests/test_auth.py b/src/tests/test_auth.py index a56a37c..c7735f5 100644 --- a/src/tests/test_auth.py +++ b/src/tests/test_auth.py @@ -1,5 +1,5 @@ import unittest -from omnitrade_api.auth import Auth +from omnitradeClient.auth import Auth ACCESS_KEY = '123456' SECRET_KEY = '123456' diff --git a/src/tests/test_client.py b/src/tests/test_client.py index 76b7269..6ebe82a 100644 --- a/src/tests/test_client.py +++ b/src/tests/test_client.py @@ -3,7 +3,7 @@ from nose.tools import assert_is_none, assert_list_equal from mock import patch, Mock -from omnitrade_api.client import Client +from omnitradeClient.client import Client OMNITRADE_URL = 'https://omnitrade.io' class TestClientMethods(unittest.TestCase): diff --git a/src/tests/test_ordered_dict.py b/src/tests/test_ordered_dict.py index 3d5a9e2..61f334b 100644 --- a/src/tests/test_ordered_dict.py +++ b/src/tests/test_ordered_dict.py @@ -1,5 +1,5 @@ import unittest -from omnitrade_api.ordered_dict import ordered_dict +from omnitradeClient.ordered_dict import ordered_dict class TestOrderedDictMethods(unittest.TestCase): From eeb62889e280b2f70415ad255c01c1734809458d Mon Sep 17 00:00:00 2001 From: Gabriel Baldao Date: Fri, 21 Feb 2020 16:04:24 -0300 Subject: [PATCH 12/21] set omnitrade as global var --- src/omnitradeClient/ordered_dict.py | 1 - src/omnitradeClient/streaming_client.py | 6 +++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/omnitradeClient/ordered_dict.py b/src/omnitradeClient/ordered_dict.py index 292a903..8abc375 100644 --- a/src/omnitradeClient/ordered_dict.py +++ b/src/omnitradeClient/ordered_dict.py @@ -1,7 +1,6 @@ def ordered_dict(dict_params): params = map(lambda key,value: (key, value), dict_params.keys(), dict_params.values()) params.sort(key=take_key) - return params def take_key(item): diff --git a/src/omnitradeClient/streaming_client.py b/src/omnitradeClient/streaming_client.py index bb8facc..b6d4164 100644 --- a/src/omnitradeClient/streaming_client.py +++ b/src/omnitradeClient/streaming_client.py @@ -6,12 +6,16 @@ logging.basicConfig(level=logging.INFO) +OMNITRADE_URL = 'wss://omnitrade.com:8080' class StreamingClient(Client): def __init__(self, callback, options = {}): + global OMNITRADE_URL super(StreamingClient, self).__init__(options) - self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else 'wss://omnitrade.com:8080' + self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else OMNITRADE_URL self.logger = options['logger'] if 'logger' in options.keys() else logging + websocket.enableTrace(True) + self.callback = callback self.ws = websocket.WebSocketApp(self.endpoint, on_message = self.on_message, From 2b815fabf86db4ac027e61dfc573d020d18f3d85 Mon Sep 17 00:00:00 2001 From: Gabriel Baldao Date: Fri, 21 Feb 2020 16:21:38 -0300 Subject: [PATCH 13/21] update readme --- README.md | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/README.md b/README.md index eed7f32..818eec8 100644 --- a/README.md +++ b/README.md @@ -1 +1,71 @@ # client-py + + +## Install + +```console +pip install git+https://github.com/OmniTrade/client-py.git +``` + +## Usage + +Require the client in your code by adding: + + +```python +from omnitradeClient import Client +from omnitradeClient import StreamingClient +``` + +You can use both the public or private API. + +### Public +------ + +Instance your public client by using: + +```python +public_client = Client() +``` + +#### .get_public + +Use **`.get_public`** to make a GET request to an URL, as the following example: + +```python +client_public.get_public('/api/v2/markets') +``` + +### Private +------ + +When using the private client, you also have to specify your access and private keys in the instantiation: + +```ruby +private_client = Client({ access_key: 'your_access_key', secret_key: 'your_secret_key' }) +``` + +You can also set a timeout and/or endpoit by adding the arguments: + +```ruby +private_client = Client({ access_key: 'your_access_key', secret_key: 'your_secret_key', timeout: 60, endpoint: 'https://omnitrade.io/' }) +``` +#### .get + +Use **`.get`** to make a GET request to an URL, you can also set the required arguments, as the following example: + +```ruby +private_client.get('/api/v2/orders', { market: 'btcbrl' }) +``` + +#### .post + +Use **`.post`** to make a POST request to an URL, you can also set the required arguments, as the following example: + +```ruby +private_client.post('/api/v2/order', { market: 'btcbrl', side: 'buy', volume: '0.42', price: '4200.0' }) +``` + +## Licence + +OmniTrade (C) All Rights Reserved. From 88752e5d91dabb86f0cb9f09b1e1fdd24bd2fa22 Mon Sep 17 00:00:00 2001 From: Gabriel Baldao Date: Fri, 21 Feb 2020 16:25:24 -0300 Subject: [PATCH 14/21] fix to review --- src/omnitradeClient/client.py | 1 - src/omnitradeClient/streaming_client.py | 1 - 2 files changed, 2 deletions(-) diff --git a/src/omnitradeClient/client.py b/src/omnitradeClient/client.py index dd164a8..3864ec0 100644 --- a/src/omnitradeClient/client.py +++ b/src/omnitradeClient/client.py @@ -6,7 +6,6 @@ OMNITRADE_URL = 'https://omnitrade.io' class Client(object): def __init__(self, options={}): - global OMNITRADE_URL self.auth = None self.__setup_auth_keys(options) diff --git a/src/omnitradeClient/streaming_client.py b/src/omnitradeClient/streaming_client.py index b6d4164..1395e28 100644 --- a/src/omnitradeClient/streaming_client.py +++ b/src/omnitradeClient/streaming_client.py @@ -9,7 +9,6 @@ OMNITRADE_URL = 'wss://omnitrade.com:8080' class StreamingClient(Client): def __init__(self, callback, options = {}): - global OMNITRADE_URL super(StreamingClient, self).__init__(options) self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else OMNITRADE_URL self.logger = options['logger'] if 'logger' in options.keys() else logging From 2ca79473844411f32661dd836f8af9aaf58b0b20 Mon Sep 17 00:00:00 2001 From: Gabriel Baldao Date: Fri, 21 Feb 2020 16:27:27 -0300 Subject: [PATCH 15/21] update requirements --- requirements.txt | 50 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/requirements.txt b/requirements.txt index d00e9f4..a8f1dbc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,46 @@ -ast -logging -websocket -requests +asn1crypto==0.24.0 +AST==0.0.2 +asyncio==3.4.3 +bleach==3.1.1 +certifi==2019.11.28 +chardet==3.0.4 +crypto==1.4.1 +cryptography==2.1.4 +docutils==0.16 +enum34==1.1.6 +funcsigs==1.0.2 +gevent==1.4.0 +greenlet==0.4.15 +hashlib==20081119 +http==0.2 +idna==2.9 +ipaddress==1.0.17 +keyring==10.6.0 +keyrings.alt==3.0 +logging==0.4.9.6 +mock==3.0.5 +Naked==0.1.31 +nose==1.3.7 +omnitrade-client==0.1 +omnitradeClient==0.2 +pkginfo==1.5.0.1 +pycrypto==2.6.1 +Pygments==2.5.2 +pygobject==3.26.1 +PyTestStub==0.0.4 +python-apt==1.6.5+ubuntu0.2 +pyxdg==0.25 +PyYAML==5.3 +readme-renderer==24.0 +requests==2.23.0 +requests-mock==1.7.0 +requests-toolbelt==0.9.1 +SecretStorage==2.3.1 +shellescape==3.8.1 +six==1.14.0 +tqdm==4.43.0 +twine==1.15.0 +urllib3==1.25.8 +webencodings==0.5.1 +websocket==0.2.1 +websocket-client==0.57.0 From 1a87a50755b11ae455d5368decf36c90becdc1c5 Mon Sep 17 00:00:00 2001 From: Gabriel Baldao Date: Fri, 21 Feb 2020 17:01:16 -0300 Subject: [PATCH 16/21] update readme to websocket application --- README.md | 18 +++++++++++++----- setup.py | 1 - 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 818eec8..47a7336 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # client-py - ## Install ```console @@ -41,20 +40,20 @@ client_public.get_public('/api/v2/markets') When using the private client, you also have to specify your access and private keys in the instantiation: -```ruby +```python private_client = Client({ access_key: 'your_access_key', secret_key: 'your_secret_key' }) ``` You can also set a timeout and/or endpoit by adding the arguments: -```ruby +```python private_client = Client({ access_key: 'your_access_key', secret_key: 'your_secret_key', timeout: 60, endpoint: 'https://omnitrade.io/' }) ``` #### .get Use **`.get`** to make a GET request to an URL, you can also set the required arguments, as the following example: -```ruby +```python private_client.get('/api/v2/orders', { market: 'btcbrl' }) ``` @@ -62,10 +61,19 @@ private_client.get('/api/v2/orders', { market: 'btcbrl' }) Use **`.post`** to make a POST request to an URL, you can also set the required arguments, as the following example: -```ruby +```python private_client.post('/api/v2/order', { market: 'btcbrl', side: 'buy', volume: '0.42', price: '4200.0' }) ``` +### WebSocket +------ + +```python +streaming_client = StreamingClient(callbackFunction, {'access_key': '123456', 'secret_key': '123412'}) +``` + +This `callbackFunction` must to receive one parameter. + ## Licence OmniTrade (C) All Rights Reserved. diff --git a/setup.py b/setup.py index ef1a03f..12142bb 100755 --- a/setup.py +++ b/setup.py @@ -1,4 +1,3 @@ - from setuptools import find_packages from setuptools import setup From 3b8a02810062e1accc47c4bbd25eabd555af843e Mon Sep 17 00:00:00 2001 From: Gabriel Baldao Date: Thu, 27 Feb 2020 10:28:21 -0300 Subject: [PATCH 17/21] add client tests and update to python3 --- README.md | 17 ++-- requirements.txt | 114 +++++++++++++++++++----- setup.py | 10 ++- src/omnitradeClient/auth.py | 16 ++-- src/omnitradeClient/client.py | 14 +-- src/omnitradeClient/ordered_dict.py | 7 +- src/omnitradeClient/streaming_client.py | 4 +- src/tests/test_auth.py | 12 +-- src/tests/test_client.py | 46 ++++++---- src/tests/test_ordered_dict.py | 3 +- 10 files changed, 168 insertions(+), 75 deletions(-) diff --git a/README.md b/README.md index 47a7336..dcc9041 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,7 @@ ## Install -```console -pip install git+https://github.com/OmniTrade/client-py.git -``` + ## Usage @@ -17,6 +15,9 @@ from omnitradeClient import StreamingClient ``` You can use both the public or private API. +#### Note: + +Every http requests will returns a `` object, so use that as you want. ### Public ------ @@ -41,20 +42,20 @@ client_public.get_public('/api/v2/markets') When using the private client, you also have to specify your access and private keys in the instantiation: ```python -private_client = Client({ access_key: 'your_access_key', secret_key: 'your_secret_key' }) +private_client = Client(access_key = 'your_access_key', secret_key = 'your_secret_key') ``` You can also set a timeout and/or endpoit by adding the arguments: ```python -private_client = Client({ access_key: 'your_access_key', secret_key: 'your_secret_key', timeout: 60, endpoint: 'https://omnitrade.io/' }) +private_client = Client(access_key = 'your_access_key', secret_key = 'your_secret_key', timeout = 60, endpoint = 'https://omnitrade.io/') ``` #### .get Use **`.get`** to make a GET request to an URL, you can also set the required arguments, as the following example: ```python -private_client.get('/api/v2/orders', { market: 'btcbrl' }) +private_client.get('/api/v2/orders', market = 'btcbrl') ``` #### .post @@ -62,14 +63,14 @@ private_client.get('/api/v2/orders', { market: 'btcbrl' }) Use **`.post`** to make a POST request to an URL, you can also set the required arguments, as the following example: ```python -private_client.post('/api/v2/order', { market: 'btcbrl', side: 'buy', volume: '0.42', price: '4200.0' }) +private_client.post('/api/v2/order', market = 'btcbrl', side = 'buy', volume = '0.42', price = '4200.0') ``` ### WebSocket ------ ```python -streaming_client = StreamingClient(callbackFunction, {'access_key': '123456', 'secret_key': '123412'}) +streaming_client = StreamingClient(callbackFunction, access_key = '123456', secret_key = '123412') ``` This `callbackFunction` must to receive one parameter. diff --git a/requirements.txt b/requirements.txt index a8f1dbc..bc1f38b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,46 +1,112 @@ +alembic==0.9.3.dev0 +apt-xapian-index==0.47 +apturl==0.5.2 asn1crypto==0.24.0 -AST==0.0.2 -asyncio==3.4.3 -bleach==3.1.1 +astroid==2.3.3 +Babel==2.4.0 +beautifulsoup4==4.6.0 +blinker==1.4 +Brlapi==0.6.6 certifi==2019.11.28 chardet==3.0.4 -crypto==1.4.1 +click==6.7 +colorama==0.3.7 +command-not-found==0.3 cryptography==2.1.4 -docutils==0.16 -enum34==1.1.6 -funcsigs==1.0.2 +cupshelpers==1.0 +defer==1.0.6 +distro-info===0.18ubuntu0.18.04.1 +evdev==0.7.0 +Flask==0.12.2 +Flask-BabelEx==0.9.3 +Flask-Compress==1.4.0 +Flask-Gravatar==0.4.2 +Flask-Login==0.4.0 +Flask-Mail==0.9.1 +Flask-Migrate==2.1.1 +Flask-Paranoid==0.2.0 +Flask-Principal==0.4.0 +Flask-Security==1.7.5 +Flask-SQLAlchemy==2.1 +Flask-WTF==0.14.2 gevent==1.4.0 greenlet==0.4.15 -hashlib==20081119 -http==0.2 +html5lib==0.999999999 +httplib2==0.9.2 idna==2.9 -ipaddress==1.0.17 +isort==4.3.21 +itsdangerous==0.24 +Jinja2==2.10 keyring==10.6.0 keyrings.alt==3.0 +language-selector==0.1 +launchpadlib==1.10.6 +lazr.restfulclient==0.13.5 +lazr.uri==1.0.3 +lazy-object-proxy==1.4.3 logging==0.4.9.6 -mock==3.0.5 -Naked==0.1.31 +louis==3.5.0 +lxml==4.2.1 +macaroonbakery==1.1.3 +Mako==1.0.7 +MarkupSafe==1.0 +mccabe==0.6.1 +mock==4.0.1 +netifaces==0.10.4 nose==1.3.7 +oauth==1.0.1 +olefile==0.45.1 omnitrade-client==0.1 omnitradeClient==0.2 -pkginfo==1.5.0.1 +paramiko==2.0.0 +passlib==1.7.1 +pexpect==4.2.1 +Pillow==5.1.0 +protobuf==3.0.0 +psutil==5.4.2 +psycopg2==2.8.4 +pyasn1==0.4.2 +pycairo==1.16.2 pycrypto==2.6.1 -Pygments==2.5.2 +pycups==1.9.73 pygobject==3.26.1 -PyTestStub==0.0.4 +pyinotify==0.9.6 +pylint==2.4.4 +pymacaroons==0.13.0 +PyNaCl==1.1.2 +pynotify==0.1.1 +pyOpenSSL==17.5.0 +pyRFC3339==1.0 python-apt==1.6.5+ubuntu0.2 +python-dateutil==2.6.1 +python-debian==0.1.32 +pytz==2018.3 pyxdg==0.25 -PyYAML==5.3 -readme-renderer==24.0 +PyYAML==3.12 +reportlab==3.4.0 requests==2.23.0 -requests-mock==1.7.0 -requests-toolbelt==0.9.1 +requests-unixsocket==0.1.5 +screen-resolution-extra==0.0.0 SecretStorage==2.3.1 -shellescape==3.8.1 +simple-websocket-server==0.4.0 +simplejson==3.13.2 six==1.14.0 -tqdm==4.43.0 -twine==1.15.0 +SQLAlchemy==1.1.11 +sqlparse==0.2.4 +sshtunnel==0.1.4 +system-service==0.3 +systemd-python==234 +typed-ast==1.4.1 +ubuntu-drivers-common==0.0.0 +ufw==0.36 +unattended-upgrades==0.1 urllib3==1.25.8 -webencodings==0.5.1 +wadllib==1.3.2 +webencodings==0.5 websocket==0.2.1 -websocket-client==0.57.0 +websockets==8.1 +Werkzeug==0.16.0 +wrapt==1.11.2 +WTForms==2.1 +xkit==0.0.0 +zope.interface==4.3.2 diff --git a/setup.py b/setup.py index 12142bb..87855c4 100755 --- a/setup.py +++ b/setup.py @@ -1,9 +1,16 @@ from setuptools import find_packages from setuptools import setup +from glob import glob +from os.path import basename +from os.path import dirname +from os.path import join +from os.path import splitext + + setup( name="omnitradeClient", - version="0.2", + version="0.1.0", license="MIT license", description="Python client for Omnitrade API", author="Omnitrade", @@ -11,6 +18,7 @@ url="https://github.com/OmniTrade/client-py", packages=find_packages("src"), package_dir={"": "src/"}, + py_modules=[splitext(basename(path))[0] for path in glob("src/omnitradeClient/*.py")], include_package_data=True, zip_safe=False, keywords=["omnitrade", "api"], diff --git a/src/omnitradeClient/auth.py b/src/omnitradeClient/auth.py index 142bb68..bfc4d44 100644 --- a/src/omnitradeClient/auth.py +++ b/src/omnitradeClient/auth.py @@ -1,5 +1,11 @@ +from platform import python_version +if '2.7' in python_version(): + import urllib +else: + import urllib.parse as urllib import hashlib -import urllib +import hmac +import time class Auth(object): def __init__(self, access_key, secret_key): @@ -7,11 +13,11 @@ def __init__(self, access_key, secret_key): self.secret_key = secret_key def signed_challenge(self, challenge): - signature = hashlib.pbkdf2_hmac('sha256', self.secret_key,"{access_key}{challenge}".format(access_key = self.access_key, challenge = challenge), 100000 ) + signature = hmac.new(str(self.secret_key).encode(),"{access_key}{challenge}".format(access_key=self.access_key, challenge=challenge).encode(), hashlib.sha256).hexdigest() return { 'auth': { 'access_key': self.access_key, 'answer': signature } } - def signed_params(self, verb, path, params = {}): + def signed_params(self, verb, path, **params): params = self.__format_params(params) signature = self.__sign(verb, path, urllib.urlencode(params)) @@ -19,10 +25,10 @@ def signed_params(self, verb, path, params = {}): return params def __sign(self, verb, path, params): - return hashlib.pbkdf2_hmac('sha256', self.secret_key, self.__payload(verb, path, params), 100000) + return hmac.new(self.secret_key.encode(), self.__payload(verb, path, params).encode(), hashlib.sha256).hexdigest() def __payload(self, verb, path, params): - return "#{verb}|#{path}|#{params}".format(verb = verb.upper(), path = path, params = params) + return "{verb}|{path}|{params}".format(verb = verb.upper(), path = path, params = params) def __format_params(self, params): params['access_key'] = self.access_key diff --git a/src/omnitradeClient/client.py b/src/omnitradeClient/client.py index 3864ec0..d6ec951 100644 --- a/src/omnitradeClient/client.py +++ b/src/omnitradeClient/client.py @@ -1,11 +1,15 @@ +from platform import python_version +if '2.7' in python_version(): + import urllib +else: + import urllib.parse as urllib import requests -import urllib from auth import Auth from ordered_dict import ordered_dict OMNITRADE_URL = 'https://omnitrade.io' class Client(object): - def __init__(self, options={}): + def __init__(self, **options): self.auth = None self.__setup_auth_keys(options) @@ -17,13 +21,13 @@ def get_public(self, path, params={}): return self.__get_request(uri, params) - def get(self, path, params={}): + def get(self, path, **params): self.__check_auth() uri, params = self.__parameters('GET',path, params) return self.__get_request(uri, params) - def post(self, path, params={}): + def post(self, path, **params): self.__check_auth() uri, params = self.__parameters('POST', path, params) @@ -50,7 +54,7 @@ def __post_request(self, uri, params): def __parameters(self, action, path, params): uri = '{endpoint}{path}'.format(endpoint=self.endpoint, path=path) - dict_params = self.auth.signed_params(action, path, params) if self.auth != None else params + dict_params = self.auth.signed_params(action, path, **params) if self.auth != None else params return uri, ordered_dict(dict_params) diff --git a/src/omnitradeClient/ordered_dict.py b/src/omnitradeClient/ordered_dict.py index 8abc375..bb0f488 100644 --- a/src/omnitradeClient/ordered_dict.py +++ b/src/omnitradeClient/ordered_dict.py @@ -1,7 +1,2 @@ def ordered_dict(dict_params): - params = map(lambda key,value: (key, value), dict_params.keys(), dict_params.values()) - params.sort(key=take_key) - return params - -def take_key(item): - return item[0] + return [(key, dict_params[key]) for key in sorted(dict_params.keys())] diff --git a/src/omnitradeClient/streaming_client.py b/src/omnitradeClient/streaming_client.py index 1395e28..742a944 100644 --- a/src/omnitradeClient/streaming_client.py +++ b/src/omnitradeClient/streaming_client.py @@ -8,8 +8,8 @@ OMNITRADE_URL = 'wss://omnitrade.com:8080' class StreamingClient(Client): - def __init__(self, callback, options = {}): - super(StreamingClient, self).__init__(options) + def __init__(self, callback, **options): + super(StreamingClient, self).__init__(**options) self.endpoint = options['endpoint'] if 'endpoint' in options.keys() else OMNITRADE_URL self.logger = options['logger'] if 'logger' in options.keys() else logging diff --git a/src/tests/test_auth.py b/src/tests/test_auth.py index c7735f5..25ee871 100644 --- a/src/tests/test_auth.py +++ b/src/tests/test_auth.py @@ -1,5 +1,5 @@ import unittest -from omnitradeClient.auth import Auth +from src.omnitradeClient.auth import Auth ACCESS_KEY = '123456' SECRET_KEY = '123456' @@ -9,12 +9,12 @@ def test_signed_challenge(self): subject = auth.signed_challenge('challenge') - self.assertEqual(subject.keys(), ['auth']) - self.assertEqual(subject['auth'].keys(), ['access_key', 'answer']) + self.assertEqual(list(subject.keys()), ['auth']) + self.assertEqual(list(subject['auth'].keys()), ['access_key', 'answer']) def test_signed_params(self): auth = Auth(ACCESS_KEY, SECRET_KEY) - subject = auth.signed_params('GET', 'api/v2/order_markets', { "volume": 0, "total": 0 }) - - self.assertEqual(subject.keys(), ['volume', 'access_key', 'tonce', 'total', 'signature']) + subject = auth.signed_params('GET', 'api/v2/order_markets', volume = 0, total = 0 ) + + self.assertEqual(sorted(subject.keys()), sorted(['volume', 'access_key', 'tonce', 'total', 'signature'])) diff --git a/src/tests/test_client.py b/src/tests/test_client.py index 6ebe82a..d71b048 100644 --- a/src/tests/test_client.py +++ b/src/tests/test_client.py @@ -1,33 +1,47 @@ import unittest import json -from nose.tools import assert_is_none, assert_list_equal -from mock import patch, Mock +from mock import patch -from omnitradeClient.client import Client +from src.omnitradeClient.client import Client OMNITRADE_URL = 'https://omnitrade.io' class TestClientMethods(unittest.TestCase): - - def test_get_public_valid_request(self): + @patch('src.omnitradeClient.client.requests.get') + def test_get_public_valid_request(self, mock_get): public_client = Client() market_path = '/api/v2/markets' - markets = [{"id": "btcbrl", "name": "BTC/BRL"}, {"id": "ltcbrl", "name": "LTC/BRL"}, {"id": "bchbrl", "name": "BCH/BRL"}, {"id": "btgbrl", "name": "BTG/BRL"}, {"id": "ethbrl", "name": "ETH/BRL"}, {"id": "dashbrl", "name": "DASH/BRL"}, {"id": "dcrbrl", "name": "DCR/BRL"}, {"id": "ltcbtc", "name": "LTC/BTC"}, {"id": "bchbtc", "name": "BCH/BTC"}, {"id": "btgbtc", "name": "BTG/BTC"}, {"id": "ethbtc", "name": "ETH/BTC"}, {"id": "dashbtc", "name": "DASH/BTC"}, {"id": "dcrbtc", "name": "DCR/BTC"}, {"id": "ltceth", "name": "LTC/ETH"}, {"id": "bcheth", "name": "BCH/ETH"}, {"id": "btgeth", "name": "BTG/ETH"}, {"id": "dasheth", "name": "DASH/ETH"}, {"id": "dcreth", "name": "DCR/ETH"}, {"id": "xrpbrl", "name": "XRP/BRL"}, {"id": "xrpbtc", "name": "XRP/BTC"}, {"id": "xrpeth", "name": "XRP/ETH"}, {"id": "mftbrl", "name": "MFT/BRL"}, {"id": "mftbtc", "name": "MFT/BTC"}, {"id": "mfteth", "name": "MFT/ETH"}, {"id": "btcusdc", "name": "BTC/USDC"}, {"id": "ltcusdc", "name": "LTC/USDC"}, {"id": "bchusdc", "name": "BCH/USDC"}, {"id": "btgusdc", "name": "BTG/USDC"}, {"id": "ethusdc", "name": "ETH/USDC"}, {"id": "dashusdc", "name": "DASH/USDC"}, {"id": "dcrusdc", "name": "DCR/USDC"}, {"id": "xrpusdc", "name": "XRP/USDC"}, {"id": "bnbbtc", "name": "BNB/BTC"}, {"id": "bnbusdc", "name": "BNB/USDC"}] + markets = [{"id": "btcbrl", "name": "BTC/BRL"}, {"id": "ltcbrl", "name": "LTC/BRL"}, {"id": "bchbrl", "name": "BCH/BRL"}] + + mock_get.return_value.status_code = 200 + mock_get.return_value.json.return_value = markets response = public_client.get_public(market_path) self.assertEqual(response.json(), markets) + self.assertEqual(response.status_code, 200) + + + @patch('src.omnitradeClient.client.requests.get') + def test_get_private_valid_request(self, mock_get): + client = Client(access_key='123456', secret_key='123456') + order_path = '/api/v2/markets' + orders = [{'id': 1917314, 'side': 'buy', 'ord_type': 'limit', 'price': '40000.0', 'avg_price': '40000.0', 'state': 'wait', 'market': 'btcbrl', 'created_at': '2019-08-21T17:06:11-03:00', 'volume': '0.5', 'remaining_volume': '0.4975', 'executed_volume': '0.0025', 'trades_count': 1}, {'id': 1917316, 'side': 'sell', 'ord_type': 'limit', 'price': '45000.0', 'avg_price': '45000.0', 'state': 'wait', 'market': 'btcbrl', 'created_at': '2019-08-21T17:07:32-03:00', 'volume': '0.6', 'remaining_volume': '0.597', 'executed_volume': '0.003', 'trades_count': 1}] + + mock_get.return_value.json.return_value = orders + + response = client.get('api/v2/markets', market = 'btcbrl',price = '10',side = 'buy',tonce = 123,volume = 1) + + self.assertEqual(response.json(), orders) + + @patch('src.omnitradeClient.client.requests.post') + def test_post_request(self, mock_post): + order = [{'id': 1917316, 'side': 'sell', 'ord_type': 'limit', 'price': '45000.0', 'avg_price': '45000.0', 'state': 'wait', 'market': 'btcbrl', 'created_at': '2019-08-21T17:07:32-03:00', 'volume': '0.6', 'remaining_volume': '0.597', 'executed_volume': '0.003', 'trades_count': 1}] - def test_post_request(self): - access_key = 'FUkESEYRJmO42MfqXcgJfm73GfIMw61qogExtcX7' #TODO improve this requests tests + client = Client(access_key = '123456', secret_key = '123456') - client = Client({'access_key': access_key,'secret_key': '123456'}) - response = client.post('/api/v2/orders/clear', {'side': 'sell' }) + mock_post.return_value.json.return_value = order - self.assertEqual(response.status_code, 201) + response = client.post('/api/v2/orders/clear', side = 'sell') - def test_post_request(self): - access_key = 'FUkESEYRJmO42MfqXcgJfm73GfIMw61qogExtcX7' #TODO improve this requests tests + self.assertEqual(response.json(), order) - client = Client({'access_key': access_key,'secret_key': '123456'}) - response = client.get('/api/v2/order', {'id': 1 }) - self.assertEqual(response.status_code, 404) diff --git a/src/tests/test_ordered_dict.py b/src/tests/test_ordered_dict.py index 61f334b..4d96820 100644 --- a/src/tests/test_ordered_dict.py +++ b/src/tests/test_ordered_dict.py @@ -1,5 +1,5 @@ import unittest -from omnitradeClient.ordered_dict import ordered_dict +from src.omnitradeClient.ordered_dict import ordered_dict class TestOrderedDictMethods(unittest.TestCase): @@ -7,4 +7,3 @@ def test_ordered_dict(self): dictionary = { 'a': 1, 'b': 2, 'c': 3} self.assertEqual(ordered_dict(dictionary), [('a', 1),('b', 2),('c', 3)]) - From ae26104a86bfc77c3316f80f21de6c417315d59d Mon Sep 17 00:00:00 2001 From: Gabriel Baldao Date: Thu, 27 Feb 2020 13:26:28 -0300 Subject: [PATCH 18/21] fix imports --- src/omnitradeClient/__init__.py | 4 ++-- src/omnitradeClient/client.py | 4 ++-- src/omnitradeClient/streaming_client.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/omnitradeClient/__init__.py b/src/omnitradeClient/__init__.py index df616da..634b791 100644 --- a/src/omnitradeClient/__init__.py +++ b/src/omnitradeClient/__init__.py @@ -1,2 +1,2 @@ -from client import Client -from streaming_client import StreamingClient +from .client import Client +from .streaming_client import StreamingClient diff --git a/src/omnitradeClient/client.py b/src/omnitradeClient/client.py index d6ec951..0808b25 100644 --- a/src/omnitradeClient/client.py +++ b/src/omnitradeClient/client.py @@ -4,8 +4,8 @@ else: import urllib.parse as urllib import requests -from auth import Auth -from ordered_dict import ordered_dict +from .auth import Auth +from .ordered_dict import ordered_dict OMNITRADE_URL = 'https://omnitrade.io' class Client(object): diff --git a/src/omnitradeClient/streaming_client.py b/src/omnitradeClient/streaming_client.py index 742a944..f23b01d 100644 --- a/src/omnitradeClient/streaming_client.py +++ b/src/omnitradeClient/streaming_client.py @@ -2,7 +2,7 @@ import logging import json import ast -from client import Client +from .client import Client logging.basicConfig(level=logging.INFO) From 40536d81133601a74e96915d330d7ec4f0da353c Mon Sep 17 00:00:00 2001 From: Gabriel Baldao Date: Thu, 27 Feb 2020 14:26:16 -0300 Subject: [PATCH 19/21] update readme, install step --- README.md | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dcc9041..e258da8 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,24 @@ # client-py -## Install +## Install (Python 3) +To install this package you should execute the command below. (but this is in tests yet) +```console +pip install git+https://github.com/OmniTrade/client-py.git +``` +Another way to install this package, you should clone this repository with: + +```console +git clone https://github.com/OmniTrade/client-py.git +cd client-py +``` + +and to install, please execute: + +```console +python3 setup.py install +``` ## Usage @@ -67,7 +83,7 @@ private_client.post('/api/v2/order', market = 'btcbrl', side = 'buy', volume = ' ``` ### WebSocket ------- +------ ```python streaming_client = StreamingClient(callbackFunction, access_key = '123456', secret_key = '123412') From 0487ffdd6afd1f6af06e71817d67ae281c6862ec Mon Sep 17 00:00:00 2001 From: Gabriel Baldao Date: Thu, 27 Feb 2020 15:23:28 -0300 Subject: [PATCH 20/21] update omnitrade url --- src/omnitradeClient/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/omnitradeClient/client.py b/src/omnitradeClient/client.py index 0808b25..a20d814 100644 --- a/src/omnitradeClient/client.py +++ b/src/omnitradeClient/client.py @@ -7,7 +7,7 @@ from .auth import Auth from .ordered_dict import ordered_dict -OMNITRADE_URL = 'https://omnitrade.io' +OMNITRADE_URL = 'https://omnitrade.io/' class Client(object): def __init__(self, **options): self.auth = None From 0c542f24e9fdb972446ca8c2cc8e89c5eb7cbc9d Mon Sep 17 00:00:00 2001 From: Gabriel Baldao Date: Mon, 2 Mar 2020 11:39:18 -0300 Subject: [PATCH 21/21] fix signature --- src/omnitradeClient/auth.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/omnitradeClient/auth.py b/src/omnitradeClient/auth.py index bfc4d44..6136ab6 100644 --- a/src/omnitradeClient/auth.py +++ b/src/omnitradeClient/auth.py @@ -6,6 +6,7 @@ import hashlib import hmac import time +from .ordered_dict import ordered_dict class Auth(object): def __init__(self, access_key, secret_key): @@ -18,9 +19,9 @@ def signed_challenge(self, challenge): return { 'auth': { 'access_key': self.access_key, 'answer': signature } } def signed_params(self, verb, path, **params): - params = self.__format_params(params) + sign_params = self.__format_params(params) - signature = self.__sign(verb, path, urllib.urlencode(params)) + signature = self.__sign(verb, path, urllib.urlencode(sign_params)) params['signature'] = signature return params @@ -33,4 +34,4 @@ def __payload(self, verb, path, params): def __format_params(self, params): params['access_key'] = self.access_key params['tonce'] = int(time.time()) * 1000 - return params + return ordered_dict(params)