diff --git a/speech/google/cloud/speech/metadata.py b/speech/google/cloud/speech/metadata.py index 89a8ff3369d9..2cbc285c16c6 100644 --- a/speech/google/cloud/speech/metadata.py +++ b/speech/google/cloud/speech/metadata.py @@ -46,7 +46,7 @@ def from_api_repr(cls, response): """ last_update = _rfc3339_to_datetime(response['lastUpdateTime']) start_time = _rfc3339_to_datetime(response['startTime']) - progress_percent = response['progressPercent'] + progress_percent = response.get('progressPercent') return cls(last_update, start_time, progress_percent) diff --git a/system_tests/speech.py b/system_tests/speech.py index d70ebcff997e..56c2f2ad7bc5 100644 --- a/system_tests/speech.py +++ b/system_tests/speech.py @@ -22,10 +22,33 @@ from system_test_utils import unique_resource_id from retry import RetryErrors +from retry import RetryResult AUDIO_FILE = os.path.join(os.path.dirname(__file__), 'data', 'hello.wav') +def _operation_complete(result): + """Return operation result.""" + return result + + +def _wait_until_complete(operation, max_attempts=5): + """Wait until an operation has completed. + + :type operation: :class:`google.cloud.operation.Operation` + :param operation: Operation that has not completed. + + :type max_attempts: int + :param max_attempts: (Optional) The maximum number of times to check if + the operation has completed. Defaults to 5. + + :rtype: bool + :returns: Boolean indicating if the operation is complete. + """ + retry = RetryResult(_operation_complete, max_tries=max_attempts) + return retry(operation.poll)() + + class Config(object): """Run-time configuration to be modified at set-up. @@ -34,10 +57,12 @@ class Config(object): """ CLIENT = None TEST_BUCKET = None + USE_GAX = True def setUpModule(): Config.CLIENT = speech.Client() + Config.USE_GAX = Config.CLIENT._use_gax # Now create a bucket for GCS stored content. storage_client = storage.Client() bucket_name = 'new' + unique_resource_id() @@ -72,12 +97,24 @@ def _make_sync_request(self, content=None, source_uri=None, source_uri=source_uri, encoding=speech.Encoding.LINEAR16, sample_rate=16000) - result = client.sync_recognize(sample, - language_code='en-US', - max_alternatives=max_alternatives, - profanity_filter=True, - speech_context=['Google', 'cloud']) - return result + return client.sync_recognize(sample, + language_code='en-US', + max_alternatives=max_alternatives, + profanity_filter=True, + speech_context=['Google', 'cloud']) + + def _make_async_request(self, content=None, source_uri=None, + max_alternatives=None): + client = Config.CLIENT + sample = client.sample(content=content, + source_uri=source_uri, + encoding=speech.Encoding.LINEAR16, + sample_rate=16000) + return client.async_recognize(sample, + language_code='en-US', + max_alternatives=max_alternatives, + profanity_filter=True, + speech_context=['Google', 'cloud']) def _check_best_results(self, results): top_result = results[0] @@ -109,3 +146,46 @@ def test_sync_recognize_gcs_file(self): result = self._make_sync_request(source_uri=source_uri, max_alternatives=1) self._check_best_results(result) + + def test_async_recognize_local_file(self): + if Config.USE_GAX: + self.skipTest('async_recognize gRPC not yet implemented.') + with open(AUDIO_FILE, 'rb') as file_obj: + content = file_obj.read() + + operation = self._make_async_request(content=content, + max_alternatives=2) + + _wait_until_complete(operation) + + self.assertEqual(len(operation.results), 2) + self._check_best_results(operation.results) + + results = operation.results + self.assertIsInstance(results[1], Transcript) + self.assertEqual(results[1].transcript, self.ASSERT_TEXT) + self.assertEqual(results[1].confidence, None) + + def test_async_recognize_gcs_file(self): + if Config.USE_GAX: + self.skipTest('async_recognize gRPC not yet implemented.') + bucket_name = Config.TEST_BUCKET.name + blob_name = 'hello.wav' + blob = Config.TEST_BUCKET.blob(blob_name) + self.to_delete_by_case.append(blob) # Clean-up. + with open(AUDIO_FILE, 'rb') as file_obj: + blob.upload_from_file(file_obj) + + source_uri = 'gs://%s/%s' % (bucket_name, blob_name) + operation = self._make_async_request(source_uri=source_uri, + max_alternatives=2) + + _wait_until_complete(operation) + + self.assertEqual(len(operation.results), 2) + self._check_best_results(operation.results) + + results = operation.results + self.assertIsInstance(results[1], Transcript) + self.assertEqual(results[1].transcript, self.ASSERT_TEXT) + self.assertEqual(results[1].confidence, None)