def _parse_main_response(self, response_raw, subrequests): self.log.debug('Parsing main RPC response...') if response_raw.status_code == 403: raise ServerSideAccessForbiddenException("Seems your IP Address is banned or something else went badly wrong...") elif response_raw.status_code == 502: raise ServerBusyOrOfflineException("502: Bad Gateway") elif response_raw.status_code != 200: error = 'Unexpected HTTP server response - needs 200 got {}'.format(response_raw.status_code) self.log.warning(error) self.log.debug('HTTP output: \n%s', response_raw.content.decode('utf-8')) raise UnexpectedResponseException(error) if response_raw.content is None: self.log.warning('Empty server response!') return False response_proto = ResponseEnvelope() try: response_proto.ParseFromString(response_raw.content) except message.DecodeError as e: self.log.warning('Could not parse response: %s', e) return False self.log.debug('Protobuf structure of rpc response:\n\r%s', response_proto) try: self.log.debug('Decode raw over protoc (protoc has to be in your PATH):\n\r%s', self.decode_raw(response_raw.content).decode('utf-8')) except: self.log.debug('Error during protoc parsing - ignored.') response_proto_dict = protobuf_to_dict(response_proto) response_proto_dict = self._parse_sub_responses(response_proto, subrequests, response_proto_dict) return response_proto_dict
def call(self, max_retry=15): request_callers = self._pop_request_callers() if not self.can_call(): return False # currently this is never ran, exceptions are raised before request_timestamp = None api_req_method_list = self._req_method_list result = None try_cnt = 0 throttling_retry = 0 unexpected_response_retry = 0 while True: request_timestamp = self.throttle_sleep() # self._call internally clear this field, so save it self._req_method_list = [ req_method for req_method in api_req_method_list ] should_throttle_retry = False should_unexpected_response_retry = False try: result = self._call() except ServerSideRequestThrottlingException: should_throttle_retry = True except UnexpectedResponseException: should_unexpected_response_retry = True if should_throttle_retry: throttling_retry += 1 if throttling_retry >= max_retry: raise ServerSideRequestThrottlingException( 'Server throttled too many times') sleep(1) # huge sleep ? continue # skip response checking if should_unexpected_response_retry: unexpected_response_retry += 1 if unexpected_response_retry >= 5: self.logger.warning( 'Server is not responding correctly to our requests. Waiting for 30 seconds to reconnect.' ) sleep(30) else: sleep(2) continue if not self.is_response_valid(result, request_callers): try_cnt += 1 if try_cnt > 3: self.logger.warning( 'Server seems to be busy or offline - try again - {}/{}' .format(try_cnt, max_retry)) if try_cnt >= max_retry: raise ServerBusyOrOfflineException() sleep(1) else: break self.last_api_request_time = request_timestamp return result
def _make_rpc(self, endpoint, request_proto_plain): self.log.debug('Execution of RPC') request_proto_serialized = request_proto_plain.SerializeToString() try: http_response = self._session.post(endpoint, data=request_proto_serialized) except requests.exceptions.ConnectionError as e: raise ServerBusyOrOfflineException(e) return http_response
def _make_rpc(self, endpoint, request_proto_plain): self.log.debug('Execution of RPC') request_proto_serialized = request_proto_plain.SerializeToString() #print binascii.hexlify(request_proto_serialized) try: http_response = self._session.post(endpoint, data=request_proto_serialized, timeout=30) except (requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e: raise ServerBusyOrOfflineException(e) return http_response