def create_client(self, service_name, region_name, is_secure=True, endpoint_url=None, verify=None, credentials=None, scoped_config=None, api_version=None, client_config=None): responses = self._event_emitter.emit( 'choose-service-name', service_name=service_name) service_name = first_non_none_response(responses, default=service_name) service_model = self._load_service_model(service_name, api_version) cls = self._create_client_class(service_name, service_model) endpoint_bridge = ClientEndpointBridge( self._endpoint_resolver, scoped_config, client_config, service_signing_name=service_model.metadata.get('signingName')) client_args = self._get_client_args( service_model, region_name, is_secure, endpoint_url, verify, credentials, scoped_config, client_config, endpoint_bridge) service_client = cls(**client_args) self._register_retries(service_client) self._register_s3_events( service_client, endpoint_bridge, endpoint_url, client_config, scoped_config) self._register_endpoint_discovery( service_client, endpoint_url, client_config ) return service_client
def _needs_retry(self, attempts, operation_model, request_dict, response=None, caught_exception=None): service_id = operation_model.service_model.service_id.hyphenize() event_name = 'needs-retry.%s.%s' % (service_id, operation_model.name) responses = self._event_emitter.emit(event_name, response=response, endpoint=self, operation=operation_model, attempts=attempts, caught_exception=caught_exception, request_dict=request_dict) handler_response = first_non_none_response(responses) if handler_response is None: return False else: # Request needs to be retried, and we need to sleep # for the specified number of times. logger.debug( "Response received to retry, sleeping for " "%s seconds", handler_response) time.sleep(handler_response) return True
def test_first_non_none(self): correct_value = 'correct_value' wrong_value = 'wrong_value' # The responses are tuples of (handler, response), # and we don't care about the handler so we just use a value of # None. responses = [(None, None), (None, correct_value), (None, wrong_value)] self.assertEqual(first_non_none_response(responses), correct_value)
def _do_get_response(self, request, operation_model, context): try: logger.debug("Sending http request: %s", request) history_recorder.record( 'HTTP_REQUEST', { 'method': request.method, 'headers': request.headers, 'streaming': operation_model.has_streaming_input, 'url': request.url, 'body': request.body }) service_id = operation_model.service_model.service_id.hyphenize() event_name = 'before-send.%s.%s' % (service_id, operation_model.name) responses = self._event_emitter.emit(event_name, request=request) http_response = first_non_none_response(responses) if http_response is None: http_response = self._send(request) except HTTPClientError as e: return (None, e) except Exception as e: logger.debug("Exception received when sending HTTP request.", exc_info=True) return (None, e) # This returns the http_response and the parsed_data. response_dict = convert_to_response_dict(http_response, operation_model) handle_checksum_body( http_response, response_dict, context, operation_model, ) http_response_record_dict = response_dict.copy() http_response_record_dict['streaming'] = \ operation_model.has_streaming_output history_recorder.record('HTTP_RESPONSE', http_response_record_dict) protocol = operation_model.metadata['protocol'] parser = self._response_parser_factory.create_parser(protocol) parsed_response = parser.parse(response_dict, operation_model.output_shape) # Do a second parsing pass to pick up on any modeled error fields # NOTE: Ideally, we would push this down into the parser classes but # they currently have no reference to the operation or service model # The parsers should probably take the operation model instead of # output shape but we can't change that now if http_response.status_code >= 300: self._add_modeled_error_fields( response_dict, parsed_response, operation_model, parser, ) history_recorder.record('PARSED_RESPONSE', parsed_response) return (http_response, parsed_response), None
def _do_get_response(self, request, operation_model): try: logger.debug("Sending http request: %s", request) history_recorder.record( 'HTTP_REQUEST', { 'method': request.method, 'headers': request.headers, 'streaming': operation_model.has_streaming_input, 'url': request.url, 'body': request.body }) service_id = operation_model.service_model.service_id.hyphenize() event_name = 'before-send.%s.%s' % (service_id, operation_model.name) responses = self._event_emitter.emit(event_name, request=request) http_response = first_non_none_response(responses) if http_response is None: http_response = self._send(request) except HTTPClientError as e: return (None, e) except Exception as e: logger.debug("Exception received when sending HTTP request.", exc_info=True) return (None, e) # This returns the http_response and the parsed_data. response_dict = convert_to_response_dict(http_response, operation_model) http_response_record_dict = response_dict.copy() http_response_record_dict['streaming'] = \ operation_model.has_streaming_output history_recorder.record('HTTP_RESPONSE', http_response_record_dict) protocol = operation_model.metadata['protocol'] parser = self._response_parser_factory.create_parser(protocol) parsed_response = parser.parse(response_dict, operation_model.output_shape) history_recorder.record('PARSED_RESPONSE', parsed_response) return (http_response, parsed_response), None
def _emit_api_params(self, api_params, operation_model, context): # Given the API params provided by the user and the operation_model # we can serialize the request to a request_dict. operation_name = operation_model.name # Emit an event that allows users to modify the parameters at the # beginning of the method. It allows handlers to modify existing # parameters or return a new set of parameters to use. service_id = self._service_model.service_id.hyphenize() responses = self.meta.events.emit( 'provide-client-params.{service_id}.{operation_name}'.format( service_id=service_id, operation_name=operation_name), params=api_params, model=operation_model, context=context) api_params = first_non_none_response(responses, default=api_params) event_name = ( 'before-parameter-build.{service_id}.{operation_name}') self.meta.events.emit( event_name.format( service_id=service_id, operation_name=operation_name), params=api_params, model=operation_model, context=context) return api_params
def _convert_to_request_dict(self, api_params, operation_model, context=None): # Given the API params provided by the user and the operation_model # we can serialize the request to a request_dict. operation_name = operation_model.name # Emit an event that allows users to modify the parameters at the # beginning of the method. It allows handlers to modify existing # parameters or return a new set of parameters to use. responses = self.meta.events.emit( 'provide-client-params.{endpoint_prefix}.{operation_name}'.format( endpoint_prefix=self._service_model.endpoint_prefix, operation_name=operation_name), params=api_params, model=operation_model, context=context) api_params = first_non_none_response(responses, default=api_params) event_name = ( 'before-parameter-build.{endpoint_prefix}.{operation_name}') self.meta.events.emit(event_name.format( endpoint_prefix=self._service_model.endpoint_prefix, operation_name=operation_name), params=api_params, model=operation_model, context=context) request_dict = self._serializer.serialize_to_request( api_params, operation_model) prepare_request_dict(request_dict, endpoint_url=self._endpoint.host, user_agent=self._client_config.user_agent, context=context) return request_dict
def test_default_value_if_non_none_found(self): responses = [(None, None), (None, None)] # If no response is found and a default value is passed in, it will # be returned. self.assertEqual( first_non_none_response(responses, default='notfound'), 'notfound')
def test_all_none(self): self.assertIsNone(first_non_none_response([]))
def emit_first_non_none_response(self, event_name, **kwargs): responses = self._events.emit(event_name, **kwargs) return first_non_none_response(responses)