def test_make_post_request_to_ai_platform_404_error( self, mock_request_header, mock_post_func): mock_request_header.return_value = {} mock_response = mock.Mock(spec=MockResponse) type(mock_response()).status_code = mock.PropertyMock(return_value=404) mock_post_func.return_value = mock_response() with self.assertRaisesRegex( ValueError, ('Target URI .* returns HTTP 404 error.\n' 'Please check if the project, model, and version names ' 'are given correctly.')): http_utils.make_post_request_to_ai_platform( 'uri/test_uri', {'data': 123})
def test_make_post_request_to_ai_platform_other_erors( self, mock_request_header, mock_post_func): mock_request_header.return_value = {} mock_response = mock.Mock(spec=MockResponse) type(mock_response()).status_code = mock.PropertyMock(return_value=403) type(mock_response()).text = mock.PropertyMock( return_value='test error') mock_post_func.return_value = mock_response() with self.assertRaisesRegex(ValueError, ('Target URI .* returns HTTP 403 error.\n' 'Please check the raw error message: \n' 'test error')): http_utils.make_post_request_to_ai_platform( 'uri/test_uri', {'data': 123})
def test_make_post_request_to_ai_platform(self, mock_request_header, mock_post_func): mock_request_header.return_value = {} mock_response = mock.Mock(spec=MockResponse) type(mock_response()).status_code = mock.PropertyMock(return_value=200) mock_response().json.return_value = 'results' mock_post_func.return_value = mock_response() res = http_utils.make_post_request_to_ai_platform( 'uri/test_uri', {'data': 123}) self.assertTrue(mock_post_func.called) self.assertEqual(res, 'results')
def predict(self, instances, timeout_ms=constants.DEFAULT_TIMEOUT): """A method to call prediction services with given instances. Args: instances: A list of instances for getting predictions. timeout_ms: Timeout for each service call to the api (in milliseconds). Returns: A list of the dictionaries. """ request_body = {'instances': instances} response = http_utils.make_post_request_to_ai_platform( self._endpoint + ':predict', request_body, self._credentials, timeout_ms) return response
def explain(self, instances, params=None, timeout_ms=constants.DEFAULT_TIMEOUT): """A method to call explanation services with given instances. Args: instances: A list of instances for getting explanations. params: Overridable parameters for the explain call. Parameters can not be overriden in a remote model at the moment. timeout_ms: Timeout for each service call to the api (in milliseconds). Returns: A list of Explanation objects. Raises: ValueError: When explanation service fails, raise ValueError with the returned error message. This is likely due to details or formats of the instances are not correct. """ if params: logging.warn('Params can not be overriden in a remote model at the' ' moment.') del params request_body = {'instances': instances} response = http_utils.make_post_request_to_ai_platform( self._endpoint + ':explain', request_body, self._credentials, timeout_ms) if 'error' in response: error_msg = response['error'] raise ValueError(('Explanation call failed. This is likely due to ' 'incorrect instance formats. \nOriginal error ' 'message: ' + json.dumps(error_msg))) explanations = [] for idx, explanation_dict in enumerate(response['explanations']): exp_obj = explanation.Explanation.from_ai_platform_response( explanation_dict, instances[idx], self._modality_input_list_map) explanations.append(exp_obj) return explanations
def explain(self, instances: List[Any], params: Optional[configs.AttributionParameters] = None, timeout_ms: int = constants.DEFAULT_TIMEOUT ) -> List[explanation.Explanation]: """A method to call explanation services with given instances. Args: instances: A list of instances for getting explanations. params: Overridable parameters for the explain call. Parameters can not be overriden in a remote model at the moment. timeout_ms: Timeout for each service call to the api (in milliseconds). Returns: A list of Explanation objects. Raises: ValueError: When explanation service fails, raise ValueError with the returned error message. This is likely due to details or formats of the instances are not correct. KeyError: When the explanation dictionary doesn't contain 'attributions' or 'attributions_by_label' in the response. """ if params: logging.warn('Params can not be overriden in a remote model at the' ' moment.') del params request_body = {'instances': instances} response = http_utils.make_post_request_to_ai_platform( self._model_endpoint_uri + ':explain', request_body, self._credentials, timeout_ms) if 'error' in response: error_msg = response['error'] raise ValueError(('Explanation call failed. This is likely due to ' 'incorrect instance formats. \nOriginal error ' 'message: ' + json.dumps(error_msg))) explanations = [] for idx, explanation_dict in enumerate(response['explanations']): if _CAIP_ATTRIBUTIONS_KEY in explanation_dict: # CAIP response. attrs_key = _CAIP_ATTRIBUTIONS_KEY feature_attrs_key = _CAIP_FEATURE_ATTRS_KEY parse_fun = explanation.Explanation.from_ai_platform_response elif _VERTEX_ATTRIBUTIONS_KEY in explanation_dict: # VERTEX response. attrs_key = _VERTEX_ATTRIBUTIONS_KEY feature_attrs_key = _VERTEX_FEATURE_ATTRS_KEY parse_fun = explanation.Explanation.from_vertex_response else: raise KeyError( 'Attribution keys are not present in the AI Platform response.') attrs = explanation_dict[attrs_key] if not self._modality_to_inputs_map: self._modality_to_inputs_map = _create_default_modality_map( next(iter(attrs))[feature_attrs_key]) explanations.append( parse_fun(attrs, instances[idx], self._modality_to_inputs_map)) return explanations