def sign(self, method='GET', params=None, headers=None): if self.__api_key == '' or self.__secret_key == '': raise AuthenticationError('Api key and secret key must not be empty.') timestamp = str(Utils.milliseconds()) if self.use_server_time: timestamp = str(self.get_server_time()) param = '' if method == 'GET' and params: for k in sorted(params): param += k + str(params[k]) elif method == 'POST' and params: param = json.dumps(params, separators=(',', ':')) sig_str = self.__api_key + timestamp + param + self.__secret_key signature = hashlib.md5(sig_str.encode('utf-8')).hexdigest() new_headers = { 'Apiid': self.__api_key, 'Timestamp': timestamp, 'Clienttype': "5", 'Sign': signature } if headers: self.extend(new_headers, headers) if hasattr(self, "_ApiClient__passphrase"): new_headers['Passphrase'] = hashlib.md5((timestamp + self.__passphrase).encode('utf-8')).hexdigest() return new_headers
def on_open(self, ws): self.logger.info("[Sub][" + str(self.id) + "] Connected to server") self.ws = ws self.last_receive_time = Utils.milliseconds() self.state = ConnectionState.CONNECTED if self.request.subscription_handler is not None: self.request.subscription_handler(self) self.__watch_dog.on_connection_created(self) return
def on_message(self, message): self.last_receive_time = Utils.milliseconds() if isinstance(message, str): # print("RX string : ", message) json_wrapper = json.loads(message) elif isinstance(message, bytes): # print("RX bytes: " + gzip.decompress(message).decode("utf-8")) json_wrapper = json.load(gzip.decompress(message).decode("utf-8")) else: self.logger.error("[Sub][" + str(self.id) + "] RX unknown type : ", type(message)) return if 'code' in json_wrapper: print(json_wrapper) if '5021' == json_wrapper['code'] and 'PING' == json_wrapper[ 'action']: return self.on_error(json_wrapper) return res = None try: if self.request.json_parser is not None: res = self.request.json_parser(json_wrapper) except Exception as e: self.logger.error( "[Sub][" + str(self.id) + "] Failed to parse server's response", e) self.on_error("Failed to parse server's response: " + str(e)) try: if self.request.update_callback is not None: self.request.update_callback(res) except Exception as e: self.logger.error( "[Sub][" + str(self.id) + "] Failed to call the callback method", e) self.on_error( "Process error: " + str(e) + " You should capture the exception in your error handler")
def watch_dog_job(*args): watch_dog_instance = args[0] for connection in watch_dog_instance.connection_list: if connection.state == ConnectionState.CONNECTED: if watch_dog_instance.is_auto_connect: ts = Utils.milliseconds() - connection.last_receive_time if ts > watch_dog_instance.receive_limit_ms: watch_dog_instance.logger.warning( "[Sub][" + str(connection.id) + "] No response from server") connection.re_connect_in_delay( watch_dog_instance.connection_delay_failure) elif connection.in_delay_connection(): watch_dog_instance.logger.warning("[Sub] call re_connect") connection.re_connect() pass elif connection.state == ConnectionState.CLOSED_ON_ERROR: if watch_dog_instance.is_auto_connect: connection.re_connect_in_delay( watch_dog_instance.connection_delay_failure) pass
def request(self, path, api='public', method="GET", params={}, headers=None): if self.enable_rate_limit: self.throttle() self.last_rest_request_Timestamp = Utils.milliseconds() if api == 'private': headers = self.sign(method, params, headers) # 设置路径参数 path = path.format(**params) api = self.urls['market_api'] if path.find('api/data/v1') >= 0 else self.urls['api'] url = api + path response = None try: if self.verbose: print('method:', method, ', url :', url, ", request:", params) if method == "GET": response = requests.get(url, params=params, headers=headers) else: response = requests.post(url, data=json.dumps(params, separators=(',', ':')), headers=headers) if self.verbose: print('method:', method, ', url:', url, ", response:", response.text) self.handle_fail(response, method, url) return response.json()['datas'] except Timeout as e: self.raise_error(RequestTimeout, method, url, e) except ValueError as e: self.raise_error(BadResponse, method, url, e, response.text) except KeyError as e: self.raise_error(BadResponse, method, url, e, response.text)
def throttle(self): now = float(Utils.milliseconds()) elapsed = now - self.last_rest_request_Timestamp if elapsed < self.rate_limit: delay = self.rate_limit - elapsed time.sleep(delay / 1000.0)