This code works well in windows, but when I move it to my vps (ubuntu16.04, python3.6), there is some problem.
import json
import time
import threading
import websocket
import requests
from datetime import datetime, timedelta, timezone
def run_in_thread(sec):
def _wrapper(func):
def __wrapper(self, *args, **kwargs):
timer = threading.Timer(sec, func, [self, *args])
timer.start()
self._ws.on_open = self.on_open
self._ws.run_forever()
return self._result
return __wrapper
return _wrapper
class CybexHistoryAPI(object):
def __init__(self, ws_endp):
self._endpoint = ws_endp
self.reset()
def reset(self):
self._ws = websocket.WebSocketApp(self._endpoint,
on_message = self.on_message,
on_error = self.on_error,
on_close = self.on_close)
self._login_api_id = -1
self._history_api_id = -1
self._api_is_ready = False
self._call_id = 1
def _send_msg(self, params):
call = {"id": self._call_id, "method": "call",
"params": params}
self._ws.send(json.dumps(call))
self._call_id += 1
def on_open(self, ws):
self._send_msg([1, "login", ["",""]])
self._call_id = 1
def on_error(self, ws, error):
print('Remote node send an error [{}]'.format(error))
def on_close(self, ws):
print('Remote node closed our connection')
def on_message(self, ws, msg):
print(msg)
if self._login_api_id < 0:
result = json.loads(msg)
self._login_api_id = result['id']
self._send_msg([self._login_api_id, "history", []])
elif self._history_api_id < 0:
result = json.loads(msg)
self._history_api_id = result['result']
self._api_is_ready = True
else:
self._result = json.loads(msg)['result']
self._ws.close()
self.reset()
@run_in_thread(0.01)
def get_account_history(self, account_id, stop, limit, start):
while not self._api_is_ready:
time.sleep(0.01)
self._send_msg([self._history_api_id, "get_account_history",
[account_id, stop, limit, start]])
@run_in_thread(0.01)
def get_market_history(self, base_id, quote_id, ts, start, end):
while not self._api_is_ready:
time.sleep(0.01)
self._send_msg([self._history_api_id, "get_market_history",
[base_id, quote_id, ts, start, end]])
@run_in_thread(0.01)
def get_fill_order_history(self, base_id, quote_id, limit):
while not self._api_is_ready:
time.sleep(0.01)
self._send_msg([self._history_api_id, "get_fill_order_history",
[base_id, quote_id, limit]])
def scan_account(acc_id, max_len = 100):
api = CybexHistoryAPI('wss://shanghai.51nebula.com')
start = 0
tot_len = 0
while tot_len < max_len:
print('start at 1.11.{}'.format(start))
ret = api.get_account_history(acc_id, '1.11.1', 100, '1.11.' + str(start))
if len(ret) == 0 or int(ret[0]['id'].split('.')[-1]) == start:
break
tot_len += len(ret)
print('got {}'.format(len(ret)))
print('end at {}'.format(ret[-1]['id']))
#print(json.dumps(ret, indent=2))
start = int(ret[-1]['id'].split('.')[-1]) - 1
print(tot_len)
return
def run_test():
scan_account('1.2.38696')
if __name__ == '__main__':
run_test()
I get the following error:
Traceback (most recent call last):
File "ListenTransferRecord.py", line 197, in <module>
run_test()
File "ListenTransferRecord.py", line 186, in run_test
respone = scan_account(accountID,10)
File "ListenTransferRecord.py", line 147, in scan_account
ret = api.get_account_history(acc_id, '1.11.1', 100, '1.11.' + str(start))
File "ListenTransferRecord.py", line 71, in __wrapper
return self._result
AttributeError: 'CybexHistoryAPI' object has no attribute '_result'
I don't understand why it can work well in windows but not in ubuntu.
And I've tried run some simple code in my VPS(ubuntu) to test if the python environment is ok.
I've tried reinstalling all the modules of this code import. But it is still not working.
The error you get just happens to trigger a bug that was already there - self._result
is only set on a specific condition (in the else
branch in the on_message
method) but you unconditionnally access it in your decorator. For some reason (which we can't tell without much more details - actually chances are no one can tell without testing the code in your exact environment) you never (so far) stumbled on this case when running the code on Window, but the bug itself isn't dependent of the environment itself. The fix here is quite simple: just make sure the _result
attribute is always set (eventually to some sentinel value like None
:
def on_message(self, ws, msg):
print(msg)
self._result = None # default value
if self._login_api_id < 0:
result = json.loads(msg)
self._login_api_id = result['id']
self._send_msg([self._login_api_id, "history", []])
elif self._history_api_id < 0:
result = json.loads(msg)
self._history_api_id = result['result']
self._api_is_ready = True
else:
self._result = json.loads(msg)['result']
self._ws.close()
self.reset()
As to why you have different behaviour on different environment, this can come from so many reasons that one can't be sure to list them all... it might come from network latency and synchronisation issues between your threads, OS specific implementation details, phase of the moon, whatever, and as I said those are mostly the kind of issues that can be just impossible to troubleshout without direct access to both your environments.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.