diff --git a/.coveragerc b/.coveragerc index a86174dd..c101945d 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,20 +1,3 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by synthtool. DO NOT EDIT! [run] branch = True @@ -32,4 +15,4 @@ exclude_lines = # This is added at the module level as a safeguard for if someone # generates the code and tries to run it without pip installing. This # makes it virtually impossible to test properly. - except pkg_resources.DistributionNotFound \ No newline at end of file + except pkg_resources.DistributionNotFound diff --git a/.github/header-checker-lint.yml b/.github/header-checker-lint.yml new file mode 100644 index 00000000..fc281c05 --- /dev/null +++ b/.github/header-checker-lint.yml @@ -0,0 +1,15 @@ +{"allowedCopyrightHolders": ["Google LLC"], + "allowedLicenses": ["Apache-2.0", "MIT", "BSD-3"], + "ignoreFiles": ["**/requirements.txt", "**/requirements-test.txt"], + "sourceFileExtensions": [ + "ts", + "js", + "java", + "sh", + "Dockerfile", + "yaml", + "py", + "html", + "txt" + ] +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index b9daa52f..b4243ced 100644 --- a/.gitignore +++ b/.gitignore @@ -50,8 +50,10 @@ docs.metadata # Virtual environment env/ + +# Test logs coverage.xml -sponge_log.xml +*sponge_log.xml # System test environment variables. system_tests/local_test_setup diff --git a/.kokoro/build.sh b/.kokoro/build.sh index 9497c9f0..04e4d1f1 100755 --- a/.kokoro/build.sh +++ b/.kokoro/build.sh @@ -15,7 +15,11 @@ set -eo pipefail -cd github/python-speech +if [[ -z "${PROJECT_ROOT:-}" ]]; then + PROJECT_ROOT="github/python-speech" +fi + +cd "${PROJECT_ROOT}" # Disable buffering, so that the logs stream through. export PYTHONUNBUFFERED=1 @@ -30,16 +34,26 @@ export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/service-account.json export PROJECT_ID=$(cat "${KOKORO_GFILE_DIR}/project-id.json") # Remove old nox -python3.6 -m pip uninstall --yes --quiet nox-automation +python3 -m pip uninstall --yes --quiet nox-automation # Install nox -python3.6 -m pip install --upgrade --quiet nox -python3.6 -m nox --version +python3 -m pip install --upgrade --quiet nox +python3 -m nox --version + +# If this is a continuous build, send the test log to the FlakyBot. +# See https://github.com/googleapis/repo-automation-bots/tree/master/packages/flakybot. +if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"continuous"* ]]; then + cleanup() { + chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot + $KOKORO_GFILE_DIR/linux_amd64/flakybot + } + trap cleanup EXIT HUP +fi # If NOX_SESSION is set, it only runs the specified session, # otherwise run all the sessions. if [[ -n "${NOX_SESSION:-}" ]]; then - python3.6 -m nox -s "${NOX_SESSION:-}" + python3 -m nox -s ${NOX_SESSION:-} else - python3.6 -m nox + python3 -m nox fi diff --git a/.kokoro/docs/docs-presubmit.cfg b/.kokoro/docs/docs-presubmit.cfg index 11181078..509afae6 100644 --- a/.kokoro/docs/docs-presubmit.cfg +++ b/.kokoro/docs/docs-presubmit.cfg @@ -15,3 +15,14 @@ env_vars: { key: "TRAMPOLINE_IMAGE_UPLOAD" value: "false" } + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-speech/.kokoro/build.sh" +} + +# Only run this nox session. +env_vars: { + key: "NOX_SESSION" + value: "docs docfx" +} diff --git a/.trampolinerc b/.trampolinerc index 995ee291..383b6ec8 100644 --- a/.trampolinerc +++ b/.trampolinerc @@ -24,6 +24,7 @@ required_envvars+=( pass_down_envvars+=( "STAGING_BUCKET" "V2_STAGING_BUCKET" + "NOX_SESSION" ) # Prevent unintentional override on the default image. diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 1eed7874..78017249 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -70,9 +70,14 @@ We use `nox `__ to instrument our tests. - To test your changes, run unit tests with ``nox``:: $ nox -s unit-2.7 - $ nox -s unit-3.7 + $ nox -s unit-3.8 $ ... +- Args to pytest can be passed through the nox command separated by a `--`. For + example, to run a single test:: + + $ nox -s unit-3.8 -- -k + .. note:: The unit tests and system tests are described in the @@ -93,8 +98,12 @@ On Debian/Ubuntu:: ************ Coding Style ************ +- We use the automatic code formatter ``black``. You can run it using + the nox session ``blacken``. This will eliminate many lint errors. Run via:: + + $ nox -s blacken -- PEP8 compliance, with exceptions defined in the linter configuration. +- PEP8 compliance is required, with exceptions defined in the linter configuration. If you have ``nox`` installed, you can test that you have not introduced any non-compliant code via:: @@ -133,13 +142,18 @@ Running System Tests - To run system tests, you can execute:: - $ nox -s system-3.7 + # Run all system tests + $ nox -s system-3.8 $ nox -s system-2.7 + # Run a single system test + $ nox -s system-3.8 -- -k + + .. note:: System tests are only configured to run under Python 2.7 and - Python 3.7. For expediency, we do not run them in older versions + Python 3.8. For expediency, we do not run them in older versions of Python 3. This alone will not run the tests. You'll need to change some local diff --git a/LICENSE b/LICENSE index a8ee855d..d6456956 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ - Apache License + + Apache License Version 2.0, January 2004 - https://www.apache.org/licenses/ + http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION @@ -192,7 +193,7 @@ you may not use this file except in compliance with the License. You may obtain a copy of the License at - https://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/MANIFEST.in b/MANIFEST.in index e9e29d12..e783f4c6 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -16,10 +16,10 @@ # Generated by synthtool. DO NOT EDIT! include README.rst LICENSE -recursive-include google *.json *.proto +recursive-include google *.json *.proto py.typed recursive-include tests * global-exclude *.py[co] global-exclude __pycache__ # Exclude scripts for samples readmegen -prune scripts/readme-gen \ No newline at end of file +prune scripts/readme-gen diff --git a/docs/_static/custom.css b/docs/_static/custom.css index 0abaf229..bcd37bbd 100644 --- a/docs/_static/custom.css +++ b/docs/_static/custom.css @@ -1,4 +1,9 @@ div#python2-eol { border-color: red; border-width: medium; -} \ No newline at end of file +} + +/* Ensure minimum width for 'Parameters' / 'Returns' column */ +dl.field-list > dt { + min-width: 100px +} diff --git a/docs/speech_v1/services.rst b/docs/speech_v1/services.rst index 2d1b3d29..07e11e84 100644 --- a/docs/speech_v1/services.rst +++ b/docs/speech_v1/services.rst @@ -1,6 +1,6 @@ Services for Google Cloud Speech v1 API ======================================= +.. toctree:: + :maxdepth: 2 -.. automodule:: google.cloud.speech_v1.services.speech - :members: - :inherited-members: + speech diff --git a/docs/speech_v1/speech.rst b/docs/speech_v1/speech.rst new file mode 100644 index 00000000..53fc9d38 --- /dev/null +++ b/docs/speech_v1/speech.rst @@ -0,0 +1,6 @@ +Speech +------------------------ + +.. automodule:: google.cloud.speech_v1.services.speech + :members: + :inherited-members: diff --git a/docs/speech_v1/types.rst b/docs/speech_v1/types.rst index 1f28fdd0..1ca37b89 100644 --- a/docs/speech_v1/types.rst +++ b/docs/speech_v1/types.rst @@ -3,4 +3,5 @@ Types for Google Cloud Speech v1 API .. automodule:: google.cloud.speech_v1.types :members: + :undoc-members: :show-inheritance: diff --git a/docs/speech_v1p1beta1/adaptation.rst b/docs/speech_v1p1beta1/adaptation.rst new file mode 100644 index 00000000..7236ba17 --- /dev/null +++ b/docs/speech_v1p1beta1/adaptation.rst @@ -0,0 +1,11 @@ +Adaptation +---------------------------- + +.. automodule:: google.cloud.speech_v1p1beta1.services.adaptation + :members: + :inherited-members: + + +.. automodule:: google.cloud.speech_v1p1beta1.services.adaptation.pagers + :members: + :inherited-members: diff --git a/docs/speech_v1p1beta1/services.rst b/docs/speech_v1p1beta1/services.rst index dbbb066c..d4982074 100644 --- a/docs/speech_v1p1beta1/services.rst +++ b/docs/speech_v1p1beta1/services.rst @@ -1,6 +1,7 @@ Services for Google Cloud Speech v1p1beta1 API ============================================== +.. toctree:: + :maxdepth: 2 -.. automodule:: google.cloud.speech_v1p1beta1.services.speech - :members: - :inherited-members: + adaptation + speech diff --git a/docs/speech_v1p1beta1/speech.rst b/docs/speech_v1p1beta1/speech.rst new file mode 100644 index 00000000..bd3e379a --- /dev/null +++ b/docs/speech_v1p1beta1/speech.rst @@ -0,0 +1,6 @@ +Speech +------------------------ + +.. automodule:: google.cloud.speech_v1p1beta1.services.speech + :members: + :inherited-members: diff --git a/docs/speech_v1p1beta1/types.rst b/docs/speech_v1p1beta1/types.rst index 96ebe607..004a3819 100644 --- a/docs/speech_v1p1beta1/types.rst +++ b/docs/speech_v1p1beta1/types.rst @@ -3,4 +3,5 @@ Types for Google Cloud Speech v1p1beta1 API .. automodule:: google.cloud.speech_v1p1beta1.types :members: + :undoc-members: :show-inheritance: diff --git a/google/cloud/speech_v1/services/speech/async_client.py b/google/cloud/speech_v1/services/speech/async_client.py index 5fea5c72..c82139bd 100644 --- a/google/cloud/speech_v1/services/speech/async_client.py +++ b/google/cloud/speech_v1/services/speech/async_client.py @@ -74,7 +74,36 @@ class SpeechAsyncClient: common_location_path = staticmethod(SpeechClient.common_location_path) parse_common_location_path = staticmethod(SpeechClient.parse_common_location_path) - from_service_account_file = SpeechClient.from_service_account_file + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SpeechAsyncClient: The constructed client. + """ + return SpeechClient.from_service_account_info.__func__(SpeechAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SpeechAsyncClient: The constructed client. + """ + return SpeechClient.from_service_account_file.__func__(SpeechAsyncClient, filename, *args, **kwargs) # type: ignore + from_service_account_json = from_service_account_file @property @@ -152,19 +181,21 @@ async def recognize( results after all audio has been sent and processed. Args: - request (:class:`~.cloud_speech.RecognizeRequest`): + request (:class:`google.cloud.speech_v1.types.RecognizeRequest`): The request object. The top-level message sent by the client for the `Recognize` method. - config (:class:`~.cloud_speech.RecognitionConfig`): + config (:class:`google.cloud.speech_v1.types.RecognitionConfig`): Required. Provides information to the recognizer that specifies how to process the request. + This corresponds to the ``config`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - audio (:class:`~.cloud_speech.RecognitionAudio`): + audio (:class:`google.cloud.speech_v1.types.RecognitionAudio`): Required. The audio data to be recognized. + This corresponds to the ``audio`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -176,10 +207,10 @@ async def recognize( sent along with the request as metadata. Returns: - ~.cloud_speech.RecognizeResponse: - The only message returned to the client by the - ``Recognize`` method. It contains the result as zero or - more sequential ``SpeechRecognitionResult`` messages. + google.cloud.speech_v1.types.RecognizeResponse: + The only message returned to the client by the Recognize method. It + contains the result as zero or more sequential + SpeechRecognitionResult messages. """ # Create or coerce a protobuf request object. @@ -242,19 +273,21 @@ async def long_running_recognize( `how-to `__. Args: - request (:class:`~.cloud_speech.LongRunningRecognizeRequest`): + request (:class:`google.cloud.speech_v1.types.LongRunningRecognizeRequest`): The request object. The top-level message sent by the client for the `LongRunningRecognize` method. - config (:class:`~.cloud_speech.RecognitionConfig`): + config (:class:`google.cloud.speech_v1.types.RecognitionConfig`): Required. Provides information to the recognizer that specifies how to process the request. + This corresponds to the ``config`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - audio (:class:`~.cloud_speech.RecognitionAudio`): + audio (:class:`google.cloud.speech_v1.types.RecognitionAudio`): Required. The audio data to be recognized. + This corresponds to the ``audio`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -266,18 +299,15 @@ async def long_running_recognize( sent along with the request as metadata. Returns: - ~.operation_async.AsyncOperation: + google.api_core.operation_async.AsyncOperation: An object representing a long-running operation. - The result type for the operation will be - :class:``~.cloud_speech.LongRunningRecognizeResponse``: - The only message returned to the client by the - ``LongRunningRecognize`` method. It contains the result - as zero or more sequential ``SpeechRecognitionResult`` - messages. It is included in the ``result.response`` - field of the ``Operation`` returned by the - ``GetOperation`` call of the - ``google::longrunning::Operations`` service. + The result type for the operation will be :class:`google.cloud.speech_v1.types.LongRunningRecognizeResponse` The only message returned to the client by the LongRunningRecognize method. + It contains the result as zero or more sequential + SpeechRecognitionResult messages. It is included in + the result.response field of the Operation returned + by the GetOperation call of the + google::longrunning::Operations service. """ # Create or coerce a protobuf request object. @@ -335,7 +365,7 @@ def streaming_recognize( available via the gRPC API (not REST). Args: - requests (AsyncIterator[`~.cloud_speech.StreamingRecognizeRequest`]): + requests (AsyncIterator[`google.cloud.speech_v1.types.StreamingRecognizeRequest`]): The request object AsyncIterator. The top-level message sent by the client for the `StreamingRecognize` method. Multiple `StreamingRecognizeRequest` messages are sent. The first @@ -350,66 +380,67 @@ def streaming_recognize( sent along with the request as metadata. Returns: - AsyncIterable[~.cloud_speech.StreamingRecognizeResponse]: - ``StreamingRecognizeResponse`` is the only message - returned to the client by ``StreamingRecognize``. A - series of zero or more ``StreamingRecognizeResponse`` - messages are streamed back to the client. If there is no - recognizable audio, and ``single_utterance`` is set to - false, then no messages are streamed back to the client. - - Here's an example of a series of ten - ``StreamingRecognizeResponse``\ s that might be returned - while processing audio: - - 1. results { alternatives { transcript: "tube" } - stability: 0.01 } - - 2. results { alternatives { transcript: "to be a" } - stability: 0.01 } - - 3. results { alternatives { transcript: "to be" } - stability: 0.9 } results { alternatives { transcript: - " or not to be" } stability: 0.01 } - - 4. results { alternatives { transcript: "to be or not to - be" confidence: 0.92 } alternatives { transcript: "to - bee or not to bee" } is_final: true } - - 5. results { alternatives { transcript: " that's" } - stability: 0.01 } - - 6. results { alternatives { transcript: " that is" } - stability: 0.9 } results { alternatives { transcript: - " the question" } stability: 0.01 } - - 7. results { alternatives { transcript: " that is the - question" confidence: 0.98 } alternatives { - transcript: " that was the question" } is_final: true - } - - Notes: - - - Only two of the above responses #4 and #7 contain - final results; they are indicated by - ``is_final: true``. Concatenating these together - generates the full transcript: "to be or not to be - that is the question". - - - The others contain interim ``results``. #3 and #6 - contain two interim ``results``: the first portion - has a high stability and is less likely to change; - the second portion has a low stability and is very - likely to change. A UI designer might choose to show - only high stability ``results``. - - - The specific ``stability`` and ``confidence`` values - shown above are only for illustrative purposes. - Actual values may vary. - - - In each response, only one of these fields will be - set: ``error``, ``speech_event_type``, or one or more - (repeated) ``results``. + AsyncIterable[google.cloud.speech_v1.types.StreamingRecognizeResponse]: + StreamingRecognizeResponse is the only message returned to the client by + StreamingRecognize. A series of zero or more + StreamingRecognizeResponse messages are streamed back + to the client. If there is no recognizable audio, and + single_utterance is set to false, then no messages + are streamed back to the client. + + Here's an example of a series of ten + StreamingRecognizeResponses that might be returned + while processing audio: + + 1. results { alternatives { transcript: "tube" } + stability: 0.01 } + 2. results { alternatives { transcript: "to be a" } + stability: 0.01 } + 3. results { alternatives { transcript: "to be" } + stability: 0.9 } results { alternatives { + transcript: " or not to be" } stability: 0.01 } + 4. + + results { alternatives { transcript: "to be or not to be" + confidence: 0.92 } + + alternatives { transcript: "to bee or not to bee" } + is_final: true } + + 5. results { alternatives { transcript: " that's" } + stability: 0.01 } + 6. results { alternatives { transcript: " that is" } + stability: 0.9 } results { alternatives { + transcript: " the question" } stability: 0.01 } + 7. + + results { alternatives { transcript: " that is the question" + confidence: 0.98 } + + alternatives { transcript: " that was the question" } + is_final: true } + + Notes: + + - Only two of the above responses #4 and #7 contain + final results; they are indicated by + is_final: true. Concatenating these together + generates the full transcript: "to be or not to be + that is the question". + - The others contain interim results. #3 and #6 + contain two interim \`results`: the first portion + has a high stability and is less likely to change; + the second portion has a low stability and is very + likely to change. A UI designer might choose to + show only high stability results. + - The specific stability and confidence values shown + above are only for illustrative purposes. Actual + values may vary. + - + + In each response, only one of these fields will be set: + error, speech_event_type, or one or more + (repeated) results. """ diff --git a/google/cloud/speech_v1/services/speech/client.py b/google/cloud/speech_v1/services/speech/client.py index 27b20723..e6b69c24 100644 --- a/google/cloud/speech_v1/services/speech/client.py +++ b/google/cloud/speech_v1/services/speech/client.py @@ -120,6 +120,22 @@ def _get_default_mtls_endpoint(api_endpoint): DEFAULT_ENDPOINT ) + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SpeechClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials @@ -132,7 +148,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): kwargs: Additional arguments to pass to the constructor. Returns: - {@api.name}: The constructed client. + SpeechClient: The constructed client. """ credentials = service_account.Credentials.from_service_account_file(filename) kwargs["credentials"] = credentials @@ -224,10 +240,10 @@ def __init__( credentials identify the application to the service; if none are specified, the client will attempt to ascertain the credentials from the environment. - transport (Union[str, ~.SpeechTransport]): The + transport (Union[str, SpeechTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (client_options_lib.ClientOptions): Custom options for the + client_options (google.api_core.client_options.ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT @@ -263,21 +279,17 @@ def __init__( util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) ) - ssl_credentials = None + client_cert_source_func = None is_mtls = False if use_client_cert: if client_options.client_cert_source: - import grpc # type: ignore - - cert, key = client_options.client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) is_mtls = True + client_cert_source_func = client_options.client_cert_source else: - creds = SslCredentials() - is_mtls = creds.is_mtls - ssl_credentials = creds.ssl_credentials if is_mtls else None + is_mtls = mtls.has_default_client_cert_source() + client_cert_source_func = ( + mtls.default_client_cert_source() if is_mtls else None + ) # Figure out which api endpoint to use. if client_options.api_endpoint is not None: @@ -320,7 +332,7 @@ def __init__( credentials_file=client_options.credentials_file, host=api_endpoint, scopes=client_options.scopes, - ssl_channel_credentials=ssl_credentials, + client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, ) @@ -339,19 +351,21 @@ def recognize( results after all audio has been sent and processed. Args: - request (:class:`~.cloud_speech.RecognizeRequest`): + request (google.cloud.speech_v1.types.RecognizeRequest): The request object. The top-level message sent by the client for the `Recognize` method. - config (:class:`~.cloud_speech.RecognitionConfig`): + config (google.cloud.speech_v1.types.RecognitionConfig): Required. Provides information to the recognizer that specifies how to process the request. + This corresponds to the ``config`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - audio (:class:`~.cloud_speech.RecognitionAudio`): + audio (google.cloud.speech_v1.types.RecognitionAudio): Required. The audio data to be recognized. + This corresponds to the ``audio`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -363,10 +377,10 @@ def recognize( sent along with the request as metadata. Returns: - ~.cloud_speech.RecognizeResponse: - The only message returned to the client by the - ``Recognize`` method. It contains the result as zero or - more sequential ``SpeechRecognitionResult`` messages. + google.cloud.speech_v1.types.RecognizeResponse: + The only message returned to the client by the Recognize method. It + contains the result as zero or more sequential + SpeechRecognitionResult messages. """ # Create or coerce a protobuf request object. @@ -422,19 +436,21 @@ def long_running_recognize( `how-to `__. Args: - request (:class:`~.cloud_speech.LongRunningRecognizeRequest`): + request (google.cloud.speech_v1.types.LongRunningRecognizeRequest): The request object. The top-level message sent by the client for the `LongRunningRecognize` method. - config (:class:`~.cloud_speech.RecognitionConfig`): + config (google.cloud.speech_v1.types.RecognitionConfig): Required. Provides information to the recognizer that specifies how to process the request. + This corresponds to the ``config`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - audio (:class:`~.cloud_speech.RecognitionAudio`): + audio (google.cloud.speech_v1.types.RecognitionAudio): Required. The audio data to be recognized. + This corresponds to the ``audio`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -446,18 +462,15 @@ def long_running_recognize( sent along with the request as metadata. Returns: - ~.operation.Operation: + google.api_core.operation.Operation: An object representing a long-running operation. - The result type for the operation will be - :class:``~.cloud_speech.LongRunningRecognizeResponse``: - The only message returned to the client by the - ``LongRunningRecognize`` method. It contains the result - as zero or more sequential ``SpeechRecognitionResult`` - messages. It is included in the ``result.response`` - field of the ``Operation`` returned by the - ``GetOperation`` call of the - ``google::longrunning::Operations`` service. + The result type for the operation will be :class:`google.cloud.speech_v1.types.LongRunningRecognizeResponse` The only message returned to the client by the LongRunningRecognize method. + It contains the result as zero or more sequential + SpeechRecognitionResult messages. It is included in + the result.response field of the Operation returned + by the GetOperation call of the + google::longrunning::Operations service. """ # Create or coerce a protobuf request object. @@ -516,7 +529,7 @@ def streaming_recognize( available via the gRPC API (not REST). Args: - requests (Iterator[`~.cloud_speech.StreamingRecognizeRequest`]): + requests (Iterator[google.cloud.speech_v1.types.StreamingRecognizeRequest]): The request object iterator. The top-level message sent by the client for the `StreamingRecognize` method. Multiple `StreamingRecognizeRequest` messages are sent. The first @@ -531,66 +544,67 @@ def streaming_recognize( sent along with the request as metadata. Returns: - Iterable[~.cloud_speech.StreamingRecognizeResponse]: - ``StreamingRecognizeResponse`` is the only message - returned to the client by ``StreamingRecognize``. A - series of zero or more ``StreamingRecognizeResponse`` - messages are streamed back to the client. If there is no - recognizable audio, and ``single_utterance`` is set to - false, then no messages are streamed back to the client. - - Here's an example of a series of ten - ``StreamingRecognizeResponse``\ s that might be returned - while processing audio: - - 1. results { alternatives { transcript: "tube" } - stability: 0.01 } - - 2. results { alternatives { transcript: "to be a" } - stability: 0.01 } - - 3. results { alternatives { transcript: "to be" } - stability: 0.9 } results { alternatives { transcript: - " or not to be" } stability: 0.01 } - - 4. results { alternatives { transcript: "to be or not to - be" confidence: 0.92 } alternatives { transcript: "to - bee or not to bee" } is_final: true } - - 5. results { alternatives { transcript: " that's" } - stability: 0.01 } - - 6. results { alternatives { transcript: " that is" } - stability: 0.9 } results { alternatives { transcript: - " the question" } stability: 0.01 } - - 7. results { alternatives { transcript: " that is the - question" confidence: 0.98 } alternatives { - transcript: " that was the question" } is_final: true - } - - Notes: - - - Only two of the above responses #4 and #7 contain - final results; they are indicated by - ``is_final: true``. Concatenating these together - generates the full transcript: "to be or not to be - that is the question". - - - The others contain interim ``results``. #3 and #6 - contain two interim ``results``: the first portion - has a high stability and is less likely to change; - the second portion has a low stability and is very - likely to change. A UI designer might choose to show - only high stability ``results``. - - - The specific ``stability`` and ``confidence`` values - shown above are only for illustrative purposes. - Actual values may vary. - - - In each response, only one of these fields will be - set: ``error``, ``speech_event_type``, or one or more - (repeated) ``results``. + Iterable[google.cloud.speech_v1.types.StreamingRecognizeResponse]: + StreamingRecognizeResponse is the only message returned to the client by + StreamingRecognize. A series of zero or more + StreamingRecognizeResponse messages are streamed back + to the client. If there is no recognizable audio, and + single_utterance is set to false, then no messages + are streamed back to the client. + + Here's an example of a series of ten + StreamingRecognizeResponses that might be returned + while processing audio: + + 1. results { alternatives { transcript: "tube" } + stability: 0.01 } + 2. results { alternatives { transcript: "to be a" } + stability: 0.01 } + 3. results { alternatives { transcript: "to be" } + stability: 0.9 } results { alternatives { + transcript: " or not to be" } stability: 0.01 } + 4. + + results { alternatives { transcript: "to be or not to be" + confidence: 0.92 } + + alternatives { transcript: "to bee or not to bee" } + is_final: true } + + 5. results { alternatives { transcript: " that's" } + stability: 0.01 } + 6. results { alternatives { transcript: " that is" } + stability: 0.9 } results { alternatives { + transcript: " the question" } stability: 0.01 } + 7. + + results { alternatives { transcript: " that is the question" + confidence: 0.98 } + + alternatives { transcript: " that was the question" } + is_final: true } + + Notes: + + - Only two of the above responses #4 and #7 contain + final results; they are indicated by + is_final: true. Concatenating these together + generates the full transcript: "to be or not to be + that is the question". + - The others contain interim results. #3 and #6 + contain two interim \`results`: the first portion + has a high stability and is less likely to change; + the second portion has a low stability and is very + likely to change. A UI designer might choose to + show only high stability results. + - The specific stability and confidence values shown + above are only for illustrative purposes. Actual + values may vary. + - + + In each response, only one of these fields will be set: + error, speech_event_type, or one or more + (repeated) results. """ diff --git a/google/cloud/speech_v1/services/speech/transports/grpc.py b/google/cloud/speech_v1/services/speech/transports/grpc.py index 5bb7ebdc..60e79b57 100644 --- a/google/cloud/speech_v1/services/speech/transports/grpc.py +++ b/google/cloud/speech_v1/services/speech/transports/grpc.py @@ -59,6 +59,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -89,6 +90,10 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -105,6 +110,11 @@ def __init__( """ self._ssl_channel_credentials = ssl_channel_credentials + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + if channel: # Sanity check: Ensure that channel and credentials are not both # provided. @@ -114,11 +124,6 @@ def __init__( self._grpc_channel = channel self._ssl_channel_credentials = None elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -162,12 +167,18 @@ def __init__( scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id ) + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + # create a new channel. The provided one is ignored. self._grpc_channel = type(self).create_channel( host, credentials=credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, + ssl_credentials=self._ssl_channel_credentials, scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, options=[ diff --git a/google/cloud/speech_v1/services/speech/transports/grpc_asyncio.py b/google/cloud/speech_v1/services/speech/transports/grpc_asyncio.py index 8f6987dc..31e68cc7 100644 --- a/google/cloud/speech_v1/services/speech/transports/grpc_asyncio.py +++ b/google/cloud/speech_v1/services/speech/transports/grpc_asyncio.py @@ -103,6 +103,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -134,6 +135,10 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -150,6 +155,11 @@ def __init__( """ self._ssl_channel_credentials = ssl_channel_credentials + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + if channel: # Sanity check: Ensure that channel and credentials are not both # provided. @@ -159,11 +169,6 @@ def __init__( self._grpc_channel = channel self._ssl_channel_credentials = None elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -207,12 +212,18 @@ def __init__( scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id ) + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + # create a new channel. The provided one is ignored. self._grpc_channel = type(self).create_channel( host, credentials=credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, + ssl_credentials=self._ssl_channel_credentials, scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, options=[ diff --git a/google/cloud/speech_v1/types/cloud_speech.py b/google/cloud/speech_v1/types/cloud_speech.py index 0687b377..a2a8401b 100644 --- a/google/cloud/speech_v1/types/cloud_speech.py +++ b/google/cloud/speech_v1/types/cloud_speech.py @@ -52,11 +52,11 @@ class RecognizeRequest(proto.Message): method. Attributes: - config (~.cloud_speech.RecognitionConfig): + config (google.cloud.speech_v1.types.RecognitionConfig): Required. Provides information to the recognizer that specifies how to process the request. - audio (~.cloud_speech.RecognitionAudio): + audio (google.cloud.speech_v1.types.RecognitionAudio): Required. The audio data to be recognized. """ @@ -70,11 +70,11 @@ class LongRunningRecognizeRequest(proto.Message): ``LongRunningRecognize`` method. Attributes: - config (~.cloud_speech.RecognitionConfig): + config (google.cloud.speech_v1.types.RecognitionConfig): Required. Provides information to the recognizer that specifies how to process the request. - audio (~.cloud_speech.RecognitionAudio): + audio (google.cloud.speech_v1.types.RecognitionAudio): Required. The audio data to be recognized. """ @@ -93,7 +93,7 @@ class StreamingRecognizeRequest(proto.Message): message. Attributes: - streaming_config (~.cloud_speech.StreamingRecognitionConfig): + streaming_config (google.cloud.speech_v1.types.StreamingRecognitionConfig): Provides information to the recognizer that specifies how to process the request. The first ``StreamingRecognizeRequest`` message must contain a ``streaming_config`` message. @@ -125,7 +125,7 @@ class StreamingRecognitionConfig(proto.Message): process the request. Attributes: - config (~.cloud_speech.RecognitionConfig): + config (google.cloud.speech_v1.types.RecognitionConfig): Required. Provides information to the recognizer that specifies how to process the request. @@ -163,7 +163,7 @@ class RecognitionConfig(proto.Message): process the request. Attributes: - encoding (~.cloud_speech.RecognitionConfig.AudioEncoding): + encoding (google.cloud.speech_v1.types.RecognitionConfig.AudioEncoding): Encoding of audio data sent in all ``RecognitionAudio`` messages. This field is optional for ``FLAC`` and ``WAV`` audio files and required for all other audio formats. For @@ -217,7 +217,7 @@ class RecognitionConfig(proto.Message): profanities, replacing all but the initial character in each filtered word with asterisks, e.g. "f***". If set to ``false`` or omitted, profanities won't be filtered out. - speech_contexts (Sequence[~.cloud_speech.SpeechContext]): + speech_contexts (Sequence[google.cloud.speech_v1.types.SpeechContext]): Array of [SpeechContext][google.cloud.speech.v1.SpeechContext]. A means to provide context to assist the speech recognition. @@ -239,7 +239,7 @@ class RecognitionConfig(proto.Message): complimentary to all users. In the future this may be exclusively available as a premium feature. - diarization_config (~.cloud_speech.SpeakerDiarizationConfig): + diarization_config (google.cloud.speech_v1.types.SpeakerDiarizationConfig): Config to enable speaker diarization and set additional parameters to make diarization better suited for your application. Note: When this is @@ -252,7 +252,7 @@ class RecognitionConfig(proto.Message): requests, the diarization results will be provided only in the top alternative of the FINAL SpeechRecognitionResult. - metadata (~.cloud_speech.RecognitionMetadata): + metadata (google.cloud.speech_v1.types.RecognitionMetadata): Metadata regarding this request. model (str): Which model to select for the given request. Select the @@ -408,7 +408,7 @@ class RecognitionMetadata(proto.Message): r"""Description of audio data to be recognized. Attributes: - interaction_type (~.cloud_speech.RecognitionMetadata.InteractionType): + interaction_type (google.cloud.speech_v1.types.RecognitionMetadata.InteractionType): The use case most closely describing the audio content to be recognized. industry_naics_code_of_audio (int): @@ -418,13 +418,13 @@ class RecognitionMetadata(proto.Message): the audio. Use the 6-digit NAICS code to identify the industry vertical - see https://www.naics.com/search/. - microphone_distance (~.cloud_speech.RecognitionMetadata.MicrophoneDistance): + microphone_distance (google.cloud.speech_v1.types.RecognitionMetadata.MicrophoneDistance): The audio type that most closely describes the audio being recognized. - original_media_type (~.cloud_speech.RecognitionMetadata.OriginalMediaType): + original_media_type (google.cloud.speech_v1.types.RecognitionMetadata.OriginalMediaType): The original media the speech was recorded on. - recording_device_type (~.cloud_speech.RecognitionMetadata.RecordingDeviceType): + recording_device_type (google.cloud.speech_v1.types.RecognitionMetadata.RecordingDeviceType): The type of device the speech was recorded with. recording_device_name (str): @@ -562,7 +562,7 @@ class RecognizeResponse(proto.Message): ``SpeechRecognitionResult`` messages. Attributes: - results (Sequence[~.cloud_speech.SpeechRecognitionResult]): + results (Sequence[google.cloud.speech_v1.types.SpeechRecognitionResult]): Sequential list of transcription results corresponding to sequential portions of audio. """ @@ -581,7 +581,7 @@ class LongRunningRecognizeResponse(proto.Message): service. Attributes: - results (Sequence[~.cloud_speech.SpeechRecognitionResult]): + results (Sequence[google.cloud.speech_v1.types.SpeechRecognitionResult]): Sequential list of transcription results corresponding to sequential portions of audio. """ @@ -602,9 +602,9 @@ class LongRunningRecognizeMetadata(proto.Message): Approximate percentage of audio processed thus far. Guaranteed to be 100 when the audio is fully processed and the results are available. - start_time (~.timestamp.Timestamp): + start_time (google.protobuf.timestamp_pb2.Timestamp): Time when the request was received. - last_update_time (~.timestamp.Timestamp): + last_update_time (google.protobuf.timestamp_pb2.Timestamp): Time of the most recent processing update. """ @@ -673,16 +673,16 @@ class StreamingRecognizeResponse(proto.Message): ``results``. Attributes: - error (~.status.Status): + error (google.rpc.status_pb2.Status): If set, returns a [google.rpc.Status][google.rpc.Status] message that specifies the error for the operation. - results (Sequence[~.cloud_speech.StreamingRecognitionResult]): + results (Sequence[google.cloud.speech_v1.types.StreamingRecognitionResult]): This repeated list contains zero or more results that correspond to consecutive portions of the audio currently being processed. It contains zero or one ``is_final=true`` result (the newly settled portion), followed by zero or more ``is_final=false`` results (the interim results). - speech_event_type (~.cloud_speech.StreamingRecognizeResponse.SpeechEventType): + speech_event_type (google.cloud.speech_v1.types.StreamingRecognizeResponse.SpeechEventType): Indicates the type of speech event. """ @@ -705,7 +705,7 @@ class StreamingRecognitionResult(proto.Message): portion of the audio that is currently being processed. Attributes: - alternatives (Sequence[~.cloud_speech.SpeechRecognitionAlternative]): + alternatives (Sequence[google.cloud.speech_v1.types.SpeechRecognitionAlternative]): May contain one or more recognition hypotheses (up to the maximum specified in ``max_alternatives``). These alternatives are ordered in terms of accuracy, with the top @@ -725,7 +725,7 @@ class StreamingRecognitionResult(proto.Message): This field is only provided for interim results (``is_final=false``). The default of 0.0 is a sentinel value indicating ``stability`` was not set. - result_end_time (~.duration.Duration): + result_end_time (google.protobuf.duration_pb2.Duration): Time offset of the end of this result relative to the beginning of the audio. channel_tag (int): @@ -761,7 +761,7 @@ class SpeechRecognitionResult(proto.Message): audio. Attributes: - alternatives (Sequence[~.cloud_speech.SpeechRecognitionAlternative]): + alternatives (Sequence[google.cloud.speech_v1.types.SpeechRecognitionAlternative]): May contain one or more recognition hypotheses (up to the maximum specified in ``max_alternatives``). These alternatives are ordered in terms of accuracy, with the top @@ -797,7 +797,7 @@ class SpeechRecognitionAlternative(proto.Message): to be accurate and users should not rely on it to be always provided. The default of 0.0 is a sentinel value indicating ``confidence`` was not set. - words (Sequence[~.cloud_speech.WordInfo]): + words (Sequence[google.cloud.speech_v1.types.WordInfo]): A list of word-specific information for each recognized word. Note: When ``enable_speaker_diarization`` is true, you will see all the words from the beginning of the audio. @@ -814,13 +814,13 @@ class WordInfo(proto.Message): r"""Word-specific information for recognized words. Attributes: - start_time (~.duration.Duration): + start_time (google.protobuf.duration_pb2.Duration): Time offset relative to the beginning of the audio, and corresponding to the start of the spoken word. This field is only set if ``enable_word_time_offsets=true`` and only in the top hypothesis. This is an experimental feature and the accuracy of the time offset can vary. - end_time (~.duration.Duration): + end_time (google.protobuf.duration_pb2.Duration): Time offset relative to the beginning of the audio, and corresponding to the end of the spoken word. This field is only set if ``enable_word_time_offsets=true`` and only in diff --git a/google/cloud/speech_v1p1beta1/__init__.py b/google/cloud/speech_v1p1beta1/__init__.py index 6424649f..5b258db7 100644 --- a/google/cloud/speech_v1p1beta1/__init__.py +++ b/google/cloud/speech_v1p1beta1/__init__.py @@ -15,6 +15,7 @@ # limitations under the License. # +from .services.adaptation import AdaptationClient from .services.speech import SpeechClient from .types.cloud_speech import LongRunningRecognizeMetadata from .types.cloud_speech import LongRunningRecognizeRequest @@ -33,6 +34,18 @@ from .types.cloud_speech import StreamingRecognizeRequest from .types.cloud_speech import StreamingRecognizeResponse from .types.cloud_speech import WordInfo +from .types.cloud_speech_adaptation import CreateCustomClassRequest +from .types.cloud_speech_adaptation import CreatePhraseSetRequest +from .types.cloud_speech_adaptation import DeleteCustomClassRequest +from .types.cloud_speech_adaptation import DeletePhraseSetRequest +from .types.cloud_speech_adaptation import GetCustomClassRequest +from .types.cloud_speech_adaptation import GetPhraseSetRequest +from .types.cloud_speech_adaptation import ListCustomClassesRequest +from .types.cloud_speech_adaptation import ListCustomClassesResponse +from .types.cloud_speech_adaptation import ListPhraseSetRequest +from .types.cloud_speech_adaptation import ListPhraseSetResponse +from .types.cloud_speech_adaptation import UpdateCustomClassRequest +from .types.cloud_speech_adaptation import UpdatePhraseSetRequest from .types.resource import CustomClass from .types.resource import PhraseSet from .types.resource import SpeechAdaptation @@ -46,7 +59,17 @@ class SpeechClient(SpeechHelpers, SpeechClient): __all__ = ( + "CreateCustomClassRequest", + "CreatePhraseSetRequest", "CustomClass", + "DeleteCustomClassRequest", + "DeletePhraseSetRequest", + "GetCustomClassRequest", + "GetPhraseSetRequest", + "ListCustomClassesRequest", + "ListCustomClassesResponse", + "ListPhraseSetRequest", + "ListPhraseSetResponse", "LongRunningRecognizeMetadata", "LongRunningRecognizeRequest", "LongRunningRecognizeResponse", @@ -58,6 +81,7 @@ class SpeechClient(SpeechHelpers, SpeechClient): "RecognizeResponse", "SpeakerDiarizationConfig", "SpeechAdaptation", + "SpeechClient", "SpeechContext", "SpeechRecognitionAlternative", "SpeechRecognitionResult", @@ -65,6 +89,8 @@ class SpeechClient(SpeechHelpers, SpeechClient): "StreamingRecognitionResult", "StreamingRecognizeRequest", "StreamingRecognizeResponse", + "UpdateCustomClassRequest", + "UpdatePhraseSetRequest", "WordInfo", - "SpeechClient", + "AdaptationClient", ) diff --git a/google/cloud/speech_v1p1beta1/proto/cloud_speech.proto b/google/cloud/speech_v1p1beta1/proto/cloud_speech.proto index 7bb12866..3eccfb66 100644 --- a/google/cloud/speech_v1p1beta1/proto/cloud_speech.proto +++ b/google/cloud/speech_v1p1beta1/proto/cloud_speech.proto @@ -1,4 +1,4 @@ -// Copyright 2020 Google LLC +// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -139,6 +139,16 @@ message StreamingRecognitionConfig { // `END_OF_SINGLE_UTTERANCE` event and cease recognition. It will return no // more than one `StreamingRecognitionResult` with the `is_final` flag set to // `true`. + // + // The `single_utterance` field can only be used with specified models, + // otherwise an error is thrown. The `model` field in [`RecognitionConfig`][] + // must be set to: + // + // * `command_and_search` + // * `phone_call` AND additional field `useEnhanced`=`true` + // * The `model` field is left undefined. In this case the API auto-selects + // a model based on any other parameters that you set in + // `RecognitionConfig`. bool single_utterance = 2; // If `true`, interim results (tentative hypotheses) may be @@ -218,7 +228,8 @@ message RecognitionConfig { // wideband is supported. `sample_rate_hertz` must be 16000. SPEEX_WITH_HEADER_BYTE = 7; - // MP3 audio. Support all standard MP3 bitrates (which range from 32-320 + // MP3 audio. MP3 encoding is a Beta feature and only available in + // v1p1beta1. Support all standard MP3 bitrates (which range from 32-320 // kbps). When using this encoding, `sample_rate_hertz` has to match the // sample rate of the file being used. MP3 = 8; @@ -635,8 +646,8 @@ message LongRunningRecognizeMetadata { // Time of the most recent processing update. google.protobuf.Timestamp last_update_time = 3; - // The URI of the audio file being transcribed. Empty if the audio was sent - // as byte content. + // Output only. The URI of the audio file being transcribed. Empty if the + // audio was sent as byte content. string uri = 4 [(google.api.field_behavior) = OUTPUT_ONLY]; } diff --git a/google/cloud/speech_v1p1beta1/proto/cloud_speech_adaptation.proto b/google/cloud/speech_v1p1beta1/proto/cloud_speech_adaptation.proto new file mode 100644 index 00000000..4e4377c9 --- /dev/null +++ b/google/cloud/speech_v1p1beta1/proto/cloud_speech_adaptation.proto @@ -0,0 +1,318 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.cloud.speech.v1p1beta1; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/cloud/speech/v1p1beta1/resource.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/field_mask.proto"; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/genproto/googleapis/cloud/speech/v1p1beta1;speech"; +option java_multiple_files = true; +option java_outer_classname = "SpeechAdaptationProto"; +option java_package = "com.google.cloud.speech.v1p1beta1"; +option objc_class_prefix = "GCS"; + +// Service that implements Google Cloud Speech Adaptation API. +service Adaptation { + option (google.api.default_host) = "speech.googleapis.com"; + option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform"; + + // Create a set of phrase hints. Each item in the set can be a single word or + // a multi-word phrase. The items in the PhraseSet are favored by the + // recognition model when you send a call that includes the PhraseSet. + rpc CreatePhraseSet(CreatePhraseSetRequest) returns (PhraseSet) { + option (google.api.http) = { + post: "/v1p1beta1/{parent=projects/*/locations/*}/phraseSets" + body: "*" + }; + option (google.api.method_signature) = "parent,phrase_set,phrase_set_id"; + } + + // Get a phrase set. + rpc GetPhraseSet(GetPhraseSetRequest) returns (PhraseSet) { + option (google.api.http) = { + get: "/v1p1beta1/{name=projects/*/locations/*/phraseSets/*}" + }; + option (google.api.method_signature) = "name"; + } + + // List phrase sets. + rpc ListPhraseSet(ListPhraseSetRequest) returns (ListPhraseSetResponse) { + option (google.api.http) = { + get: "/v1p1beta1/{parent=projects/*/locations/*}/phraseSets" + }; + option (google.api.method_signature) = "parent"; + } + + // Update a phrase set. + rpc UpdatePhraseSet(UpdatePhraseSetRequest) returns (PhraseSet) { + option (google.api.http) = { + patch: "/v1p1beta1/{phrase_set.name=projects/*/locations/*/phraseSets/*}" + body: "phrase_set" + }; + } + + // Delete a phrase set. + rpc DeletePhraseSet(DeletePhraseSetRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + delete: "/v1p1beta1/{name=projects/*/locations/*/phraseSets/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Create a custom class. + rpc CreateCustomClass(CreateCustomClassRequest) returns (CustomClass) { + option (google.api.http) = { + post: "/v1p1beta1/{parent=projects/*/locations/*}/customClasses" + body: "*" + }; + option (google.api.method_signature) = "parent,custom_class,custom_class_id"; + } + + // Get a custom class. + rpc GetCustomClass(GetCustomClassRequest) returns (CustomClass) { + option (google.api.http) = { + get: "/v1p1beta1/{name=projects/*/locations/*/customClasses/*}" + }; + option (google.api.method_signature) = "name"; + } + + // List custom classes. + rpc ListCustomClasses(ListCustomClassesRequest) returns (ListCustomClassesResponse) { + option (google.api.http) = { + get: "/v1p1beta1/{parent=projects/*/locations/*}/customClasses" + }; + option (google.api.method_signature) = "parent"; + } + + // Update a custom class. + rpc UpdateCustomClass(UpdateCustomClassRequest) returns (CustomClass) { + option (google.api.http) = { + patch: "/v1p1beta1/{custom_class.name=projects/*/locations/*/customClasses/*}" + body: "custom_class" + }; + } + + // Delete a custom class. + rpc DeleteCustomClass(DeleteCustomClassRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + delete: "/v1p1beta1/{name=projects/*/locations/*/customClasses/*}" + }; + option (google.api.method_signature) = "name"; + } +} + +// Message sent by the client for the `CreatePhraseSet` method. +message CreatePhraseSetRequest { + // Required. The parent resource where this phrase set will be created. + // Format: + // {api_version}/projects/{project}/locations/{location}/phraseSets + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + child_type: "speech.googleapis.com/PhraseSet" + } + ]; + + // The ID to use for the phrase set, which will become the final + // component of the phrase set's resource name. + // + // This value should be 4-63 characters, and valid characters + // are /[a-z][0-9]-/. + string phrase_set_id = 2; + + // Required. The phrase set to create. + PhraseSet phrase_set = 3 [(google.api.field_behavior) = REQUIRED]; +} + +// Message sent by the client for the `UpdatePhraseSet` method. +message UpdatePhraseSetRequest { + // Required. The phrase set to update. + // + // The phrase set's `name` field is used to identify the set to be + // updated. Format: + // {api_version}/projects/{project}/locations/{location}/phraseSets/{phrase_set} + PhraseSet phrase_set = 1 [(google.api.field_behavior) = REQUIRED]; + + // The list of fields to be updated. + google.protobuf.FieldMask update_mask = 2; +} + +// Message sent by the client for the `GetPhraseSet` method. +message GetPhraseSetRequest { + // Required. The name of the phrase set to retrieve. + // Format: + // {api_version}/projects/{project}/locations/{location}/phraseSets/{phrase_set} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "speech.googleapis.com/PhraseSet" + } + ]; +} + +// Message sent by the client for the `ListPhraseSet` method. +message ListPhraseSetRequest { + // Required. The parent, which owns this collection of phrase set. + // Format: + // projects/{project}/locations/{location} + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + child_type: "speech.googleapis.com/PhraseSet" + } + ]; + + // The maximum number of phrase sets to return. The service may return + // fewer than this value. If unspecified, at most 50 phrase sets will be + // returned. The maximum value is 1000; values above 1000 will be coerced to + // 1000. + int32 page_size = 2; + + // A page token, received from a previous `ListPhraseSet` call. + // Provide this to retrieve the subsequent page. + // + // When paginating, all other parameters provided to `ListPhraseSet` must + // match the call that provided the page token. + string page_token = 3; +} + +// Message returned to the client by the `ListPhraseSet` method. +message ListPhraseSetResponse { + // The phrase set. + repeated PhraseSet phrase_sets = 1; + + // A token, which can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + string next_page_token = 2; +} + +// Message sent by the client for the `DeletePhraseSet` method. +message DeletePhraseSetRequest { + // Required. The name of the phrase set to delete. + // Format: + // {api_version}/projects/{project}/locations/{location}/phraseSets/{phrase_set} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "speech.googleapis.com/PhraseSet" + } + ]; +} + +// Message sent by the client for the `CreateCustomClass` method. +message CreateCustomClassRequest { + // Required. The parent resource where this custom class will be created. + // Format: + // {api_version}/projects/{project}/locations/{location}/customClasses + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + child_type: "speech.googleapis.com/CustomClass" + } + ]; + + // The ID to use for the custom class, which will become the final + // component of the custom class' resource name. + // + // This value should be 4-63 characters, and valid characters + // are /[a-z][0-9]-/. + string custom_class_id = 2; + + // Required. The custom class to create. + CustomClass custom_class = 3 [(google.api.field_behavior) = REQUIRED]; +} + +// Message sent by the client for the `UpdateCustomClass` method. +message UpdateCustomClassRequest { + // Required. The custom class to update. + // + // The custom class's `name` field is used to identify the custom class to be + // updated. Format: + // {api_version}/projects/{project}/locations/{location}/customClasses/{custom_class} + CustomClass custom_class = 1 [(google.api.field_behavior) = REQUIRED]; + + // The list of fields to be updated. + google.protobuf.FieldMask update_mask = 2; +} + +// Message sent by the client for the `GetCustomClass` method. +message GetCustomClassRequest { + // Required. The name of the custom class to retrieve. + // Format: + // {api_version}/projects/{project}/locations/{location}/customClasses/{custom_class} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "speech.googleapis.com/CustomClass" + } + ]; +} + +// Message sent by the client for the `ListCustomClasses` method. +message ListCustomClassesRequest { + // Required. The parent, which owns this collection of custom classes. + // Format: + // {api_version}/projects/{project}/locations/{location}/customClasses + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + child_type: "speech.googleapis.com/CustomClass" + } + ]; + + // The maximum number of custom classes to return. The service may return + // fewer than this value. If unspecified, at most 50 custom classes will be + // returned. The maximum value is 1000; values above 1000 will be coerced to + // 1000. + int32 page_size = 2; + + // A page token, received from a previous `ListCustomClass` call. + // Provide this to retrieve the subsequent page. + // + // When paginating, all other parameters provided to `ListCustomClass` must + // match the call that provided the page token. + string page_token = 3; +} + +// Message returned to the client by the `ListCustomClasses` method. +message ListCustomClassesResponse { + // The custom classes. + repeated CustomClass custom_classes = 1; + + // A token, which can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + string next_page_token = 2; +} + +// Message sent by the client for the `DeleteCustomClass` method. +message DeleteCustomClassRequest { + // Required. The name of the custom class to delete. + // Format: + // {api_version}/projects/{project}/locations/{location}/customClasses/{custom_class} + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "speech.googleapis.com/CustomClass" + } + ]; +} diff --git a/google/cloud/speech_v1p1beta1/proto/resource.proto b/google/cloud/speech_v1p1beta1/proto/resource.proto index 5bb379ff..74cee064 100644 --- a/google/cloud/speech_v1p1beta1/proto/resource.proto +++ b/google/cloud/speech_v1p1beta1/proto/resource.proto @@ -1,4 +1,4 @@ -// Copyright 2020 Google LLC +// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,8 +16,8 @@ syntax = "proto3"; package google.cloud.speech.v1p1beta1; -import "google/api/annotations.proto"; import "google/api/resource.proto"; +import "google/api/annotations.proto"; option cc_enable_arenas = true; option go_package = "google.golang.org/genproto/googleapis/cloud/speech/v1p1beta1;speech"; @@ -45,7 +45,7 @@ message CustomClass { string name = 1; // If this custom class is a resource, the custom_class_id is the resource id - // of the CustomClass. + // of the CustomClass. Case sensitive. string custom_class_id = 2; // A collection of class items. @@ -121,9 +121,12 @@ message SpeechAdaptation { // phrase set can use any custom class. repeated PhraseSet phrase_sets = 1; + // A collection of phrase set resource names to use. + repeated string phrase_set_references = 2; + // A collection of custom classes. To specify the classes inline, leave the // class' `name` blank and fill in the rest of its fields, giving it a unique // `custom_class_id`. Refer to the inline defined class in phrase hints by its // `custom_class_id`. - repeated CustomClass custom_classes = 2; + repeated CustomClass custom_classes = 3; } diff --git a/google/cloud/speech_v1p1beta1/services/adaptation/__init__.py b/google/cloud/speech_v1p1beta1/services/adaptation/__init__.py new file mode 100644 index 00000000..6de88b81 --- /dev/null +++ b/google/cloud/speech_v1p1beta1/services/adaptation/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- + +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from .client import AdaptationClient +from .async_client import AdaptationAsyncClient + +__all__ = ( + "AdaptationClient", + "AdaptationAsyncClient", +) diff --git a/google/cloud/speech_v1p1beta1/services/adaptation/async_client.py b/google/cloud/speech_v1p1beta1/services/adaptation/async_client.py new file mode 100644 index 00000000..96827966 --- /dev/null +++ b/google/cloud/speech_v1p1beta1/services/adaptation/async_client.py @@ -0,0 +1,942 @@ +# -*- coding: utf-8 -*- + +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from collections import OrderedDict +import functools +import re +from typing import Dict, Sequence, Tuple, Type, Union +import pkg_resources + +import google.api_core.client_options as ClientOptions # type: ignore +from google.api_core import exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.speech_v1p1beta1.services.adaptation import pagers +from google.cloud.speech_v1p1beta1.types import cloud_speech_adaptation +from google.cloud.speech_v1p1beta1.types import resource + +from .transports.base import AdaptationTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import AdaptationGrpcAsyncIOTransport +from .client import AdaptationClient + + +class AdaptationAsyncClient: + """Service that implements Google Cloud Speech Adaptation API.""" + + _client: AdaptationClient + + DEFAULT_ENDPOINT = AdaptationClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AdaptationClient.DEFAULT_MTLS_ENDPOINT + + custom_class_path = staticmethod(AdaptationClient.custom_class_path) + parse_custom_class_path = staticmethod(AdaptationClient.parse_custom_class_path) + phrase_set_path = staticmethod(AdaptationClient.phrase_set_path) + parse_phrase_set_path = staticmethod(AdaptationClient.parse_phrase_set_path) + + common_billing_account_path = staticmethod( + AdaptationClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AdaptationClient.parse_common_billing_account_path + ) + + common_folder_path = staticmethod(AdaptationClient.common_folder_path) + parse_common_folder_path = staticmethod(AdaptationClient.parse_common_folder_path) + + common_organization_path = staticmethod(AdaptationClient.common_organization_path) + parse_common_organization_path = staticmethod( + AdaptationClient.parse_common_organization_path + ) + + common_project_path = staticmethod(AdaptationClient.common_project_path) + parse_common_project_path = staticmethod(AdaptationClient.parse_common_project_path) + + common_location_path = staticmethod(AdaptationClient.common_location_path) + parse_common_location_path = staticmethod( + AdaptationClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdaptationAsyncClient: The constructed client. + """ + return AdaptationClient.from_service_account_info.__func__(AdaptationAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdaptationAsyncClient: The constructed client. + """ + return AdaptationClient.from_service_account_file.__func__(AdaptationAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdaptationTransport: + """Return the transport used by the client instance. + + Returns: + AdaptationTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial( + type(AdaptationClient).get_transport_class, type(AdaptationClient) + ) + + def __init__( + self, + *, + credentials: credentials.Credentials = None, + transport: Union[str, AdaptationTransport] = "grpc_asyncio", + client_options: ClientOptions = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiate the adaptation client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.AdaptationTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + + self._client = AdaptationClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + async def create_phrase_set( + self, + request: cloud_speech_adaptation.CreatePhraseSetRequest = None, + *, + parent: str = None, + phrase_set: resource.PhraseSet = None, + phrase_set_id: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> resource.PhraseSet: + r"""Create a set of phrase hints. Each item in the set + can be a single word or a multi-word phrase. The items + in the PhraseSet are favored by the recognition model + when you send a call that includes the PhraseSet. + + Args: + request (:class:`google.cloud.speech_v1p1beta1.types.CreatePhraseSetRequest`): + The request object. Message sent by the client for the + `CreatePhraseSet` method. + parent (:class:`str`): + Required. The parent resource where this phrase set will + be created. Format: + {api_version}/projects/{project}/locations/{location}/phraseSets + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + phrase_set (:class:`google.cloud.speech_v1p1beta1.types.PhraseSet`): + Required. The phrase set to create. + This corresponds to the ``phrase_set`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + phrase_set_id (:class:`str`): + The ID to use for the phrase set, which will become the + final component of the phrase set's resource name. + + This value should be 4-63 characters, and valid + characters are /[a-z][0-9]-/. + + This corresponds to the ``phrase_set_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.speech_v1p1beta1.types.PhraseSet: + Provides "hints" to the speech + recognizer to favor specific words and + phrases in the results. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, phrase_set, phrase_set_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = cloud_speech_adaptation.CreatePhraseSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if parent is not None: + request.parent = parent + if phrase_set is not None: + request.phrase_set = phrase_set + if phrase_set_id is not None: + request.phrase_set_id = phrase_set_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_phrase_set, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_phrase_set( + self, + request: cloud_speech_adaptation.GetPhraseSetRequest = None, + *, + name: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> resource.PhraseSet: + r"""Get a phrase set. + + Args: + request (:class:`google.cloud.speech_v1p1beta1.types.GetPhraseSetRequest`): + The request object. Message sent by the client for the + `GetPhraseSet` method. + name (:class:`str`): + Required. The name of the phrase set to retrieve. + Format: + {api_version}/projects/{project}/locations/{location}/phraseSets/{phrase_set} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.speech_v1p1beta1.types.PhraseSet: + Provides "hints" to the speech + recognizer to favor specific words and + phrases in the results. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = cloud_speech_adaptation.GetPhraseSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_phrase_set, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def list_phrase_set( + self, + request: cloud_speech_adaptation.ListPhraseSetRequest = None, + *, + parent: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListPhraseSetAsyncPager: + r"""List phrase sets. + + Args: + request (:class:`google.cloud.speech_v1p1beta1.types.ListPhraseSetRequest`): + The request object. Message sent by the client for the + `ListPhraseSet` method. + parent (:class:`str`): + Required. The parent, which owns this + collection of phrase set. Format: + projects/{project}/locations/{location} + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.speech_v1p1beta1.services.adaptation.pagers.ListPhraseSetAsyncPager: + Message returned to the client by the ListPhraseSet + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = cloud_speech_adaptation.ListPhraseSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_phrase_set, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListPhraseSetAsyncPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_phrase_set( + self, + request: cloud_speech_adaptation.UpdatePhraseSetRequest = None, + *, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> resource.PhraseSet: + r"""Update a phrase set. + + Args: + request (:class:`google.cloud.speech_v1p1beta1.types.UpdatePhraseSetRequest`): + The request object. Message sent by the client for the + `UpdatePhraseSet` method. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.speech_v1p1beta1.types.PhraseSet: + Provides "hints" to the speech + recognizer to favor specific words and + phrases in the results. + + """ + # Create or coerce a protobuf request object. + + request = cloud_speech_adaptation.UpdatePhraseSetRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_phrase_set, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("phrase_set.name", request.phrase_set.name),) + ), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def delete_phrase_set( + self, + request: cloud_speech_adaptation.DeletePhraseSetRequest = None, + *, + name: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Delete a phrase set. + + Args: + request (:class:`google.cloud.speech_v1p1beta1.types.DeletePhraseSetRequest`): + The request object. Message sent by the client for the + `DeletePhraseSet` method. + name (:class:`str`): + Required. The name of the phrase set to delete. Format: + {api_version}/projects/{project}/locations/{location}/phraseSets/{phrase_set} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = cloud_speech_adaptation.DeletePhraseSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_phrase_set, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + await rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + async def create_custom_class( + self, + request: cloud_speech_adaptation.CreateCustomClassRequest = None, + *, + parent: str = None, + custom_class: resource.CustomClass = None, + custom_class_id: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> resource.CustomClass: + r"""Create a custom class. + + Args: + request (:class:`google.cloud.speech_v1p1beta1.types.CreateCustomClassRequest`): + The request object. Message sent by the client for the + `CreateCustomClass` method. + parent (:class:`str`): + Required. The parent resource where this custom class + will be created. Format: + {api_version}/projects/{project}/locations/{location}/customClasses + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + custom_class (:class:`google.cloud.speech_v1p1beta1.types.CustomClass`): + Required. The custom class to create. + This corresponds to the ``custom_class`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + custom_class_id (:class:`str`): + The ID to use for the custom class, which will become + the final component of the custom class' resource name. + + This value should be 4-63 characters, and valid + characters are /[a-z][0-9]-/. + + This corresponds to the ``custom_class_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.speech_v1p1beta1.types.CustomClass: + A set of words or phrases that + represents a common concept likely to + appear in your audio, for example a list + of passenger ship names. CustomClass + items can be substituted into + placeholders that you set in PhraseSet + phrases. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, custom_class, custom_class_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = cloud_speech_adaptation.CreateCustomClassRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if parent is not None: + request.parent = parent + if custom_class is not None: + request.custom_class = custom_class + if custom_class_id is not None: + request.custom_class_id = custom_class_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_custom_class, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_custom_class( + self, + request: cloud_speech_adaptation.GetCustomClassRequest = None, + *, + name: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> resource.CustomClass: + r"""Get a custom class. + + Args: + request (:class:`google.cloud.speech_v1p1beta1.types.GetCustomClassRequest`): + The request object. Message sent by the client for the + `GetCustomClass` method. + name (:class:`str`): + Required. The name of the custom class to retrieve. + Format: + {api_version}/projects/{project}/locations/{location}/customClasses/{custom_class} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.speech_v1p1beta1.types.CustomClass: + A set of words or phrases that + represents a common concept likely to + appear in your audio, for example a list + of passenger ship names. CustomClass + items can be substituted into + placeholders that you set in PhraseSet + phrases. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = cloud_speech_adaptation.GetCustomClassRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_custom_class, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def list_custom_classes( + self, + request: cloud_speech_adaptation.ListCustomClassesRequest = None, + *, + parent: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListCustomClassesAsyncPager: + r"""List custom classes. + + Args: + request (:class:`google.cloud.speech_v1p1beta1.types.ListCustomClassesRequest`): + The request object. Message sent by the client for the + `ListCustomClasses` method. + parent (:class:`str`): + Required. The parent, which owns this collection of + custom classes. Format: + {api_version}/projects/{project}/locations/{location}/customClasses + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.speech_v1p1beta1.services.adaptation.pagers.ListCustomClassesAsyncPager: + Message returned to the client by the ListCustomClasses + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = cloud_speech_adaptation.ListCustomClassesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_custom_classes, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListCustomClassesAsyncPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_custom_class( + self, + request: cloud_speech_adaptation.UpdateCustomClassRequest = None, + *, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> resource.CustomClass: + r"""Update a custom class. + + Args: + request (:class:`google.cloud.speech_v1p1beta1.types.UpdateCustomClassRequest`): + The request object. Message sent by the client for the + `UpdateCustomClass` method. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.speech_v1p1beta1.types.CustomClass: + A set of words or phrases that + represents a common concept likely to + appear in your audio, for example a list + of passenger ship names. CustomClass + items can be substituted into + placeholders that you set in PhraseSet + phrases. + + """ + # Create or coerce a protobuf request object. + + request = cloud_speech_adaptation.UpdateCustomClassRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_custom_class, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("custom_class.name", request.custom_class.name),) + ), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def delete_custom_class( + self, + request: cloud_speech_adaptation.DeleteCustomClassRequest = None, + *, + name: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Delete a custom class. + + Args: + request (:class:`google.cloud.speech_v1p1beta1.types.DeleteCustomClassRequest`): + The request object. Message sent by the client for the + `DeleteCustomClass` method. + name (:class:`str`): + Required. The name of the custom class to delete. + Format: + {api_version}/projects/{project}/locations/{location}/customClasses/{custom_class} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = cloud_speech_adaptation.DeleteCustomClassRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_custom_class, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + await rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-cloud-speech",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AdaptationAsyncClient",) diff --git a/google/cloud/speech_v1p1beta1/services/adaptation/client.py b/google/cloud/speech_v1p1beta1/services/adaptation/client.py new file mode 100644 index 00000000..36f9a04c --- /dev/null +++ b/google/cloud/speech_v1p1beta1/services/adaptation/client.py @@ -0,0 +1,1144 @@ +# -*- coding: utf-8 -*- + +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from collections import OrderedDict +from distutils import util +import os +import re +from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib # type: ignore +from google.api_core import exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.speech_v1p1beta1.services.adaptation import pagers +from google.cloud.speech_v1p1beta1.types import cloud_speech_adaptation +from google.cloud.speech_v1p1beta1.types import resource + +from .transports.base import AdaptationTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AdaptationGrpcTransport +from .transports.grpc_asyncio import AdaptationGrpcAsyncIOTransport + + +class AdaptationClientMeta(type): + """Metaclass for the Adaptation client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = OrderedDict() # type: Dict[str, Type[AdaptationTransport]] + _transport_registry["grpc"] = AdaptationGrpcTransport + _transport_registry["grpc_asyncio"] = AdaptationGrpcAsyncIOTransport + + def get_transport_class(cls, label: str = None,) -> Type[AdaptationTransport]: + """Return an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdaptationClient(metaclass=AdaptationClientMeta): + """Service that implements Google Cloud Speech Adaptation API.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Convert api endpoint to mTLS endpoint. + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "speech.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdaptationClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdaptationClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file(filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdaptationTransport: + """Return the transport used by the client instance. + + Returns: + AdaptationTransport: The transport used by the client instance. + """ + return self._transport + + @staticmethod + def custom_class_path(project: str, location: str, custom_class: str,) -> str: + """Return a fully-qualified custom_class string.""" + return "projects/{project}/locations/{location}/customClasses/{custom_class}".format( + project=project, location=location, custom_class=custom_class, + ) + + @staticmethod + def parse_custom_class_path(path: str) -> Dict[str, str]: + """Parse a custom_class path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/customClasses/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def phrase_set_path(project: str, location: str, phrase_set: str,) -> str: + """Return a fully-qualified phrase_set string.""" + return "projects/{project}/locations/{location}/phraseSets/{phrase_set}".format( + project=project, location=location, phrase_set=phrase_set, + ) + + @staticmethod + def parse_phrase_set_path(path: str) -> Dict[str, str]: + """Parse a phrase_set path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/phraseSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Return a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Return a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Return a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Return a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Return a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[credentials.Credentials] = None, + transport: Union[str, AdaptationTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiate the adaptation client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AdaptationTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + use_client_cert = bool( + util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + client_cert_source_func = ( + mtls.default_client_cert_source() if is_mtls else None + ) + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AdaptationTransport): + # transport is a AdaptationTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, " + "provide its scopes directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + ) + + def create_phrase_set( + self, + request: cloud_speech_adaptation.CreatePhraseSetRequest = None, + *, + parent: str = None, + phrase_set: resource.PhraseSet = None, + phrase_set_id: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> resource.PhraseSet: + r"""Create a set of phrase hints. Each item in the set + can be a single word or a multi-word phrase. The items + in the PhraseSet are favored by the recognition model + when you send a call that includes the PhraseSet. + + Args: + request (google.cloud.speech_v1p1beta1.types.CreatePhraseSetRequest): + The request object. Message sent by the client for the + `CreatePhraseSet` method. + parent (str): + Required. The parent resource where this phrase set will + be created. Format: + {api_version}/projects/{project}/locations/{location}/phraseSets + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + phrase_set (google.cloud.speech_v1p1beta1.types.PhraseSet): + Required. The phrase set to create. + This corresponds to the ``phrase_set`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + phrase_set_id (str): + The ID to use for the phrase set, which will become the + final component of the phrase set's resource name. + + This value should be 4-63 characters, and valid + characters are /[a-z][0-9]-/. + + This corresponds to the ``phrase_set_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.speech_v1p1beta1.types.PhraseSet: + Provides "hints" to the speech + recognizer to favor specific words and + phrases in the results. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, phrase_set, phrase_set_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a cloud_speech_adaptation.CreatePhraseSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, cloud_speech_adaptation.CreatePhraseSetRequest): + request = cloud_speech_adaptation.CreatePhraseSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if parent is not None: + request.parent = parent + if phrase_set is not None: + request.phrase_set = phrase_set + if phrase_set_id is not None: + request.phrase_set_id = phrase_set_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_phrase_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_phrase_set( + self, + request: cloud_speech_adaptation.GetPhraseSetRequest = None, + *, + name: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> resource.PhraseSet: + r"""Get a phrase set. + + Args: + request (google.cloud.speech_v1p1beta1.types.GetPhraseSetRequest): + The request object. Message sent by the client for the + `GetPhraseSet` method. + name (str): + Required. The name of the phrase set to retrieve. + Format: + {api_version}/projects/{project}/locations/{location}/phraseSets/{phrase_set} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.speech_v1p1beta1.types.PhraseSet: + Provides "hints" to the speech + recognizer to favor specific words and + phrases in the results. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a cloud_speech_adaptation.GetPhraseSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, cloud_speech_adaptation.GetPhraseSetRequest): + request = cloud_speech_adaptation.GetPhraseSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_phrase_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def list_phrase_set( + self, + request: cloud_speech_adaptation.ListPhraseSetRequest = None, + *, + parent: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListPhraseSetPager: + r"""List phrase sets. + + Args: + request (google.cloud.speech_v1p1beta1.types.ListPhraseSetRequest): + The request object. Message sent by the client for the + `ListPhraseSet` method. + parent (str): + Required. The parent, which owns this + collection of phrase set. Format: + projects/{project}/locations/{location} + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.speech_v1p1beta1.services.adaptation.pagers.ListPhraseSetPager: + Message returned to the client by the ListPhraseSet + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a cloud_speech_adaptation.ListPhraseSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, cloud_speech_adaptation.ListPhraseSetRequest): + request = cloud_speech_adaptation.ListPhraseSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_phrase_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListPhraseSetPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + def update_phrase_set( + self, + request: cloud_speech_adaptation.UpdatePhraseSetRequest = None, + *, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> resource.PhraseSet: + r"""Update a phrase set. + + Args: + request (google.cloud.speech_v1p1beta1.types.UpdatePhraseSetRequest): + The request object. Message sent by the client for the + `UpdatePhraseSet` method. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.speech_v1p1beta1.types.PhraseSet: + Provides "hints" to the speech + recognizer to favor specific words and + phrases in the results. + + """ + # Create or coerce a protobuf request object. + + # Minor optimization to avoid making a copy if the user passes + # in a cloud_speech_adaptation.UpdatePhraseSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, cloud_speech_adaptation.UpdatePhraseSetRequest): + request = cloud_speech_adaptation.UpdatePhraseSetRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_phrase_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("phrase_set.name", request.phrase_set.name),) + ), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def delete_phrase_set( + self, + request: cloud_speech_adaptation.DeletePhraseSetRequest = None, + *, + name: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Delete a phrase set. + + Args: + request (google.cloud.speech_v1p1beta1.types.DeletePhraseSetRequest): + The request object. Message sent by the client for the + `DeletePhraseSet` method. + name (str): + Required. The name of the phrase set to delete. Format: + {api_version}/projects/{project}/locations/{location}/phraseSets/{phrase_set} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a cloud_speech_adaptation.DeletePhraseSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, cloud_speech_adaptation.DeletePhraseSetRequest): + request = cloud_speech_adaptation.DeletePhraseSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_phrase_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + def create_custom_class( + self, + request: cloud_speech_adaptation.CreateCustomClassRequest = None, + *, + parent: str = None, + custom_class: resource.CustomClass = None, + custom_class_id: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> resource.CustomClass: + r"""Create a custom class. + + Args: + request (google.cloud.speech_v1p1beta1.types.CreateCustomClassRequest): + The request object. Message sent by the client for the + `CreateCustomClass` method. + parent (str): + Required. The parent resource where this custom class + will be created. Format: + {api_version}/projects/{project}/locations/{location}/customClasses + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + custom_class (google.cloud.speech_v1p1beta1.types.CustomClass): + Required. The custom class to create. + This corresponds to the ``custom_class`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + custom_class_id (str): + The ID to use for the custom class, which will become + the final component of the custom class' resource name. + + This value should be 4-63 characters, and valid + characters are /[a-z][0-9]-/. + + This corresponds to the ``custom_class_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.speech_v1p1beta1.types.CustomClass: + A set of words or phrases that + represents a common concept likely to + appear in your audio, for example a list + of passenger ship names. CustomClass + items can be substituted into + placeholders that you set in PhraseSet + phrases. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, custom_class, custom_class_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a cloud_speech_adaptation.CreateCustomClassRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, cloud_speech_adaptation.CreateCustomClassRequest): + request = cloud_speech_adaptation.CreateCustomClassRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if parent is not None: + request.parent = parent + if custom_class is not None: + request.custom_class = custom_class + if custom_class_id is not None: + request.custom_class_id = custom_class_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_custom_class] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_custom_class( + self, + request: cloud_speech_adaptation.GetCustomClassRequest = None, + *, + name: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> resource.CustomClass: + r"""Get a custom class. + + Args: + request (google.cloud.speech_v1p1beta1.types.GetCustomClassRequest): + The request object. Message sent by the client for the + `GetCustomClass` method. + name (str): + Required. The name of the custom class to retrieve. + Format: + {api_version}/projects/{project}/locations/{location}/customClasses/{custom_class} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.speech_v1p1beta1.types.CustomClass: + A set of words or phrases that + represents a common concept likely to + appear in your audio, for example a list + of passenger ship names. CustomClass + items can be substituted into + placeholders that you set in PhraseSet + phrases. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a cloud_speech_adaptation.GetCustomClassRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, cloud_speech_adaptation.GetCustomClassRequest): + request = cloud_speech_adaptation.GetCustomClassRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_custom_class] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def list_custom_classes( + self, + request: cloud_speech_adaptation.ListCustomClassesRequest = None, + *, + parent: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListCustomClassesPager: + r"""List custom classes. + + Args: + request (google.cloud.speech_v1p1beta1.types.ListCustomClassesRequest): + The request object. Message sent by the client for the + `ListCustomClasses` method. + parent (str): + Required. The parent, which owns this collection of + custom classes. Format: + {api_version}/projects/{project}/locations/{location}/customClasses + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.speech_v1p1beta1.services.adaptation.pagers.ListCustomClassesPager: + Message returned to the client by the ListCustomClasses + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a cloud_speech_adaptation.ListCustomClassesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, cloud_speech_adaptation.ListCustomClassesRequest): + request = cloud_speech_adaptation.ListCustomClassesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_custom_classes] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListCustomClassesPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + def update_custom_class( + self, + request: cloud_speech_adaptation.UpdateCustomClassRequest = None, + *, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> resource.CustomClass: + r"""Update a custom class. + + Args: + request (google.cloud.speech_v1p1beta1.types.UpdateCustomClassRequest): + The request object. Message sent by the client for the + `UpdateCustomClass` method. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.speech_v1p1beta1.types.CustomClass: + A set of words or phrases that + represents a common concept likely to + appear in your audio, for example a list + of passenger ship names. CustomClass + items can be substituted into + placeholders that you set in PhraseSet + phrases. + + """ + # Create or coerce a protobuf request object. + + # Minor optimization to avoid making a copy if the user passes + # in a cloud_speech_adaptation.UpdateCustomClassRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, cloud_speech_adaptation.UpdateCustomClassRequest): + request = cloud_speech_adaptation.UpdateCustomClassRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_custom_class] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("custom_class.name", request.custom_class.name),) + ), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def delete_custom_class( + self, + request: cloud_speech_adaptation.DeleteCustomClassRequest = None, + *, + name: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Delete a custom class. + + Args: + request (google.cloud.speech_v1p1beta1.types.DeleteCustomClassRequest): + The request object. Message sent by the client for the + `DeleteCustomClass` method. + name (str): + Required. The name of the custom class to delete. + Format: + {api_version}/projects/{project}/locations/{location}/customClasses/{custom_class} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a cloud_speech_adaptation.DeleteCustomClassRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, cloud_speech_adaptation.DeleteCustomClassRequest): + request = cloud_speech_adaptation.DeleteCustomClassRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_custom_class] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-cloud-speech",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AdaptationClient",) diff --git a/google/cloud/speech_v1p1beta1/services/adaptation/pagers.py b/google/cloud/speech_v1p1beta1/services/adaptation/pagers.py new file mode 100644 index 00000000..a93a47e7 --- /dev/null +++ b/google/cloud/speech_v1p1beta1/services/adaptation/pagers.py @@ -0,0 +1,292 @@ +# -*- coding: utf-8 -*- + +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from typing import ( + Any, + AsyncIterable, + Awaitable, + Callable, + Iterable, + Sequence, + Tuple, + Optional, +) + +from google.cloud.speech_v1p1beta1.types import cloud_speech_adaptation +from google.cloud.speech_v1p1beta1.types import resource + + +class ListPhraseSetPager: + """A pager for iterating through ``list_phrase_set`` requests. + + This class thinly wraps an initial + :class:`google.cloud.speech_v1p1beta1.types.ListPhraseSetResponse` object, and + provides an ``__iter__`` method to iterate through its + ``phrase_sets`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListPhraseSet`` requests and continue to iterate + through the ``phrase_sets`` field on the + corresponding responses. + + All the usual :class:`google.cloud.speech_v1p1beta1.types.ListPhraseSetResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., cloud_speech_adaptation.ListPhraseSetResponse], + request: cloud_speech_adaptation.ListPhraseSetRequest, + response: cloud_speech_adaptation.ListPhraseSetResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.speech_v1p1beta1.types.ListPhraseSetRequest): + The initial request object. + response (google.cloud.speech_v1p1beta1.types.ListPhraseSetResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = cloud_speech_adaptation.ListPhraseSetRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterable[cloud_speech_adaptation.ListPhraseSetResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterable[resource.PhraseSet]: + for page in self.pages: + yield from page.phrase_sets + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListPhraseSetAsyncPager: + """A pager for iterating through ``list_phrase_set`` requests. + + This class thinly wraps an initial + :class:`google.cloud.speech_v1p1beta1.types.ListPhraseSetResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``phrase_sets`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListPhraseSet`` requests and continue to iterate + through the ``phrase_sets`` field on the + corresponding responses. + + All the usual :class:`google.cloud.speech_v1p1beta1.types.ListPhraseSetResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., Awaitable[cloud_speech_adaptation.ListPhraseSetResponse]], + request: cloud_speech_adaptation.ListPhraseSetRequest, + response: cloud_speech_adaptation.ListPhraseSetResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.speech_v1p1beta1.types.ListPhraseSetRequest): + The initial request object. + response (google.cloud.speech_v1p1beta1.types.ListPhraseSetResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = cloud_speech_adaptation.ListPhraseSetRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterable[cloud_speech_adaptation.ListPhraseSetResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__(self) -> AsyncIterable[resource.PhraseSet]: + async def async_generator(): + async for page in self.pages: + for response in page.phrase_sets: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListCustomClassesPager: + """A pager for iterating through ``list_custom_classes`` requests. + + This class thinly wraps an initial + :class:`google.cloud.speech_v1p1beta1.types.ListCustomClassesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``custom_classes`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListCustomClasses`` requests and continue to iterate + through the ``custom_classes`` field on the + corresponding responses. + + All the usual :class:`google.cloud.speech_v1p1beta1.types.ListCustomClassesResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., cloud_speech_adaptation.ListCustomClassesResponse], + request: cloud_speech_adaptation.ListCustomClassesRequest, + response: cloud_speech_adaptation.ListCustomClassesResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.speech_v1p1beta1.types.ListCustomClassesRequest): + The initial request object. + response (google.cloud.speech_v1p1beta1.types.ListCustomClassesResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = cloud_speech_adaptation.ListCustomClassesRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterable[cloud_speech_adaptation.ListCustomClassesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterable[resource.CustomClass]: + for page in self.pages: + yield from page.custom_classes + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListCustomClassesAsyncPager: + """A pager for iterating through ``list_custom_classes`` requests. + + This class thinly wraps an initial + :class:`google.cloud.speech_v1p1beta1.types.ListCustomClassesResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``custom_classes`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListCustomClasses`` requests and continue to iterate + through the ``custom_classes`` field on the + corresponding responses. + + All the usual :class:`google.cloud.speech_v1p1beta1.types.ListCustomClassesResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., Awaitable[cloud_speech_adaptation.ListCustomClassesResponse] + ], + request: cloud_speech_adaptation.ListCustomClassesRequest, + response: cloud_speech_adaptation.ListCustomClassesResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.speech_v1p1beta1.types.ListCustomClassesRequest): + The initial request object. + response (google.cloud.speech_v1p1beta1.types.ListCustomClassesResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = cloud_speech_adaptation.ListCustomClassesRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterable[cloud_speech_adaptation.ListCustomClassesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__(self) -> AsyncIterable[resource.CustomClass]: + async def async_generator(): + async for page in self.pages: + for response in page.custom_classes: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/cloud/speech_v1p1beta1/services/adaptation/transports/__init__.py b/google/cloud/speech_v1p1beta1/services/adaptation/transports/__init__.py new file mode 100644 index 00000000..b9694a54 --- /dev/null +++ b/google/cloud/speech_v1p1beta1/services/adaptation/transports/__init__.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- + +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from collections import OrderedDict +from typing import Dict, Type + +from .base import AdaptationTransport +from .grpc import AdaptationGrpcTransport +from .grpc_asyncio import AdaptationGrpcAsyncIOTransport + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[AdaptationTransport]] +_transport_registry["grpc"] = AdaptationGrpcTransport +_transport_registry["grpc_asyncio"] = AdaptationGrpcAsyncIOTransport + +__all__ = ( + "AdaptationTransport", + "AdaptationGrpcTransport", + "AdaptationGrpcAsyncIOTransport", +) diff --git a/google/cloud/speech_v1p1beta1/services/adaptation/transports/base.py b/google/cloud/speech_v1p1beta1/services/adaptation/transports/base.py new file mode 100644 index 00000000..765ebd1c --- /dev/null +++ b/google/cloud/speech_v1p1beta1/services/adaptation/transports/base.py @@ -0,0 +1,238 @@ +# -*- coding: utf-8 -*- + +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import abc +import typing +import pkg_resources + +from google import auth # type: ignore +from google.api_core import exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials # type: ignore + +from google.cloud.speech_v1p1beta1.types import cloud_speech_adaptation +from google.cloud.speech_v1p1beta1.types import resource +from google.protobuf import empty_pb2 as empty # type: ignore + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-cloud-speech",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AdaptationTransport(abc.ABC): + """Abstract transport class for Adaptation.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + + def __init__( + self, + *, + host: str = "speech.googleapis.com", + credentials: credentials.Credentials = None, + credentials_file: typing.Optional[str] = None, + scopes: typing.Optional[typing.Sequence[str]] = AUTH_SCOPES, + quota_project_id: typing.Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scope (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = auth.load_credentials_from_file( + credentials_file, scopes=scopes, quota_project_id=quota_project_id + ) + + elif credentials is None: + credentials, _ = auth.default( + scopes=scopes, quota_project_id=quota_project_id + ) + + # Save the credentials. + self._credentials = credentials + + # Lifted into its own function so it can be stubbed out during tests. + self._prep_wrapped_messages(client_info) + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.create_phrase_set: gapic_v1.method.wrap_method( + self.create_phrase_set, default_timeout=None, client_info=client_info, + ), + self.get_phrase_set: gapic_v1.method.wrap_method( + self.get_phrase_set, default_timeout=None, client_info=client_info, + ), + self.list_phrase_set: gapic_v1.method.wrap_method( + self.list_phrase_set, default_timeout=None, client_info=client_info, + ), + self.update_phrase_set: gapic_v1.method.wrap_method( + self.update_phrase_set, default_timeout=None, client_info=client_info, + ), + self.delete_phrase_set: gapic_v1.method.wrap_method( + self.delete_phrase_set, default_timeout=None, client_info=client_info, + ), + self.create_custom_class: gapic_v1.method.wrap_method( + self.create_custom_class, default_timeout=None, client_info=client_info, + ), + self.get_custom_class: gapic_v1.method.wrap_method( + self.get_custom_class, default_timeout=None, client_info=client_info, + ), + self.list_custom_classes: gapic_v1.method.wrap_method( + self.list_custom_classes, default_timeout=None, client_info=client_info, + ), + self.update_custom_class: gapic_v1.method.wrap_method( + self.update_custom_class, default_timeout=None, client_info=client_info, + ), + self.delete_custom_class: gapic_v1.method.wrap_method( + self.delete_custom_class, default_timeout=None, client_info=client_info, + ), + } + + @property + def create_phrase_set( + self, + ) -> typing.Callable[ + [cloud_speech_adaptation.CreatePhraseSetRequest], + typing.Union[resource.PhraseSet, typing.Awaitable[resource.PhraseSet]], + ]: + raise NotImplementedError() + + @property + def get_phrase_set( + self, + ) -> typing.Callable[ + [cloud_speech_adaptation.GetPhraseSetRequest], + typing.Union[resource.PhraseSet, typing.Awaitable[resource.PhraseSet]], + ]: + raise NotImplementedError() + + @property + def list_phrase_set( + self, + ) -> typing.Callable[ + [cloud_speech_adaptation.ListPhraseSetRequest], + typing.Union[ + cloud_speech_adaptation.ListPhraseSetResponse, + typing.Awaitable[cloud_speech_adaptation.ListPhraseSetResponse], + ], + ]: + raise NotImplementedError() + + @property + def update_phrase_set( + self, + ) -> typing.Callable[ + [cloud_speech_adaptation.UpdatePhraseSetRequest], + typing.Union[resource.PhraseSet, typing.Awaitable[resource.PhraseSet]], + ]: + raise NotImplementedError() + + @property + def delete_phrase_set( + self, + ) -> typing.Callable[ + [cloud_speech_adaptation.DeletePhraseSetRequest], + typing.Union[empty.Empty, typing.Awaitable[empty.Empty]], + ]: + raise NotImplementedError() + + @property + def create_custom_class( + self, + ) -> typing.Callable[ + [cloud_speech_adaptation.CreateCustomClassRequest], + typing.Union[resource.CustomClass, typing.Awaitable[resource.CustomClass]], + ]: + raise NotImplementedError() + + @property + def get_custom_class( + self, + ) -> typing.Callable[ + [cloud_speech_adaptation.GetCustomClassRequest], + typing.Union[resource.CustomClass, typing.Awaitable[resource.CustomClass]], + ]: + raise NotImplementedError() + + @property + def list_custom_classes( + self, + ) -> typing.Callable[ + [cloud_speech_adaptation.ListCustomClassesRequest], + typing.Union[ + cloud_speech_adaptation.ListCustomClassesResponse, + typing.Awaitable[cloud_speech_adaptation.ListCustomClassesResponse], + ], + ]: + raise NotImplementedError() + + @property + def update_custom_class( + self, + ) -> typing.Callable[ + [cloud_speech_adaptation.UpdateCustomClassRequest], + typing.Union[resource.CustomClass, typing.Awaitable[resource.CustomClass]], + ]: + raise NotImplementedError() + + @property + def delete_custom_class( + self, + ) -> typing.Callable[ + [cloud_speech_adaptation.DeleteCustomClassRequest], + typing.Union[empty.Empty, typing.Awaitable[empty.Empty]], + ]: + raise NotImplementedError() + + +__all__ = ("AdaptationTransport",) diff --git a/google/cloud/speech_v1p1beta1/services/adaptation/transports/grpc.py b/google/cloud/speech_v1p1beta1/services/adaptation/transports/grpc.py new file mode 100644 index 00000000..f5842033 --- /dev/null +++ b/google/cloud/speech_v1p1beta1/services/adaptation/transports/grpc.py @@ -0,0 +1,529 @@ +# -*- coding: utf-8 -*- + +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google import auth # type: ignore +from google.auth import credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.cloud.speech_v1p1beta1.types import cloud_speech_adaptation +from google.cloud.speech_v1p1beta1.types import resource +from google.protobuf import empty_pb2 as empty # type: ignore + +from .base import AdaptationTransport, DEFAULT_CLIENT_INFO + + +class AdaptationGrpcTransport(AdaptationTransport): + """gRPC backend transport for Adaptation. + + Service that implements Google Cloud Speech Adaptation API. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "speech.googleapis.com", + credentials: credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or applicatin default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._ssl_channel_credentials = ssl_channel_credentials + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Sanity check: Ensure that channel and credentials are not both + # provided. + credentials = False + + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + elif api_mtls_endpoint: + host = ( + api_mtls_endpoint + if ":" in api_mtls_endpoint + else api_mtls_endpoint + ":443" + ) + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + ssl_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + ssl_credentials = SslCredentials().ssl_credentials + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + self._ssl_channel_credentials = ssl_credentials + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=self._ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + self._stubs = {} # type: Dict[str, Callable] + + # Run the base constructor. + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + client_info=client_info, + ) + + @classmethod + def create_channel( + cls, + host: str = "speech.googleapis.com", + credentials: credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + address (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + scopes = scopes or cls.AUTH_SCOPES + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def create_phrase_set( + self, + ) -> Callable[[cloud_speech_adaptation.CreatePhraseSetRequest], resource.PhraseSet]: + r"""Return a callable for the create phrase set method over gRPC. + + Create a set of phrase hints. Each item in the set + can be a single word or a multi-word phrase. The items + in the PhraseSet are favored by the recognition model + when you send a call that includes the PhraseSet. + + Returns: + Callable[[~.CreatePhraseSetRequest], + ~.PhraseSet]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_phrase_set" not in self._stubs: + self._stubs["create_phrase_set"] = self.grpc_channel.unary_unary( + "/google.cloud.speech.v1p1beta1.Adaptation/CreatePhraseSet", + request_serializer=cloud_speech_adaptation.CreatePhraseSetRequest.serialize, + response_deserializer=resource.PhraseSet.deserialize, + ) + return self._stubs["create_phrase_set"] + + @property + def get_phrase_set( + self, + ) -> Callable[[cloud_speech_adaptation.GetPhraseSetRequest], resource.PhraseSet]: + r"""Return a callable for the get phrase set method over gRPC. + + Get a phrase set. + + Returns: + Callable[[~.GetPhraseSetRequest], + ~.PhraseSet]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_phrase_set" not in self._stubs: + self._stubs["get_phrase_set"] = self.grpc_channel.unary_unary( + "/google.cloud.speech.v1p1beta1.Adaptation/GetPhraseSet", + request_serializer=cloud_speech_adaptation.GetPhraseSetRequest.serialize, + response_deserializer=resource.PhraseSet.deserialize, + ) + return self._stubs["get_phrase_set"] + + @property + def list_phrase_set( + self, + ) -> Callable[ + [cloud_speech_adaptation.ListPhraseSetRequest], + cloud_speech_adaptation.ListPhraseSetResponse, + ]: + r"""Return a callable for the list phrase set method over gRPC. + + List phrase sets. + + Returns: + Callable[[~.ListPhraseSetRequest], + ~.ListPhraseSetResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_phrase_set" not in self._stubs: + self._stubs["list_phrase_set"] = self.grpc_channel.unary_unary( + "/google.cloud.speech.v1p1beta1.Adaptation/ListPhraseSet", + request_serializer=cloud_speech_adaptation.ListPhraseSetRequest.serialize, + response_deserializer=cloud_speech_adaptation.ListPhraseSetResponse.deserialize, + ) + return self._stubs["list_phrase_set"] + + @property + def update_phrase_set( + self, + ) -> Callable[[cloud_speech_adaptation.UpdatePhraseSetRequest], resource.PhraseSet]: + r"""Return a callable for the update phrase set method over gRPC. + + Update a phrase set. + + Returns: + Callable[[~.UpdatePhraseSetRequest], + ~.PhraseSet]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_phrase_set" not in self._stubs: + self._stubs["update_phrase_set"] = self.grpc_channel.unary_unary( + "/google.cloud.speech.v1p1beta1.Adaptation/UpdatePhraseSet", + request_serializer=cloud_speech_adaptation.UpdatePhraseSetRequest.serialize, + response_deserializer=resource.PhraseSet.deserialize, + ) + return self._stubs["update_phrase_set"] + + @property + def delete_phrase_set( + self, + ) -> Callable[[cloud_speech_adaptation.DeletePhraseSetRequest], empty.Empty]: + r"""Return a callable for the delete phrase set method over gRPC. + + Delete a phrase set. + + Returns: + Callable[[~.DeletePhraseSetRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_phrase_set" not in self._stubs: + self._stubs["delete_phrase_set"] = self.grpc_channel.unary_unary( + "/google.cloud.speech.v1p1beta1.Adaptation/DeletePhraseSet", + request_serializer=cloud_speech_adaptation.DeletePhraseSetRequest.serialize, + response_deserializer=empty.Empty.FromString, + ) + return self._stubs["delete_phrase_set"] + + @property + def create_custom_class( + self, + ) -> Callable[ + [cloud_speech_adaptation.CreateCustomClassRequest], resource.CustomClass + ]: + r"""Return a callable for the create custom class method over gRPC. + + Create a custom class. + + Returns: + Callable[[~.CreateCustomClassRequest], + ~.CustomClass]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_custom_class" not in self._stubs: + self._stubs["create_custom_class"] = self.grpc_channel.unary_unary( + "/google.cloud.speech.v1p1beta1.Adaptation/CreateCustomClass", + request_serializer=cloud_speech_adaptation.CreateCustomClassRequest.serialize, + response_deserializer=resource.CustomClass.deserialize, + ) + return self._stubs["create_custom_class"] + + @property + def get_custom_class( + self, + ) -> Callable[ + [cloud_speech_adaptation.GetCustomClassRequest], resource.CustomClass + ]: + r"""Return a callable for the get custom class method over gRPC. + + Get a custom class. + + Returns: + Callable[[~.GetCustomClassRequest], + ~.CustomClass]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_custom_class" not in self._stubs: + self._stubs["get_custom_class"] = self.grpc_channel.unary_unary( + "/google.cloud.speech.v1p1beta1.Adaptation/GetCustomClass", + request_serializer=cloud_speech_adaptation.GetCustomClassRequest.serialize, + response_deserializer=resource.CustomClass.deserialize, + ) + return self._stubs["get_custom_class"] + + @property + def list_custom_classes( + self, + ) -> Callable[ + [cloud_speech_adaptation.ListCustomClassesRequest], + cloud_speech_adaptation.ListCustomClassesResponse, + ]: + r"""Return a callable for the list custom classes method over gRPC. + + List custom classes. + + Returns: + Callable[[~.ListCustomClassesRequest], + ~.ListCustomClassesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_custom_classes" not in self._stubs: + self._stubs["list_custom_classes"] = self.grpc_channel.unary_unary( + "/google.cloud.speech.v1p1beta1.Adaptation/ListCustomClasses", + request_serializer=cloud_speech_adaptation.ListCustomClassesRequest.serialize, + response_deserializer=cloud_speech_adaptation.ListCustomClassesResponse.deserialize, + ) + return self._stubs["list_custom_classes"] + + @property + def update_custom_class( + self, + ) -> Callable[ + [cloud_speech_adaptation.UpdateCustomClassRequest], resource.CustomClass + ]: + r"""Return a callable for the update custom class method over gRPC. + + Update a custom class. + + Returns: + Callable[[~.UpdateCustomClassRequest], + ~.CustomClass]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_custom_class" not in self._stubs: + self._stubs["update_custom_class"] = self.grpc_channel.unary_unary( + "/google.cloud.speech.v1p1beta1.Adaptation/UpdateCustomClass", + request_serializer=cloud_speech_adaptation.UpdateCustomClassRequest.serialize, + response_deserializer=resource.CustomClass.deserialize, + ) + return self._stubs["update_custom_class"] + + @property + def delete_custom_class( + self, + ) -> Callable[[cloud_speech_adaptation.DeleteCustomClassRequest], empty.Empty]: + r"""Return a callable for the delete custom class method over gRPC. + + Delete a custom class. + + Returns: + Callable[[~.DeleteCustomClassRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_custom_class" not in self._stubs: + self._stubs["delete_custom_class"] = self.grpc_channel.unary_unary( + "/google.cloud.speech.v1p1beta1.Adaptation/DeleteCustomClass", + request_serializer=cloud_speech_adaptation.DeleteCustomClassRequest.serialize, + response_deserializer=empty.Empty.FromString, + ) + return self._stubs["delete_custom_class"] + + +__all__ = ("AdaptationGrpcTransport",) diff --git a/google/cloud/speech_v1p1beta1/services/adaptation/transports/grpc_asyncio.py b/google/cloud/speech_v1p1beta1/services/adaptation/transports/grpc_asyncio.py new file mode 100644 index 00000000..b1aafed5 --- /dev/null +++ b/google/cloud/speech_v1p1beta1/services/adaptation/transports/grpc_asyncio.py @@ -0,0 +1,545 @@ +# -*- coding: utf-8 -*- + +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers_async # type: ignore +from google import auth # type: ignore +from google.auth import credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.speech_v1p1beta1.types import cloud_speech_adaptation +from google.cloud.speech_v1p1beta1.types import resource +from google.protobuf import empty_pb2 as empty # type: ignore + +from .base import AdaptationTransport, DEFAULT_CLIENT_INFO +from .grpc import AdaptationGrpcTransport + + +class AdaptationGrpcAsyncIOTransport(AdaptationTransport): + """gRPC AsyncIO backend transport for Adaptation. + + Service that implements Google Cloud Speech Adaptation API. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "speech.googleapis.com", + credentials: credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + address (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + scopes = scopes or cls.AUTH_SCOPES + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "speech.googleapis.com", + credentials: credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: aio.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id=None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or applicatin default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._ssl_channel_credentials = ssl_channel_credentials + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Sanity check: Ensure that channel and credentials are not both + # provided. + credentials = False + + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + elif api_mtls_endpoint: + host = ( + api_mtls_endpoint + if ":" in api_mtls_endpoint + else api_mtls_endpoint + ":443" + ) + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + ssl_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + ssl_credentials = SslCredentials().ssl_credentials + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + self._ssl_channel_credentials = ssl_credentials + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=self._ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Run the base constructor. + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + client_info=client_info, + ) + + self._stubs = {} + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def create_phrase_set( + self, + ) -> Callable[ + [cloud_speech_adaptation.CreatePhraseSetRequest], Awaitable[resource.PhraseSet] + ]: + r"""Return a callable for the create phrase set method over gRPC. + + Create a set of phrase hints. Each item in the set + can be a single word or a multi-word phrase. The items + in the PhraseSet are favored by the recognition model + when you send a call that includes the PhraseSet. + + Returns: + Callable[[~.CreatePhraseSetRequest], + Awaitable[~.PhraseSet]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_phrase_set" not in self._stubs: + self._stubs["create_phrase_set"] = self.grpc_channel.unary_unary( + "/google.cloud.speech.v1p1beta1.Adaptation/CreatePhraseSet", + request_serializer=cloud_speech_adaptation.CreatePhraseSetRequest.serialize, + response_deserializer=resource.PhraseSet.deserialize, + ) + return self._stubs["create_phrase_set"] + + @property + def get_phrase_set( + self, + ) -> Callable[ + [cloud_speech_adaptation.GetPhraseSetRequest], Awaitable[resource.PhraseSet] + ]: + r"""Return a callable for the get phrase set method over gRPC. + + Get a phrase set. + + Returns: + Callable[[~.GetPhraseSetRequest], + Awaitable[~.PhraseSet]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_phrase_set" not in self._stubs: + self._stubs["get_phrase_set"] = self.grpc_channel.unary_unary( + "/google.cloud.speech.v1p1beta1.Adaptation/GetPhraseSet", + request_serializer=cloud_speech_adaptation.GetPhraseSetRequest.serialize, + response_deserializer=resource.PhraseSet.deserialize, + ) + return self._stubs["get_phrase_set"] + + @property + def list_phrase_set( + self, + ) -> Callable[ + [cloud_speech_adaptation.ListPhraseSetRequest], + Awaitable[cloud_speech_adaptation.ListPhraseSetResponse], + ]: + r"""Return a callable for the list phrase set method over gRPC. + + List phrase sets. + + Returns: + Callable[[~.ListPhraseSetRequest], + Awaitable[~.ListPhraseSetResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_phrase_set" not in self._stubs: + self._stubs["list_phrase_set"] = self.grpc_channel.unary_unary( + "/google.cloud.speech.v1p1beta1.Adaptation/ListPhraseSet", + request_serializer=cloud_speech_adaptation.ListPhraseSetRequest.serialize, + response_deserializer=cloud_speech_adaptation.ListPhraseSetResponse.deserialize, + ) + return self._stubs["list_phrase_set"] + + @property + def update_phrase_set( + self, + ) -> Callable[ + [cloud_speech_adaptation.UpdatePhraseSetRequest], Awaitable[resource.PhraseSet] + ]: + r"""Return a callable for the update phrase set method over gRPC. + + Update a phrase set. + + Returns: + Callable[[~.UpdatePhraseSetRequest], + Awaitable[~.PhraseSet]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_phrase_set" not in self._stubs: + self._stubs["update_phrase_set"] = self.grpc_channel.unary_unary( + "/google.cloud.speech.v1p1beta1.Adaptation/UpdatePhraseSet", + request_serializer=cloud_speech_adaptation.UpdatePhraseSetRequest.serialize, + response_deserializer=resource.PhraseSet.deserialize, + ) + return self._stubs["update_phrase_set"] + + @property + def delete_phrase_set( + self, + ) -> Callable[ + [cloud_speech_adaptation.DeletePhraseSetRequest], Awaitable[empty.Empty] + ]: + r"""Return a callable for the delete phrase set method over gRPC. + + Delete a phrase set. + + Returns: + Callable[[~.DeletePhraseSetRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_phrase_set" not in self._stubs: + self._stubs["delete_phrase_set"] = self.grpc_channel.unary_unary( + "/google.cloud.speech.v1p1beta1.Adaptation/DeletePhraseSet", + request_serializer=cloud_speech_adaptation.DeletePhraseSetRequest.serialize, + response_deserializer=empty.Empty.FromString, + ) + return self._stubs["delete_phrase_set"] + + @property + def create_custom_class( + self, + ) -> Callable[ + [cloud_speech_adaptation.CreateCustomClassRequest], + Awaitable[resource.CustomClass], + ]: + r"""Return a callable for the create custom class method over gRPC. + + Create a custom class. + + Returns: + Callable[[~.CreateCustomClassRequest], + Awaitable[~.CustomClass]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_custom_class" not in self._stubs: + self._stubs["create_custom_class"] = self.grpc_channel.unary_unary( + "/google.cloud.speech.v1p1beta1.Adaptation/CreateCustomClass", + request_serializer=cloud_speech_adaptation.CreateCustomClassRequest.serialize, + response_deserializer=resource.CustomClass.deserialize, + ) + return self._stubs["create_custom_class"] + + @property + def get_custom_class( + self, + ) -> Callable[ + [cloud_speech_adaptation.GetCustomClassRequest], Awaitable[resource.CustomClass] + ]: + r"""Return a callable for the get custom class method over gRPC. + + Get a custom class. + + Returns: + Callable[[~.GetCustomClassRequest], + Awaitable[~.CustomClass]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_custom_class" not in self._stubs: + self._stubs["get_custom_class"] = self.grpc_channel.unary_unary( + "/google.cloud.speech.v1p1beta1.Adaptation/GetCustomClass", + request_serializer=cloud_speech_adaptation.GetCustomClassRequest.serialize, + response_deserializer=resource.CustomClass.deserialize, + ) + return self._stubs["get_custom_class"] + + @property + def list_custom_classes( + self, + ) -> Callable[ + [cloud_speech_adaptation.ListCustomClassesRequest], + Awaitable[cloud_speech_adaptation.ListCustomClassesResponse], + ]: + r"""Return a callable for the list custom classes method over gRPC. + + List custom classes. + + Returns: + Callable[[~.ListCustomClassesRequest], + Awaitable[~.ListCustomClassesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_custom_classes" not in self._stubs: + self._stubs["list_custom_classes"] = self.grpc_channel.unary_unary( + "/google.cloud.speech.v1p1beta1.Adaptation/ListCustomClasses", + request_serializer=cloud_speech_adaptation.ListCustomClassesRequest.serialize, + response_deserializer=cloud_speech_adaptation.ListCustomClassesResponse.deserialize, + ) + return self._stubs["list_custom_classes"] + + @property + def update_custom_class( + self, + ) -> Callable[ + [cloud_speech_adaptation.UpdateCustomClassRequest], + Awaitable[resource.CustomClass], + ]: + r"""Return a callable for the update custom class method over gRPC. + + Update a custom class. + + Returns: + Callable[[~.UpdateCustomClassRequest], + Awaitable[~.CustomClass]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_custom_class" not in self._stubs: + self._stubs["update_custom_class"] = self.grpc_channel.unary_unary( + "/google.cloud.speech.v1p1beta1.Adaptation/UpdateCustomClass", + request_serializer=cloud_speech_adaptation.UpdateCustomClassRequest.serialize, + response_deserializer=resource.CustomClass.deserialize, + ) + return self._stubs["update_custom_class"] + + @property + def delete_custom_class( + self, + ) -> Callable[ + [cloud_speech_adaptation.DeleteCustomClassRequest], Awaitable[empty.Empty] + ]: + r"""Return a callable for the delete custom class method over gRPC. + + Delete a custom class. + + Returns: + Callable[[~.DeleteCustomClassRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_custom_class" not in self._stubs: + self._stubs["delete_custom_class"] = self.grpc_channel.unary_unary( + "/google.cloud.speech.v1p1beta1.Adaptation/DeleteCustomClass", + request_serializer=cloud_speech_adaptation.DeleteCustomClassRequest.serialize, + response_deserializer=empty.Empty.FromString, + ) + return self._stubs["delete_custom_class"] + + +__all__ = ("AdaptationGrpcAsyncIOTransport",) diff --git a/google/cloud/speech_v1p1beta1/services/speech/async_client.py b/google/cloud/speech_v1p1beta1/services/speech/async_client.py index 71dc4ec7..012eb0f5 100644 --- a/google/cloud/speech_v1p1beta1/services/speech/async_client.py +++ b/google/cloud/speech_v1p1beta1/services/speech/async_client.py @@ -79,7 +79,36 @@ class SpeechAsyncClient: common_location_path = staticmethod(SpeechClient.common_location_path) parse_common_location_path = staticmethod(SpeechClient.parse_common_location_path) - from_service_account_file = SpeechClient.from_service_account_file + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SpeechAsyncClient: The constructed client. + """ + return SpeechClient.from_service_account_info.__func__(SpeechAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SpeechAsyncClient: The constructed client. + """ + return SpeechClient.from_service_account_file.__func__(SpeechAsyncClient, filename, *args, **kwargs) # type: ignore + from_service_account_json = from_service_account_file @property @@ -157,19 +186,21 @@ async def recognize( results after all audio has been sent and processed. Args: - request (:class:`~.cloud_speech.RecognizeRequest`): + request (:class:`google.cloud.speech_v1p1beta1.types.RecognizeRequest`): The request object. The top-level message sent by the client for the `Recognize` method. - config (:class:`~.cloud_speech.RecognitionConfig`): + config (:class:`google.cloud.speech_v1p1beta1.types.RecognitionConfig`): Required. Provides information to the recognizer that specifies how to process the request. + This corresponds to the ``config`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - audio (:class:`~.cloud_speech.RecognitionAudio`): + audio (:class:`google.cloud.speech_v1p1beta1.types.RecognitionAudio`): Required. The audio data to be recognized. + This corresponds to the ``audio`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -181,10 +212,10 @@ async def recognize( sent along with the request as metadata. Returns: - ~.cloud_speech.RecognizeResponse: - The only message returned to the client by the - ``Recognize`` method. It contains the result as zero or - more sequential ``SpeechRecognitionResult`` messages. + google.cloud.speech_v1p1beta1.types.RecognizeResponse: + The only message returned to the client by the Recognize method. It + contains the result as zero or more sequential + SpeechRecognitionResult messages. """ # Create or coerce a protobuf request object. @@ -247,19 +278,21 @@ async def long_running_recognize( `how-to `__. Args: - request (:class:`~.cloud_speech.LongRunningRecognizeRequest`): + request (:class:`google.cloud.speech_v1p1beta1.types.LongRunningRecognizeRequest`): The request object. The top-level message sent by the client for the `LongRunningRecognize` method. - config (:class:`~.cloud_speech.RecognitionConfig`): + config (:class:`google.cloud.speech_v1p1beta1.types.RecognitionConfig`): Required. Provides information to the recognizer that specifies how to process the request. + This corresponds to the ``config`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - audio (:class:`~.cloud_speech.RecognitionAudio`): + audio (:class:`google.cloud.speech_v1p1beta1.types.RecognitionAudio`): Required. The audio data to be recognized. + This corresponds to the ``audio`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -271,18 +304,15 @@ async def long_running_recognize( sent along with the request as metadata. Returns: - ~.operation_async.AsyncOperation: + google.api_core.operation_async.AsyncOperation: An object representing a long-running operation. - The result type for the operation will be - :class:``~.cloud_speech.LongRunningRecognizeResponse``: - The only message returned to the client by the - ``LongRunningRecognize`` method. It contains the result - as zero or more sequential ``SpeechRecognitionResult`` - messages. It is included in the ``result.response`` - field of the ``Operation`` returned by the - ``GetOperation`` call of the - ``google::longrunning::Operations`` service. + The result type for the operation will be :class:`google.cloud.speech_v1p1beta1.types.LongRunningRecognizeResponse` The only message returned to the client by the LongRunningRecognize method. + It contains the result as zero or more sequential + SpeechRecognitionResult messages. It is included in + the result.response field of the Operation returned + by the GetOperation call of the + google::longrunning::Operations service. """ # Create or coerce a protobuf request object. @@ -340,7 +370,7 @@ def streaming_recognize( available via the gRPC API (not REST). Args: - requests (AsyncIterator[`~.cloud_speech.StreamingRecognizeRequest`]): + requests (AsyncIterator[`google.cloud.speech_v1p1beta1.types.StreamingRecognizeRequest`]): The request object AsyncIterator. The top-level message sent by the client for the `StreamingRecognize` method. Multiple `StreamingRecognizeRequest` messages are sent. The first @@ -355,66 +385,67 @@ def streaming_recognize( sent along with the request as metadata. Returns: - AsyncIterable[~.cloud_speech.StreamingRecognizeResponse]: - ``StreamingRecognizeResponse`` is the only message - returned to the client by ``StreamingRecognize``. A - series of zero or more ``StreamingRecognizeResponse`` - messages are streamed back to the client. If there is no - recognizable audio, and ``single_utterance`` is set to - false, then no messages are streamed back to the client. - - Here's an example of a series of ten - ``StreamingRecognizeResponse``\ s that might be returned - while processing audio: - - 1. results { alternatives { transcript: "tube" } - stability: 0.01 } - - 2. results { alternatives { transcript: "to be a" } - stability: 0.01 } - - 3. results { alternatives { transcript: "to be" } - stability: 0.9 } results { alternatives { transcript: - " or not to be" } stability: 0.01 } - - 4. results { alternatives { transcript: "to be or not to - be" confidence: 0.92 } alternatives { transcript: "to - bee or not to bee" } is_final: true } - - 5. results { alternatives { transcript: " that's" } - stability: 0.01 } - - 6. results { alternatives { transcript: " that is" } - stability: 0.9 } results { alternatives { transcript: - " the question" } stability: 0.01 } - - 7. results { alternatives { transcript: " that is the - question" confidence: 0.98 } alternatives { - transcript: " that was the question" } is_final: true - } - - Notes: - - - Only two of the above responses #4 and #7 contain - final results; they are indicated by - ``is_final: true``. Concatenating these together - generates the full transcript: "to be or not to be - that is the question". - - - The others contain interim ``results``. #3 and #6 - contain two interim ``results``: the first portion - has a high stability and is less likely to change; - the second portion has a low stability and is very - likely to change. A UI designer might choose to show - only high stability ``results``. - - - The specific ``stability`` and ``confidence`` values - shown above are only for illustrative purposes. - Actual values may vary. - - - In each response, only one of these fields will be - set: ``error``, ``speech_event_type``, or one or more - (repeated) ``results``. + AsyncIterable[google.cloud.speech_v1p1beta1.types.StreamingRecognizeResponse]: + StreamingRecognizeResponse is the only message returned to the client by + StreamingRecognize. A series of zero or more + StreamingRecognizeResponse messages are streamed back + to the client. If there is no recognizable audio, and + single_utterance is set to false, then no messages + are streamed back to the client. + + Here's an example of a series of ten + StreamingRecognizeResponses that might be returned + while processing audio: + + 1. results { alternatives { transcript: "tube" } + stability: 0.01 } + 2. results { alternatives { transcript: "to be a" } + stability: 0.01 } + 3. results { alternatives { transcript: "to be" } + stability: 0.9 } results { alternatives { + transcript: " or not to be" } stability: 0.01 } + 4. + + results { alternatives { transcript: "to be or not to be" + confidence: 0.92 } + + alternatives { transcript: "to bee or not to bee" } + is_final: true } + + 5. results { alternatives { transcript: " that's" } + stability: 0.01 } + 6. results { alternatives { transcript: " that is" } + stability: 0.9 } results { alternatives { + transcript: " the question" } stability: 0.01 } + 7. + + results { alternatives { transcript: " that is the question" + confidence: 0.98 } + + alternatives { transcript: " that was the question" } + is_final: true } + + Notes: + + - Only two of the above responses #4 and #7 contain + final results; they are indicated by + is_final: true. Concatenating these together + generates the full transcript: "to be or not to be + that is the question". + - The others contain interim results. #3 and #6 + contain two interim \`results`: the first portion + has a high stability and is less likely to change; + the second portion has a low stability and is very + likely to change. A UI designer might choose to + show only high stability results. + - The specific stability and confidence values shown + above are only for illustrative purposes. Actual + values may vary. + - + + In each response, only one of these fields will be set: + error, speech_event_type, or one or more + (repeated) results. """ diff --git a/google/cloud/speech_v1p1beta1/services/speech/client.py b/google/cloud/speech_v1p1beta1/services/speech/client.py index 14ea0e8e..e4280c93 100644 --- a/google/cloud/speech_v1p1beta1/services/speech/client.py +++ b/google/cloud/speech_v1p1beta1/services/speech/client.py @@ -120,6 +120,22 @@ def _get_default_mtls_endpoint(api_endpoint): DEFAULT_ENDPOINT ) + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SpeechClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials @@ -132,7 +148,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): kwargs: Additional arguments to pass to the constructor. Returns: - {@api.name}: The constructed client. + SpeechClient: The constructed client. """ credentials = service_account.Credentials.from_service_account_file(filename) kwargs["credentials"] = credentials @@ -256,10 +272,10 @@ def __init__( credentials identify the application to the service; if none are specified, the client will attempt to ascertain the credentials from the environment. - transport (Union[str, ~.SpeechTransport]): The + transport (Union[str, SpeechTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (client_options_lib.ClientOptions): Custom options for the + client_options (google.api_core.client_options.ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT @@ -295,21 +311,17 @@ def __init__( util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) ) - ssl_credentials = None + client_cert_source_func = None is_mtls = False if use_client_cert: if client_options.client_cert_source: - import grpc # type: ignore - - cert, key = client_options.client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) is_mtls = True + client_cert_source_func = client_options.client_cert_source else: - creds = SslCredentials() - is_mtls = creds.is_mtls - ssl_credentials = creds.ssl_credentials if is_mtls else None + is_mtls = mtls.has_default_client_cert_source() + client_cert_source_func = ( + mtls.default_client_cert_source() if is_mtls else None + ) # Figure out which api endpoint to use. if client_options.api_endpoint is not None: @@ -352,7 +364,7 @@ def __init__( credentials_file=client_options.credentials_file, host=api_endpoint, scopes=client_options.scopes, - ssl_channel_credentials=ssl_credentials, + client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, ) @@ -371,19 +383,21 @@ def recognize( results after all audio has been sent and processed. Args: - request (:class:`~.cloud_speech.RecognizeRequest`): + request (google.cloud.speech_v1p1beta1.types.RecognizeRequest): The request object. The top-level message sent by the client for the `Recognize` method. - config (:class:`~.cloud_speech.RecognitionConfig`): + config (google.cloud.speech_v1p1beta1.types.RecognitionConfig): Required. Provides information to the recognizer that specifies how to process the request. + This corresponds to the ``config`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - audio (:class:`~.cloud_speech.RecognitionAudio`): + audio (google.cloud.speech_v1p1beta1.types.RecognitionAudio): Required. The audio data to be recognized. + This corresponds to the ``audio`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -395,10 +409,10 @@ def recognize( sent along with the request as metadata. Returns: - ~.cloud_speech.RecognizeResponse: - The only message returned to the client by the - ``Recognize`` method. It contains the result as zero or - more sequential ``SpeechRecognitionResult`` messages. + google.cloud.speech_v1p1beta1.types.RecognizeResponse: + The only message returned to the client by the Recognize method. It + contains the result as zero or more sequential + SpeechRecognitionResult messages. """ # Create or coerce a protobuf request object. @@ -454,19 +468,21 @@ def long_running_recognize( `how-to `__. Args: - request (:class:`~.cloud_speech.LongRunningRecognizeRequest`): + request (google.cloud.speech_v1p1beta1.types.LongRunningRecognizeRequest): The request object. The top-level message sent by the client for the `LongRunningRecognize` method. - config (:class:`~.cloud_speech.RecognitionConfig`): + config (google.cloud.speech_v1p1beta1.types.RecognitionConfig): Required. Provides information to the recognizer that specifies how to process the request. + This corresponds to the ``config`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - audio (:class:`~.cloud_speech.RecognitionAudio`): + audio (google.cloud.speech_v1p1beta1.types.RecognitionAudio): Required. The audio data to be recognized. + This corresponds to the ``audio`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -478,18 +494,15 @@ def long_running_recognize( sent along with the request as metadata. Returns: - ~.operation.Operation: + google.api_core.operation.Operation: An object representing a long-running operation. - The result type for the operation will be - :class:``~.cloud_speech.LongRunningRecognizeResponse``: - The only message returned to the client by the - ``LongRunningRecognize`` method. It contains the result - as zero or more sequential ``SpeechRecognitionResult`` - messages. It is included in the ``result.response`` - field of the ``Operation`` returned by the - ``GetOperation`` call of the - ``google::longrunning::Operations`` service. + The result type for the operation will be :class:`google.cloud.speech_v1p1beta1.types.LongRunningRecognizeResponse` The only message returned to the client by the LongRunningRecognize method. + It contains the result as zero or more sequential + SpeechRecognitionResult messages. It is included in + the result.response field of the Operation returned + by the GetOperation call of the + google::longrunning::Operations service. """ # Create or coerce a protobuf request object. @@ -548,7 +561,7 @@ def streaming_recognize( available via the gRPC API (not REST). Args: - requests (Iterator[`~.cloud_speech.StreamingRecognizeRequest`]): + requests (Iterator[google.cloud.speech_v1p1beta1.types.StreamingRecognizeRequest]): The request object iterator. The top-level message sent by the client for the `StreamingRecognize` method. Multiple `StreamingRecognizeRequest` messages are sent. The first @@ -563,66 +576,67 @@ def streaming_recognize( sent along with the request as metadata. Returns: - Iterable[~.cloud_speech.StreamingRecognizeResponse]: - ``StreamingRecognizeResponse`` is the only message - returned to the client by ``StreamingRecognize``. A - series of zero or more ``StreamingRecognizeResponse`` - messages are streamed back to the client. If there is no - recognizable audio, and ``single_utterance`` is set to - false, then no messages are streamed back to the client. - - Here's an example of a series of ten - ``StreamingRecognizeResponse``\ s that might be returned - while processing audio: - - 1. results { alternatives { transcript: "tube" } - stability: 0.01 } - - 2. results { alternatives { transcript: "to be a" } - stability: 0.01 } - - 3. results { alternatives { transcript: "to be" } - stability: 0.9 } results { alternatives { transcript: - " or not to be" } stability: 0.01 } - - 4. results { alternatives { transcript: "to be or not to - be" confidence: 0.92 } alternatives { transcript: "to - bee or not to bee" } is_final: true } - - 5. results { alternatives { transcript: " that's" } - stability: 0.01 } - - 6. results { alternatives { transcript: " that is" } - stability: 0.9 } results { alternatives { transcript: - " the question" } stability: 0.01 } - - 7. results { alternatives { transcript: " that is the - question" confidence: 0.98 } alternatives { - transcript: " that was the question" } is_final: true - } - - Notes: - - - Only two of the above responses #4 and #7 contain - final results; they are indicated by - ``is_final: true``. Concatenating these together - generates the full transcript: "to be or not to be - that is the question". - - - The others contain interim ``results``. #3 and #6 - contain two interim ``results``: the first portion - has a high stability and is less likely to change; - the second portion has a low stability and is very - likely to change. A UI designer might choose to show - only high stability ``results``. - - - The specific ``stability`` and ``confidence`` values - shown above are only for illustrative purposes. - Actual values may vary. - - - In each response, only one of these fields will be - set: ``error``, ``speech_event_type``, or one or more - (repeated) ``results``. + Iterable[google.cloud.speech_v1p1beta1.types.StreamingRecognizeResponse]: + StreamingRecognizeResponse is the only message returned to the client by + StreamingRecognize. A series of zero or more + StreamingRecognizeResponse messages are streamed back + to the client. If there is no recognizable audio, and + single_utterance is set to false, then no messages + are streamed back to the client. + + Here's an example of a series of ten + StreamingRecognizeResponses that might be returned + while processing audio: + + 1. results { alternatives { transcript: "tube" } + stability: 0.01 } + 2. results { alternatives { transcript: "to be a" } + stability: 0.01 } + 3. results { alternatives { transcript: "to be" } + stability: 0.9 } results { alternatives { + transcript: " or not to be" } stability: 0.01 } + 4. + + results { alternatives { transcript: "to be or not to be" + confidence: 0.92 } + + alternatives { transcript: "to bee or not to bee" } + is_final: true } + + 5. results { alternatives { transcript: " that's" } + stability: 0.01 } + 6. results { alternatives { transcript: " that is" } + stability: 0.9 } results { alternatives { + transcript: " the question" } stability: 0.01 } + 7. + + results { alternatives { transcript: " that is the question" + confidence: 0.98 } + + alternatives { transcript: " that was the question" } + is_final: true } + + Notes: + + - Only two of the above responses #4 and #7 contain + final results; they are indicated by + is_final: true. Concatenating these together + generates the full transcript: "to be or not to be + that is the question". + - The others contain interim results. #3 and #6 + contain two interim \`results`: the first portion + has a high stability and is less likely to change; + the second portion has a low stability and is very + likely to change. A UI designer might choose to + show only high stability results. + - The specific stability and confidence values shown + above are only for illustrative purposes. Actual + values may vary. + - + + In each response, only one of these fields will be set: + error, speech_event_type, or one or more + (repeated) results. """ diff --git a/google/cloud/speech_v1p1beta1/services/speech/transports/grpc.py b/google/cloud/speech_v1p1beta1/services/speech/transports/grpc.py index 2b86c6c7..4154e3aa 100644 --- a/google/cloud/speech_v1p1beta1/services/speech/transports/grpc.py +++ b/google/cloud/speech_v1p1beta1/services/speech/transports/grpc.py @@ -59,6 +59,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -89,6 +90,10 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -105,6 +110,11 @@ def __init__( """ self._ssl_channel_credentials = ssl_channel_credentials + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + if channel: # Sanity check: Ensure that channel and credentials are not both # provided. @@ -114,11 +124,6 @@ def __init__( self._grpc_channel = channel self._ssl_channel_credentials = None elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -162,12 +167,18 @@ def __init__( scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id ) + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + # create a new channel. The provided one is ignored. self._grpc_channel = type(self).create_channel( host, credentials=credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, + ssl_credentials=self._ssl_channel_credentials, scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, options=[ diff --git a/google/cloud/speech_v1p1beta1/services/speech/transports/grpc_asyncio.py b/google/cloud/speech_v1p1beta1/services/speech/transports/grpc_asyncio.py index 1efae229..de5f15a3 100644 --- a/google/cloud/speech_v1p1beta1/services/speech/transports/grpc_asyncio.py +++ b/google/cloud/speech_v1p1beta1/services/speech/transports/grpc_asyncio.py @@ -103,6 +103,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -134,6 +135,10 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -150,6 +155,11 @@ def __init__( """ self._ssl_channel_credentials = ssl_channel_credentials + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + if channel: # Sanity check: Ensure that channel and credentials are not both # provided. @@ -159,11 +169,6 @@ def __init__( self._grpc_channel = channel self._ssl_channel_credentials = None elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -207,12 +212,18 @@ def __init__( scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id ) + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + # create a new channel. The provided one is ignored. self._grpc_channel = type(self).create_channel( host, credentials=credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, + ssl_credentials=self._ssl_channel_credentials, scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, options=[ diff --git a/google/cloud/speech_v1p1beta1/types/__init__.py b/google/cloud/speech_v1p1beta1/types/__init__.py index 9713892d..11617052 100644 --- a/google/cloud/speech_v1p1beta1/types/__init__.py +++ b/google/cloud/speech_v1p1beta1/types/__init__.py @@ -39,6 +39,20 @@ SpeechRecognitionAlternative, WordInfo, ) +from .cloud_speech_adaptation import ( + CreatePhraseSetRequest, + UpdatePhraseSetRequest, + GetPhraseSetRequest, + ListPhraseSetRequest, + ListPhraseSetResponse, + DeletePhraseSetRequest, + CreateCustomClassRequest, + UpdateCustomClassRequest, + GetCustomClassRequest, + ListCustomClassesRequest, + ListCustomClassesResponse, + DeleteCustomClassRequest, +) __all__ = ( "CustomClass", @@ -61,4 +75,16 @@ "SpeechRecognitionResult", "SpeechRecognitionAlternative", "WordInfo", + "CreatePhraseSetRequest", + "UpdatePhraseSetRequest", + "GetPhraseSetRequest", + "ListPhraseSetRequest", + "ListPhraseSetResponse", + "DeletePhraseSetRequest", + "CreateCustomClassRequest", + "UpdateCustomClassRequest", + "GetCustomClassRequest", + "ListCustomClassesRequest", + "ListCustomClassesResponse", + "DeleteCustomClassRequest", ) diff --git a/google/cloud/speech_v1p1beta1/types/cloud_speech.py b/google/cloud/speech_v1p1beta1/types/cloud_speech.py index e2ea5ff5..59d5d718 100644 --- a/google/cloud/speech_v1p1beta1/types/cloud_speech.py +++ b/google/cloud/speech_v1p1beta1/types/cloud_speech.py @@ -53,11 +53,11 @@ class RecognizeRequest(proto.Message): method. Attributes: - config (~.cloud_speech.RecognitionConfig): + config (google.cloud.speech_v1p1beta1.types.RecognitionConfig): Required. Provides information to the recognizer that specifies how to process the request. - audio (~.cloud_speech.RecognitionAudio): + audio (google.cloud.speech_v1p1beta1.types.RecognitionAudio): Required. The audio data to be recognized. """ @@ -71,11 +71,11 @@ class LongRunningRecognizeRequest(proto.Message): ``LongRunningRecognize`` method. Attributes: - config (~.cloud_speech.RecognitionConfig): + config (google.cloud.speech_v1p1beta1.types.RecognitionConfig): Required. Provides information to the recognizer that specifies how to process the request. - audio (~.cloud_speech.RecognitionAudio): + audio (google.cloud.speech_v1p1beta1.types.RecognitionAudio): Required. The audio data to be recognized. """ @@ -94,7 +94,7 @@ class StreamingRecognizeRequest(proto.Message): message. Attributes: - streaming_config (~.cloud_speech.StreamingRecognitionConfig): + streaming_config (google.cloud.speech_v1p1beta1.types.StreamingRecognitionConfig): Provides information to the recognizer that specifies how to process the request. The first ``StreamingRecognizeRequest`` message must contain a ``streaming_config`` message. @@ -126,7 +126,7 @@ class StreamingRecognitionConfig(proto.Message): process the request. Attributes: - config (~.cloud_speech.RecognitionConfig): + config (google.cloud.speech_v1p1beta1.types.RecognitionConfig): Required. Provides information to the recognizer that specifies how to process the request. @@ -145,6 +145,17 @@ class StreamingRecognitionConfig(proto.Message): ``END_OF_SINGLE_UTTERANCE`` event and cease recognition. It will return no more than one ``StreamingRecognitionResult`` with the ``is_final`` flag set to ``true``. + + The ``single_utterance`` field can only be used with + specified models, otherwise an error is thrown. The + ``model`` field in [``RecognitionConfig``][] must be set to: + + - ``command_and_search`` + - ``phone_call`` AND additional field + ``useEnhanced``\ =\ ``true`` + - The ``model`` field is left undefined. In this case the + API auto-selects a model based on any other parameters + that you set in ``RecognitionConfig``. interim_results (bool): If ``true``, interim results (tentative hypotheses) may be returned as they become available (these interim results are @@ -164,7 +175,7 @@ class RecognitionConfig(proto.Message): process the request. Attributes: - encoding (~.cloud_speech.RecognitionConfig.AudioEncoding): + encoding (google.cloud.speech_v1p1beta1.types.RecognitionConfig.AudioEncoding): Encoding of audio data sent in all ``RecognitionAudio`` messages. This field is optional for ``FLAC`` and ``WAV`` audio files and required for all other audio formats. For @@ -232,14 +243,14 @@ class RecognitionConfig(proto.Message): profanities, replacing all but the initial character in each filtered word with asterisks, e.g. "f***". If set to ``false`` or omitted, profanities won't be filtered out. - adaptation (~.resource.SpeechAdaptation): + adaptation (google.cloud.speech_v1p1beta1.types.SpeechAdaptation): Speech adaptation configuration improves the accuracy of speech recognition. When speech adaptation is set it supersedes the ``speech_contexts`` field. For more information, see the `speech adaptation `__ documentation. - speech_contexts (Sequence[~.cloud_speech.SpeechContext]): + speech_contexts (Sequence[google.cloud.speech_v1p1beta1.types.SpeechContext]): Array of [SpeechContext][google.cloud.speech.v1p1beta1.SpeechContext]. A means to provide context to assist the speech recognition. @@ -272,7 +283,7 @@ class RecognitionConfig(proto.Message): conversation. Defaults to '2'. Ignored unless enable_speaker_diarization is set to true. Note: Use diarization_config instead. - diarization_config (~.cloud_speech.SpeakerDiarizationConfig): + diarization_config (google.cloud.speech_v1p1beta1.types.SpeakerDiarizationConfig): Config to enable speaker diarization and set additional parameters to make diarization better suited for your application. Note: When this is @@ -285,7 +296,7 @@ class RecognitionConfig(proto.Message): requests, the diarization results will be provided only in the top alternative of the FINAL SpeechRecognitionResult. - metadata (~.cloud_speech.RecognitionMetadata): + metadata (google.cloud.speech_v1p1beta1.types.RecognitionMetadata): Metadata regarding this request. model (str): Which model to select for the given request. Select the @@ -454,7 +465,7 @@ class RecognitionMetadata(proto.Message): r"""Description of audio data to be recognized. Attributes: - interaction_type (~.cloud_speech.RecognitionMetadata.InteractionType): + interaction_type (google.cloud.speech_v1p1beta1.types.RecognitionMetadata.InteractionType): The use case most closely describing the audio content to be recognized. industry_naics_code_of_audio (int): @@ -464,13 +475,13 @@ class RecognitionMetadata(proto.Message): the audio. Use the 6-digit NAICS code to identify the industry vertical - see https://www.naics.com/search/. - microphone_distance (~.cloud_speech.RecognitionMetadata.MicrophoneDistance): + microphone_distance (google.cloud.speech_v1p1beta1.types.RecognitionMetadata.MicrophoneDistance): The audio type that most closely describes the audio being recognized. - original_media_type (~.cloud_speech.RecognitionMetadata.OriginalMediaType): + original_media_type (google.cloud.speech_v1p1beta1.types.RecognitionMetadata.OriginalMediaType): The original media the speech was recorded on. - recording_device_type (~.cloud_speech.RecognitionMetadata.RecordingDeviceType): + recording_device_type (google.cloud.speech_v1p1beta1.types.RecognitionMetadata.RecordingDeviceType): The type of device the speech was recorded with. recording_device_name (str): @@ -627,7 +638,7 @@ class RecognizeResponse(proto.Message): ``SpeechRecognitionResult`` messages. Attributes: - results (Sequence[~.cloud_speech.SpeechRecognitionResult]): + results (Sequence[google.cloud.speech_v1p1beta1.types.SpeechRecognitionResult]): Sequential list of transcription results corresponding to sequential portions of audio. """ @@ -646,7 +657,7 @@ class LongRunningRecognizeResponse(proto.Message): service. Attributes: - results (Sequence[~.cloud_speech.SpeechRecognitionResult]): + results (Sequence[google.cloud.speech_v1p1beta1.types.SpeechRecognitionResult]): Sequential list of transcription results corresponding to sequential portions of audio. """ @@ -667,13 +678,14 @@ class LongRunningRecognizeMetadata(proto.Message): Approximate percentage of audio processed thus far. Guaranteed to be 100 when the audio is fully processed and the results are available. - start_time (~.timestamp.Timestamp): + start_time (google.protobuf.timestamp_pb2.Timestamp): Time when the request was received. - last_update_time (~.timestamp.Timestamp): + last_update_time (google.protobuf.timestamp_pb2.Timestamp): Time of the most recent processing update. uri (str): - The URI of the audio file being transcribed. - Empty if the audio was sent as byte content. + Output only. The URI of the audio file being + transcribed. Empty if the audio was sent as byte + content. """ progress_percent = proto.Field(proto.INT32, number=1) @@ -743,16 +755,16 @@ class StreamingRecognizeResponse(proto.Message): ``results``. Attributes: - error (~.status.Status): + error (google.rpc.status_pb2.Status): If set, returns a [google.rpc.Status][google.rpc.Status] message that specifies the error for the operation. - results (Sequence[~.cloud_speech.StreamingRecognitionResult]): + results (Sequence[google.cloud.speech_v1p1beta1.types.StreamingRecognitionResult]): This repeated list contains zero or more results that correspond to consecutive portions of the audio currently being processed. It contains zero or one ``is_final=true`` result (the newly settled portion), followed by zero or more ``is_final=false`` results (the interim results). - speech_event_type (~.cloud_speech.StreamingRecognizeResponse.SpeechEventType): + speech_event_type (google.cloud.speech_v1p1beta1.types.StreamingRecognizeResponse.SpeechEventType): Indicates the type of speech event. """ @@ -775,7 +787,7 @@ class StreamingRecognitionResult(proto.Message): portion of the audio that is currently being processed. Attributes: - alternatives (Sequence[~.cloud_speech.SpeechRecognitionAlternative]): + alternatives (Sequence[google.cloud.speech_v1p1beta1.types.SpeechRecognitionAlternative]): May contain one or more recognition hypotheses (up to the maximum specified in ``max_alternatives``). These alternatives are ordered in terms of accuracy, with the top @@ -795,7 +807,7 @@ class StreamingRecognitionResult(proto.Message): This field is only provided for interim results (``is_final=false``). The default of 0.0 is a sentinel value indicating ``stability`` was not set. - result_end_time (~.duration.Duration): + result_end_time (google.protobuf.duration_pb2.Duration): Time offset of the end of this result relative to the beginning of the audio. channel_tag (int): @@ -831,7 +843,7 @@ class SpeechRecognitionResult(proto.Message): audio. Attributes: - alternatives (Sequence[~.cloud_speech.SpeechRecognitionAlternative]): + alternatives (Sequence[google.cloud.speech_v1p1beta1.types.SpeechRecognitionAlternative]): May contain one or more recognition hypotheses (up to the maximum specified in ``max_alternatives``). These alternatives are ordered in terms of accuracy, with the top @@ -875,7 +887,7 @@ class SpeechRecognitionAlternative(proto.Message): to be accurate and users should not rely on it to be always provided. The default of 0.0 is a sentinel value indicating ``confidence`` was not set. - words (Sequence[~.cloud_speech.WordInfo]): + words (Sequence[google.cloud.speech_v1p1beta1.types.WordInfo]): A list of word-specific information for each recognized word. Note: When ``enable_speaker_diarization`` is true, you will see all the words from the beginning of the audio. @@ -892,13 +904,13 @@ class WordInfo(proto.Message): r"""Word-specific information for recognized words. Attributes: - start_time (~.duration.Duration): + start_time (google.protobuf.duration_pb2.Duration): Time offset relative to the beginning of the audio, and corresponding to the start of the spoken word. This field is only set if ``enable_word_time_offsets=true`` and only in the top hypothesis. This is an experimental feature and the accuracy of the time offset can vary. - end_time (~.duration.Duration): + end_time (google.protobuf.duration_pb2.Duration): Time offset relative to the beginning of the audio, and corresponding to the end of the spoken word. This field is only set if ``enable_word_time_offsets=true`` and only in diff --git a/google/cloud/speech_v1p1beta1/types/cloud_speech_adaptation.py b/google/cloud/speech_v1p1beta1/types/cloud_speech_adaptation.py new file mode 100644 index 00000000..e1d92dad --- /dev/null +++ b/google/cloud/speech_v1p1beta1/types/cloud_speech_adaptation.py @@ -0,0 +1,286 @@ +# -*- coding: utf-8 -*- + +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import proto # type: ignore + + +from google.cloud.speech_v1p1beta1.types import resource +from google.protobuf import field_mask_pb2 as field_mask # type: ignore + + +__protobuf__ = proto.module( + package="google.cloud.speech.v1p1beta1", + manifest={ + "CreatePhraseSetRequest", + "UpdatePhraseSetRequest", + "GetPhraseSetRequest", + "ListPhraseSetRequest", + "ListPhraseSetResponse", + "DeletePhraseSetRequest", + "CreateCustomClassRequest", + "UpdateCustomClassRequest", + "GetCustomClassRequest", + "ListCustomClassesRequest", + "ListCustomClassesResponse", + "DeleteCustomClassRequest", + }, +) + + +class CreatePhraseSetRequest(proto.Message): + r"""Message sent by the client for the ``CreatePhraseSet`` method. + + Attributes: + parent (str): + Required. The parent resource where this phrase set will be + created. Format: + {api_version}/projects/{project}/locations/{location}/phraseSets + phrase_set_id (str): + The ID to use for the phrase set, which will become the + final component of the phrase set's resource name. + + This value should be 4-63 characters, and valid characters + are /[a-z][0-9]-/. + phrase_set (google.cloud.speech_v1p1beta1.types.PhraseSet): + Required. The phrase set to create. + """ + + parent = proto.Field(proto.STRING, number=1) + + phrase_set_id = proto.Field(proto.STRING, number=2) + + phrase_set = proto.Field(proto.MESSAGE, number=3, message=resource.PhraseSet,) + + +class UpdatePhraseSetRequest(proto.Message): + r"""Message sent by the client for the ``UpdatePhraseSet`` method. + + Attributes: + phrase_set (google.cloud.speech_v1p1beta1.types.PhraseSet): + Required. The phrase set to update. + + The phrase set's ``name`` field is used to identify the set + to be updated. Format: + {api_version}/projects/{project}/locations/{location}/phraseSets/{phrase_set} + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The list of fields to be updated. + """ + + phrase_set = proto.Field(proto.MESSAGE, number=1, message=resource.PhraseSet,) + + update_mask = proto.Field(proto.MESSAGE, number=2, message=field_mask.FieldMask,) + + +class GetPhraseSetRequest(proto.Message): + r"""Message sent by the client for the ``GetPhraseSet`` method. + + Attributes: + name (str): + Required. The name of the phrase set to retrieve. Format: + {api_version}/projects/{project}/locations/{location}/phraseSets/{phrase_set} + """ + + name = proto.Field(proto.STRING, number=1) + + +class ListPhraseSetRequest(proto.Message): + r"""Message sent by the client for the ``ListPhraseSet`` method. + + Attributes: + parent (str): + Required. The parent, which owns this + collection of phrase set. Format: + projects/{project}/locations/{location} + page_size (int): + The maximum number of phrase sets to return. + The service may return fewer than this value. If + unspecified, at most 50 phrase sets will be + returned. The maximum value is 1000; values + above 1000 will be coerced to 1000. + page_token (str): + A page token, received from a previous ``ListPhraseSet`` + call. Provide this to retrieve the subsequent page. + + When paginating, all other parameters provided to + ``ListPhraseSet`` must match the call that provided the page + token. + """ + + parent = proto.Field(proto.STRING, number=1) + + page_size = proto.Field(proto.INT32, number=2) + + page_token = proto.Field(proto.STRING, number=3) + + +class ListPhraseSetResponse(proto.Message): + r"""Message returned to the client by the ``ListPhraseSet`` method. + + Attributes: + phrase_sets (Sequence[google.cloud.speech_v1p1beta1.types.PhraseSet]): + The phrase set. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + """ + + @property + def raw_page(self): + return self + + phrase_sets = proto.RepeatedField( + proto.MESSAGE, number=1, message=resource.PhraseSet, + ) + + next_page_token = proto.Field(proto.STRING, number=2) + + +class DeletePhraseSetRequest(proto.Message): + r"""Message sent by the client for the ``DeletePhraseSet`` method. + + Attributes: + name (str): + Required. The name of the phrase set to delete. Format: + {api_version}/projects/{project}/locations/{location}/phraseSets/{phrase_set} + """ + + name = proto.Field(proto.STRING, number=1) + + +class CreateCustomClassRequest(proto.Message): + r"""Message sent by the client for the ``CreateCustomClass`` method. + + Attributes: + parent (str): + Required. The parent resource where this custom class will + be created. Format: + {api_version}/projects/{project}/locations/{location}/customClasses + custom_class_id (str): + The ID to use for the custom class, which will become the + final component of the custom class' resource name. + + This value should be 4-63 characters, and valid characters + are /[a-z][0-9]-/. + custom_class (google.cloud.speech_v1p1beta1.types.CustomClass): + Required. The custom class to create. + """ + + parent = proto.Field(proto.STRING, number=1) + + custom_class_id = proto.Field(proto.STRING, number=2) + + custom_class = proto.Field(proto.MESSAGE, number=3, message=resource.CustomClass,) + + +class UpdateCustomClassRequest(proto.Message): + r"""Message sent by the client for the ``UpdateCustomClass`` method. + + Attributes: + custom_class (google.cloud.speech_v1p1beta1.types.CustomClass): + Required. The custom class to update. + + The custom class's ``name`` field is used to identify the + custom class to be updated. Format: + {api_version}/projects/{project}/locations/{location}/customClasses/{custom_class} + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The list of fields to be updated. + """ + + custom_class = proto.Field(proto.MESSAGE, number=1, message=resource.CustomClass,) + + update_mask = proto.Field(proto.MESSAGE, number=2, message=field_mask.FieldMask,) + + +class GetCustomClassRequest(proto.Message): + r"""Message sent by the client for the ``GetCustomClass`` method. + + Attributes: + name (str): + Required. The name of the custom class to retrieve. Format: + {api_version}/projects/{project}/locations/{location}/customClasses/{custom_class} + """ + + name = proto.Field(proto.STRING, number=1) + + +class ListCustomClassesRequest(proto.Message): + r"""Message sent by the client for the ``ListCustomClasses`` method. + + Attributes: + parent (str): + Required. The parent, which owns this collection of custom + classes. Format: + {api_version}/projects/{project}/locations/{location}/customClasses + page_size (int): + The maximum number of custom classes to + return. The service may return fewer than this + value. If unspecified, at most 50 custom classes + will be returned. The maximum value is 1000; + values above 1000 will be coerced to 1000. + page_token (str): + A page token, received from a previous ``ListCustomClass`` + call. Provide this to retrieve the subsequent page. + + When paginating, all other parameters provided to + ``ListCustomClass`` must match the call that provided the + page token. + """ + + parent = proto.Field(proto.STRING, number=1) + + page_size = proto.Field(proto.INT32, number=2) + + page_token = proto.Field(proto.STRING, number=3) + + +class ListCustomClassesResponse(proto.Message): + r"""Message returned to the client by the ``ListCustomClasses`` method. + + Attributes: + custom_classes (Sequence[google.cloud.speech_v1p1beta1.types.CustomClass]): + The custom classes. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + """ + + @property + def raw_page(self): + return self + + custom_classes = proto.RepeatedField( + proto.MESSAGE, number=1, message=resource.CustomClass, + ) + + next_page_token = proto.Field(proto.STRING, number=2) + + +class DeleteCustomClassRequest(proto.Message): + r"""Message sent by the client for the ``DeleteCustomClass`` method. + + Attributes: + name (str): + Required. The name of the custom class to delete. Format: + {api_version}/projects/{project}/locations/{location}/customClasses/{custom_class} + """ + + name = proto.Field(proto.STRING, number=1) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/speech_v1p1beta1/types/resource.py b/google/cloud/speech_v1p1beta1/types/resource.py index eb04c8ea..a9d06af7 100644 --- a/google/cloud/speech_v1p1beta1/types/resource.py +++ b/google/cloud/speech_v1p1beta1/types/resource.py @@ -35,8 +35,8 @@ class CustomClass(proto.Message): The resource name of the custom class. custom_class_id (str): If this custom class is a resource, the custom_class_id is - the resource id of the CustomClass. - items (Sequence[~.resource.CustomClass.ClassItem]): + the resource id of the CustomClass. Case sensitive. + items (Sequence[google.cloud.speech_v1p1beta1.types.CustomClass.ClassItem]): A collection of class items. """ @@ -64,7 +64,7 @@ class PhraseSet(proto.Message): Attributes: name (str): The resource name of the phrase set. - phrases (Sequence[~.resource.PhraseSet.Phrase]): + phrases (Sequence[google.cloud.speech_v1p1beta1.types.PhraseSet.Phrase]): A list of word and phrases. boost (float): Hint Boost. Positive value will increase the probability @@ -137,11 +137,14 @@ class SpeechAdaptation(proto.Message): r"""Speech adaptation configuration. Attributes: - phrase_sets (Sequence[~.resource.PhraseSet]): + phrase_sets (Sequence[google.cloud.speech_v1p1beta1.types.PhraseSet]): A collection of phrase sets. To specify the hints inline, leave the phrase set's ``name`` blank and fill in the rest of its fields. Any phrase set can use any custom class. - custom_classes (Sequence[~.resource.CustomClass]): + phrase_set_references (Sequence[str]): + A collection of phrase set resource names to + use. + custom_classes (Sequence[google.cloud.speech_v1p1beta1.types.CustomClass]): A collection of custom classes. To specify the classes inline, leave the class' ``name`` blank and fill in the rest of its fields, giving it a unique ``custom_class_id``. Refer @@ -151,8 +154,10 @@ class SpeechAdaptation(proto.Message): phrase_sets = proto.RepeatedField(proto.MESSAGE, number=1, message="PhraseSet",) + phrase_set_references = proto.RepeatedField(proto.STRING, number=2) + custom_classes = proto.RepeatedField( - proto.MESSAGE, number=2, message="CustomClass", + proto.MESSAGE, number=3, message="CustomClass", ) diff --git a/noxfile.py b/noxfile.py index a57e24be..6e69bfe0 100644 --- a/noxfile.py +++ b/noxfile.py @@ -30,6 +30,17 @@ SYSTEM_TEST_PYTHON_VERSIONS = ["3.8"] UNIT_TEST_PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9"] +# 'docfx' is excluded since it only needs to run in 'docs-presubmit' +nox.options.sessions = [ + "unit", + "system", + "cover", + "lint", + "lint_setup_py", + "blacken", + "docs", +] + @nox.session(python=DEFAULT_PYTHON_VERSION) def lint(session): @@ -75,12 +86,14 @@ def default(session): session.install( "mock", "pytest", "pytest-cov", ) + session.install("-e", ".") # Run py.test against the unit tests. session.run( "py.test", "--quiet", + f"--junitxml=unit_{session.python}_sponge_log.xml", "--cov=google/cloud", "--cov=tests/unit", "--cov-append", @@ -129,9 +142,21 @@ def system(session): # Run py.test against the system tests. if system_test_exists: - session.run("py.test", "--quiet", system_test_path, *session.posargs) + session.run( + "py.test", + "--quiet", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_path, + *session.posargs, + ) if system_test_folder_exists: - session.run("py.test", "--quiet", system_test_folder_path, *session.posargs) + session.run( + "py.test", + "--quiet", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_folder_path, + *session.posargs, + ) @nox.session(python=DEFAULT_PYTHON_VERSION) diff --git a/samples/microphone/noxfile.py b/samples/microphone/noxfile.py index bca0522e..97bf7da8 100644 --- a/samples/microphone/noxfile.py +++ b/samples/microphone/noxfile.py @@ -85,7 +85,7 @@ def get_pytest_env_vars() -> Dict[str, str]: # DO NOT EDIT - automatically generated. # All versions used to tested samples. -ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8"] +ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8", "3.9"] # Any default versions that should be ignored. IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] diff --git a/samples/snippets/noxfile.py b/samples/snippets/noxfile.py index bca0522e..97bf7da8 100644 --- a/samples/snippets/noxfile.py +++ b/samples/snippets/noxfile.py @@ -85,7 +85,7 @@ def get_pytest_env_vars() -> Dict[str, str]: # DO NOT EDIT - automatically generated. # All versions used to tested samples. -ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8"] +ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8", "3.9"] # Any default versions that should be ignored. IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] diff --git a/scripts/fixup_speech_v1p1beta1_keywords.py b/scripts/fixup_speech_v1p1beta1_keywords.py index bcc5ab74..58c63d01 100644 --- a/scripts/fixup_speech_v1p1beta1_keywords.py +++ b/scripts/fixup_speech_v1p1beta1_keywords.py @@ -41,9 +41,19 @@ def partition( class speechCallTransformer(cst.CSTTransformer): CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'create_custom_class': ('parent', 'custom_class', 'custom_class_id', ), + 'create_phrase_set': ('parent', 'phrase_set', 'phrase_set_id', ), + 'delete_custom_class': ('name', ), + 'delete_phrase_set': ('name', ), + 'get_custom_class': ('name', ), + 'get_phrase_set': ('name', ), + 'list_custom_classes': ('parent', 'page_size', 'page_token', ), + 'list_phrase_set': ('parent', 'page_size', 'page_token', ), 'long_running_recognize': ('config', 'audio', ), 'recognize': ('config', 'audio', ), 'streaming_recognize': ('streaming_config', 'audio_content', ), + 'update_custom_class': ('custom_class', 'update_mask', ), + 'update_phrase_set': ('phrase_set', 'update_mask', ), } diff --git a/synth.metadata b/synth.metadata index df4dfd81..0f42177c 100644 --- a/synth.metadata +++ b/synth.metadata @@ -3,30 +3,30 @@ { "git": { "name": ".", - "remote": "https://github.com/googleapis/python-speech.git", - "sha": "29bd581e8364558c002b2f3e74ff7605ff9d434a" + "remote": "git@github.com:googleapis/python-speech", + "sha": "d06460152ea96b33006c0441227647f03b688862" } }, { "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "dd372aa22ded7a8ba6f0e03a80e06358a3fa0907", - "internalRef": "347055288" + "sha": "9adc11e84218d5e234392e7fe81676e778895525", + "internalRef": "359844338" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "373861061648b5fe5e0ac4f8a38b32d639ee93e4" + "sha": "8c5628b86cfa8386de7b8fc1675e6b528b552d57" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "373861061648b5fe5e0ac4f8a38b32d639ee93e4" + "sha": "8c5628b86cfa8386de7b8fc1675e6b528b552d57" } } ], @@ -49,116 +49,5 @@ "generator": "bazel" } } - ], - "generatedFiles": [ - ".flake8", - ".github/CONTRIBUTING.md", - ".github/ISSUE_TEMPLATE/bug_report.md", - ".github/ISSUE_TEMPLATE/feature_request.md", - ".github/ISSUE_TEMPLATE/support_request.md", - ".github/PULL_REQUEST_TEMPLATE.md", - ".github/release-please.yml", - ".github/snippet-bot.yml", - ".gitignore", - ".kokoro/build.sh", - ".kokoro/continuous/common.cfg", - ".kokoro/continuous/continuous.cfg", - ".kokoro/docker/docs/Dockerfile", - ".kokoro/docker/docs/fetch_gpg_keys.sh", - ".kokoro/docs/common.cfg", - ".kokoro/docs/docs-presubmit.cfg", - ".kokoro/docs/docs.cfg", - ".kokoro/populate-secrets.sh", - ".kokoro/presubmit/common.cfg", - ".kokoro/presubmit/presubmit.cfg", - ".kokoro/publish-docs.sh", - ".kokoro/release.sh", - ".kokoro/release/common.cfg", - ".kokoro/release/release.cfg", - ".kokoro/samples/lint/common.cfg", - ".kokoro/samples/lint/continuous.cfg", - ".kokoro/samples/lint/periodic.cfg", - ".kokoro/samples/lint/presubmit.cfg", - ".kokoro/samples/python3.6/common.cfg", - ".kokoro/samples/python3.6/continuous.cfg", - ".kokoro/samples/python3.6/periodic.cfg", - ".kokoro/samples/python3.6/presubmit.cfg", - ".kokoro/samples/python3.7/common.cfg", - ".kokoro/samples/python3.7/continuous.cfg", - ".kokoro/samples/python3.7/periodic.cfg", - ".kokoro/samples/python3.7/presubmit.cfg", - ".kokoro/samples/python3.8/common.cfg", - ".kokoro/samples/python3.8/continuous.cfg", - ".kokoro/samples/python3.8/periodic.cfg", - ".kokoro/samples/python3.8/presubmit.cfg", - ".kokoro/test-samples.sh", - ".kokoro/trampoline.sh", - ".kokoro/trampoline_v2.sh", - ".pre-commit-config.yaml", - ".trampolinerc", - "CODE_OF_CONDUCT.md", - "CONTRIBUTING.rst", - "LICENSE", - "MANIFEST.in", - "docs/_static/custom.css", - "docs/_templates/layout.html", - "docs/conf.py", - "docs/multiprocessing.rst", - "docs/speech_v1/services.rst", - "docs/speech_v1/types.rst", - "docs/speech_v1p1beta1/services.rst", - "docs/speech_v1p1beta1/types.rst", - "google/cloud/speech/__init__.py", - "google/cloud/speech/py.typed", - "google/cloud/speech_v1/__init__.py", - "google/cloud/speech_v1/proto/cloud_speech.proto", - "google/cloud/speech_v1/py.typed", - "google/cloud/speech_v1/services/__init__.py", - "google/cloud/speech_v1/services/speech/__init__.py", - "google/cloud/speech_v1/services/speech/async_client.py", - "google/cloud/speech_v1/services/speech/client.py", - "google/cloud/speech_v1/services/speech/transports/__init__.py", - "google/cloud/speech_v1/services/speech/transports/base.py", - "google/cloud/speech_v1/services/speech/transports/grpc.py", - "google/cloud/speech_v1/services/speech/transports/grpc_asyncio.py", - "google/cloud/speech_v1/types/__init__.py", - "google/cloud/speech_v1/types/cloud_speech.py", - "google/cloud/speech_v1p1beta1/__init__.py", - "google/cloud/speech_v1p1beta1/proto/cloud_speech.proto", - "google/cloud/speech_v1p1beta1/proto/resource.proto", - "google/cloud/speech_v1p1beta1/py.typed", - "google/cloud/speech_v1p1beta1/services/__init__.py", - "google/cloud/speech_v1p1beta1/services/speech/__init__.py", - "google/cloud/speech_v1p1beta1/services/speech/async_client.py", - "google/cloud/speech_v1p1beta1/services/speech/client.py", - "google/cloud/speech_v1p1beta1/services/speech/transports/__init__.py", - "google/cloud/speech_v1p1beta1/services/speech/transports/base.py", - "google/cloud/speech_v1p1beta1/services/speech/transports/grpc.py", - "google/cloud/speech_v1p1beta1/services/speech/transports/grpc_asyncio.py", - "google/cloud/speech_v1p1beta1/types/__init__.py", - "google/cloud/speech_v1p1beta1/types/cloud_speech.py", - "google/cloud/speech_v1p1beta1/types/resource.py", - "mypy.ini", - "noxfile.py", - "renovate.json", - "samples/AUTHORING_GUIDE.md", - "samples/CONTRIBUTING.md", - "samples/microphone/noxfile.py", - "samples/snippets/noxfile.py", - "scripts/decrypt-secrets.sh", - "scripts/fixup_speech_v1_keywords.py", - "scripts/fixup_speech_v1p1beta1_keywords.py", - "scripts/readme-gen/readme_gen.py", - "scripts/readme-gen/templates/README.tmpl.rst", - "scripts/readme-gen/templates/auth.tmpl.rst", - "scripts/readme-gen/templates/auth_api_key.tmpl.rst", - "scripts/readme-gen/templates/install_deps.tmpl.rst", - "scripts/readme-gen/templates/install_portaudio.tmpl.rst", - "setup.cfg", - "testing/.gitignore", - "tests/unit/gapic/speech_v1/__init__.py", - "tests/unit/gapic/speech_v1/test_speech.py", - "tests/unit/gapic/speech_v1p1beta1/__init__.py", - "tests/unit/gapic/speech_v1p1beta1/test_speech.py" ] } \ No newline at end of file diff --git a/tests/unit/gapic/speech_v1/__init__.py b/tests/unit/gapic/speech_v1/__init__.py index 8b137891..42ffdf2b 100644 --- a/tests/unit/gapic/speech_v1/__init__.py +++ b/tests/unit/gapic/speech_v1/__init__.py @@ -1 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/tests/unit/gapic/speech_v1/test_speech.py b/tests/unit/gapic/speech_v1/test_speech.py index 55fee09c..2e28d565 100644 --- a/tests/unit/gapic/speech_v1/test_speech.py +++ b/tests/unit/gapic/speech_v1/test_speech.py @@ -82,7 +82,22 @@ def test__get_default_mtls_endpoint(): assert SpeechClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi -@pytest.mark.parametrize("client_class", [SpeechClient, SpeechAsyncClient]) +@pytest.mark.parametrize("client_class", [SpeechClient, SpeechAsyncClient,]) +def test_speech_client_from_service_account_info(client_class): + creds = credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == "speech.googleapis.com:443" + + +@pytest.mark.parametrize("client_class", [SpeechClient, SpeechAsyncClient,]) def test_speech_client_from_service_account_file(client_class): creds = credentials.AnonymousCredentials() with mock.patch.object( @@ -91,16 +106,21 @@ def test_speech_client_from_service_account_file(client_class): factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) client = client_class.from_service_account_json("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) assert client.transport._host == "speech.googleapis.com:443" def test_speech_client_get_transport_class(): transport = SpeechClient.get_transport_class() - assert transport == transports.SpeechGrpcTransport + available_transports = [ + transports.SpeechGrpcTransport, + ] + assert transport in available_transports transport = SpeechClient.get_transport_class("grpc") assert transport == transports.SpeechGrpcTransport @@ -141,7 +161,7 @@ def test_speech_client_client_options(client_class, transport_class, transport_n credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -157,7 +177,7 @@ def test_speech_client_client_options(client_class, transport_class, transport_n credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -173,7 +193,7 @@ def test_speech_client_client_options(client_class, transport_class, transport_n credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -201,7 +221,7 @@ def test_speech_client_client_options(client_class, transport_class, transport_n credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id="octopus", client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -248,29 +268,25 @@ def test_speech_client_mtls_env_auto( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - ssl_channel_creds = mock.Mock() - with mock.patch( - "grpc.ssl_channel_credentials", return_value=ssl_channel_creds - ): - patched.return_value = None - client = client_class(client_options=options) + patched.return_value = None + client = client_class(client_options=options) - if use_client_cert_env == "false": - expected_ssl_channel_creds = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_ssl_channel_creds = ssl_channel_creds - expected_host = client.DEFAULT_MTLS_ENDPOINT + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) # Check the case ADC client cert is provided. Whether client cert is used depends on # GOOGLE_API_USE_CLIENT_CERTIFICATE value. @@ -279,66 +295,53 @@ def test_speech_client_mtls_env_auto( ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, ): with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.ssl_credentials", - new_callable=mock.PropertyMock, - ) as ssl_credentials_mock: - if use_client_cert_env == "false": - is_mtls_mock.return_value = False - ssl_credentials_mock.return_value = None - expected_host = client.DEFAULT_ENDPOINT - expected_ssl_channel_creds = None - else: - is_mtls_mock.return_value = True - ssl_credentials_mock.return_value = mock.Mock() - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_ssl_channel_creds = ( - ssl_credentials_mock.return_value - ) - - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None - ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - is_mtls_mock.return_value = False patched.return_value = None client = client_class() patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_ENDPOINT, + host=expected_host, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=expected_client_cert_source, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + @pytest.mark.parametrize( "client_class,transport_class,transport_name", @@ -360,7 +363,7 @@ def test_speech_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -386,7 +389,7 @@ def test_speech_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -403,7 +406,7 @@ def test_speech_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -440,6 +443,22 @@ def test_recognize_from_dict(): test_recognize(request_type=dict) +def test_recognize_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = SpeechClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.recognize), "__call__") as call: + client.recognize() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech.RecognizeRequest() + + @pytest.mark.asyncio async def test_recognize_async( transport: str = "grpc_asyncio", request_type=cloud_speech.RecognizeRequest @@ -603,6 +622,24 @@ def test_long_running_recognize_from_dict(): test_long_running_recognize(request_type=dict) +def test_long_running_recognize_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = SpeechClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.long_running_recognize), "__call__" + ) as call: + client.long_running_recognize() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech.LongRunningRecognizeRequest() + + @pytest.mark.asyncio async def test_long_running_recognize_async( transport: str = "grpc_asyncio", @@ -874,7 +911,7 @@ def test_transport_get_channel(): @pytest.mark.parametrize( "transport_class", - [transports.SpeechGrpcTransport, transports.SpeechGrpcAsyncIOTransport], + [transports.SpeechGrpcTransport, transports.SpeechGrpcAsyncIOTransport,], ) def test_transport_adc(transport_class): # Test default credentials are used if not provided. @@ -981,6 +1018,48 @@ def test_speech_transport_auth_adc(): ) +@pytest.mark.parametrize( + "transport_class", + [transports.SpeechGrpcTransport, transports.SpeechGrpcAsyncIOTransport], +) +def test_speech_grpc_transport_client_cert_source_for_mtls(transport_class): + cred = credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds, + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback, + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, private_key=expected_key + ) + + def test_speech_host_no_port(): client = SpeechClient( credentials=credentials.AnonymousCredentials(), @@ -1002,7 +1081,7 @@ def test_speech_host_with_port(): def test_speech_grpc_transport_channel(): - channel = grpc.insecure_channel("http://localhost/") + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.SpeechGrpcTransport( @@ -1014,7 +1093,7 @@ def test_speech_grpc_transport_channel(): def test_speech_grpc_asyncio_transport_channel(): - channel = aio.insecure_channel("http://localhost/") + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.SpeechGrpcAsyncIOTransport( @@ -1025,6 +1104,8 @@ def test_speech_grpc_asyncio_transport_channel(): assert transport._ssl_channel_credentials == None +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [transports.SpeechGrpcTransport, transports.SpeechGrpcAsyncIOTransport], @@ -1034,7 +1115,7 @@ def test_speech_transport_channel_mtls_with_client_cert_source(transport_class): "grpc.ssl_channel_credentials", autospec=True ) as grpc_ssl_channel_cred: with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_ssl_cred = mock.Mock() grpc_ssl_channel_cred.return_value = mock_ssl_cred @@ -1072,6 +1153,8 @@ def test_speech_transport_channel_mtls_with_client_cert_source(transport_class): assert transport._ssl_channel_credentials == mock_ssl_cred +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [transports.SpeechGrpcTransport, transports.SpeechGrpcAsyncIOTransport], @@ -1084,7 +1167,7 @@ def test_speech_transport_channel_mtls_with_adc(transport_class): ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel diff --git a/tests/unit/gapic/speech_v1p1beta1/__init__.py b/tests/unit/gapic/speech_v1p1beta1/__init__.py index 8b137891..42ffdf2b 100644 --- a/tests/unit/gapic/speech_v1p1beta1/__init__.py +++ b/tests/unit/gapic/speech_v1p1beta1/__init__.py @@ -1 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/tests/unit/gapic/speech_v1p1beta1/test_adaptation.py b/tests/unit/gapic/speech_v1p1beta1/test_adaptation.py new file mode 100644 index 00000000..f47c5d84 --- /dev/null +++ b/tests/unit/gapic/speech_v1p1beta1/test_adaptation.py @@ -0,0 +1,3352 @@ +# -*- coding: utf-8 -*- + +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import os +import mock + +import grpc +from grpc.experimental import aio +import math +import pytest +from proto.marshal.rules.dates import DurationRule, TimestampRule + +from google import auth +from google.api_core import client_options +from google.api_core import exceptions +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers +from google.api_core import grpc_helpers_async +from google.auth import credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.speech_v1p1beta1.services.adaptation import AdaptationAsyncClient +from google.cloud.speech_v1p1beta1.services.adaptation import AdaptationClient +from google.cloud.speech_v1p1beta1.services.adaptation import pagers +from google.cloud.speech_v1p1beta1.services.adaptation import transports +from google.cloud.speech_v1p1beta1.types import cloud_speech_adaptation +from google.cloud.speech_v1p1beta1.types import resource +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 as field_mask # type: ignore + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert AdaptationClient._get_default_mtls_endpoint(None) is None + assert ( + AdaptationClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + ) + assert ( + AdaptationClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + AdaptationClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + AdaptationClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert AdaptationClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class", [AdaptationClient, AdaptationAsyncClient,]) +def test_adaptation_client_from_service_account_info(client_class): + creds = credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == "speech.googleapis.com:443" + + +@pytest.mark.parametrize("client_class", [AdaptationClient, AdaptationAsyncClient,]) +def test_adaptation_client_from_service_account_file(client_class): + creds = credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json") + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json("dummy/file/path.json") + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == "speech.googleapis.com:443" + + +def test_adaptation_client_get_transport_class(): + transport = AdaptationClient.get_transport_class() + available_transports = [ + transports.AdaptationGrpcTransport, + ] + assert transport in available_transports + + transport = AdaptationClient.get_transport_class("grpc") + assert transport == transports.AdaptationGrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (AdaptationClient, transports.AdaptationGrpcTransport, "grpc"), + ( + AdaptationAsyncClient, + transports.AdaptationGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ], +) +@mock.patch.object( + AdaptationClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AdaptationClient) +) +@mock.patch.object( + AdaptationAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(AdaptationAsyncClient), +) +def test_adaptation_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(AdaptationClient, "get_transport_class") as gtc: + transport = transport_class(credentials=credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(AdaptationClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + (AdaptationClient, transports.AdaptationGrpcTransport, "grpc", "true"), + ( + AdaptationAsyncClient, + transports.AdaptationGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + (AdaptationClient, transports.AdaptationGrpcTransport, "grpc", "false"), + ( + AdaptationAsyncClient, + transports.AdaptationGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ], +) +@mock.patch.object( + AdaptationClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AdaptationClient) +) +@mock.patch.object( + AdaptationAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(AdaptationAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_adaptation_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (AdaptationClient, transports.AdaptationGrpcTransport, "grpc"), + ( + AdaptationAsyncClient, + transports.AdaptationGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ], +) +def test_adaptation_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions(scopes=["1", "2"],) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (AdaptationClient, transports.AdaptationGrpcTransport, "grpc"), + ( + AdaptationAsyncClient, + transports.AdaptationGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ], +) +def test_adaptation_client_client_options_credentials_file( + client_class, transport_class, transport_name +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +def test_adaptation_client_client_options_from_dict(): + with mock.patch( + "google.cloud.speech_v1p1beta1.services.adaptation.transports.AdaptationGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = AdaptationClient(client_options={"api_endpoint": "squid.clam.whelk"}) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +def test_create_phrase_set( + transport: str = "grpc", request_type=cloud_speech_adaptation.CreatePhraseSetRequest +): + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_phrase_set), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = resource.PhraseSet(name="name_value", boost=0.551,) + + response = client.create_phrase_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.CreatePhraseSetRequest() + + # Establish that the response is the type that we expect. + + assert isinstance(response, resource.PhraseSet) + + assert response.name == "name_value" + + assert math.isclose(response.boost, 0.551, rel_tol=1e-6) + + +def test_create_phrase_set_from_dict(): + test_create_phrase_set(request_type=dict) + + +def test_create_phrase_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_phrase_set), "__call__" + ) as call: + client.create_phrase_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.CreatePhraseSetRequest() + + +@pytest.mark.asyncio +async def test_create_phrase_set_async( + transport: str = "grpc_asyncio", + request_type=cloud_speech_adaptation.CreatePhraseSetRequest, +): + client = AdaptationAsyncClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_phrase_set), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + resource.PhraseSet(name="name_value", boost=0.551,) + ) + + response = await client.create_phrase_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.CreatePhraseSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, resource.PhraseSet) + + assert response.name == "name_value" + + assert math.isclose(response.boost, 0.551, rel_tol=1e-6) + + +@pytest.mark.asyncio +async def test_create_phrase_set_async_from_dict(): + await test_create_phrase_set_async(request_type=dict) + + +def test_create_phrase_set_field_headers(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cloud_speech_adaptation.CreatePhraseSetRequest() + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_phrase_set), "__call__" + ) as call: + call.return_value = resource.PhraseSet() + + client.create_phrase_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_create_phrase_set_field_headers_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cloud_speech_adaptation.CreatePhraseSetRequest() + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_phrase_set), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(resource.PhraseSet()) + + await client.create_phrase_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + + +def test_create_phrase_set_flattened(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_phrase_set), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = resource.PhraseSet() + + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_phrase_set( + parent="parent_value", + phrase_set=resource.PhraseSet(name="name_value"), + phrase_set_id="phrase_set_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0].parent == "parent_value" + + assert args[0].phrase_set == resource.PhraseSet(name="name_value") + + assert args[0].phrase_set_id == "phrase_set_id_value" + + +def test_create_phrase_set_flattened_error(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_phrase_set( + cloud_speech_adaptation.CreatePhraseSetRequest(), + parent="parent_value", + phrase_set=resource.PhraseSet(name="name_value"), + phrase_set_id="phrase_set_id_value", + ) + + +@pytest.mark.asyncio +async def test_create_phrase_set_flattened_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_phrase_set), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = resource.PhraseSet() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(resource.PhraseSet()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_phrase_set( + parent="parent_value", + phrase_set=resource.PhraseSet(name="name_value"), + phrase_set_id="phrase_set_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0].parent == "parent_value" + + assert args[0].phrase_set == resource.PhraseSet(name="name_value") + + assert args[0].phrase_set_id == "phrase_set_id_value" + + +@pytest.mark.asyncio +async def test_create_phrase_set_flattened_error_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_phrase_set( + cloud_speech_adaptation.CreatePhraseSetRequest(), + parent="parent_value", + phrase_set=resource.PhraseSet(name="name_value"), + phrase_set_id="phrase_set_id_value", + ) + + +def test_get_phrase_set( + transport: str = "grpc", request_type=cloud_speech_adaptation.GetPhraseSetRequest +): + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_phrase_set), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = resource.PhraseSet(name="name_value", boost=0.551,) + + response = client.get_phrase_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.GetPhraseSetRequest() + + # Establish that the response is the type that we expect. + + assert isinstance(response, resource.PhraseSet) + + assert response.name == "name_value" + + assert math.isclose(response.boost, 0.551, rel_tol=1e-6) + + +def test_get_phrase_set_from_dict(): + test_get_phrase_set(request_type=dict) + + +def test_get_phrase_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_phrase_set), "__call__") as call: + client.get_phrase_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.GetPhraseSetRequest() + + +@pytest.mark.asyncio +async def test_get_phrase_set_async( + transport: str = "grpc_asyncio", + request_type=cloud_speech_adaptation.GetPhraseSetRequest, +): + client = AdaptationAsyncClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_phrase_set), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + resource.PhraseSet(name="name_value", boost=0.551,) + ) + + response = await client.get_phrase_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.GetPhraseSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, resource.PhraseSet) + + assert response.name == "name_value" + + assert math.isclose(response.boost, 0.551, rel_tol=1e-6) + + +@pytest.mark.asyncio +async def test_get_phrase_set_async_from_dict(): + await test_get_phrase_set_async(request_type=dict) + + +def test_get_phrase_set_field_headers(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cloud_speech_adaptation.GetPhraseSetRequest() + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_phrase_set), "__call__") as call: + call.return_value = resource.PhraseSet() + + client.get_phrase_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "name=name/value",) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_phrase_set_field_headers_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cloud_speech_adaptation.GetPhraseSetRequest() + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_phrase_set), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(resource.PhraseSet()) + + await client.get_phrase_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "name=name/value",) in kw["metadata"] + + +def test_get_phrase_set_flattened(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_phrase_set), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = resource.PhraseSet() + + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_phrase_set(name="name_value",) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0].name == "name_value" + + +def test_get_phrase_set_flattened_error(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_phrase_set( + cloud_speech_adaptation.GetPhraseSetRequest(), name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_phrase_set_flattened_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_phrase_set), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = resource.PhraseSet() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(resource.PhraseSet()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_phrase_set(name="name_value",) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0].name == "name_value" + + +@pytest.mark.asyncio +async def test_get_phrase_set_flattened_error_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_phrase_set( + cloud_speech_adaptation.GetPhraseSetRequest(), name="name_value", + ) + + +def test_list_phrase_set( + transport: str = "grpc", request_type=cloud_speech_adaptation.ListPhraseSetRequest +): + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_phrase_set), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = cloud_speech_adaptation.ListPhraseSetResponse( + next_page_token="next_page_token_value", + ) + + response = client.list_phrase_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.ListPhraseSetRequest() + + # Establish that the response is the type that we expect. + + assert isinstance(response, pagers.ListPhraseSetPager) + + assert response.next_page_token == "next_page_token_value" + + +def test_list_phrase_set_from_dict(): + test_list_phrase_set(request_type=dict) + + +def test_list_phrase_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_phrase_set), "__call__") as call: + client.list_phrase_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.ListPhraseSetRequest() + + +@pytest.mark.asyncio +async def test_list_phrase_set_async( + transport: str = "grpc_asyncio", + request_type=cloud_speech_adaptation.ListPhraseSetRequest, +): + client = AdaptationAsyncClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_phrase_set), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + cloud_speech_adaptation.ListPhraseSetResponse( + next_page_token="next_page_token_value", + ) + ) + + response = await client.list_phrase_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.ListPhraseSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListPhraseSetAsyncPager) + + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_phrase_set_async_from_dict(): + await test_list_phrase_set_async(request_type=dict) + + +def test_list_phrase_set_field_headers(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cloud_speech_adaptation.ListPhraseSetRequest() + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_phrase_set), "__call__") as call: + call.return_value = cloud_speech_adaptation.ListPhraseSetResponse() + + client.list_phrase_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_phrase_set_field_headers_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cloud_speech_adaptation.ListPhraseSetRequest() + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_phrase_set), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + cloud_speech_adaptation.ListPhraseSetResponse() + ) + + await client.list_phrase_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + + +def test_list_phrase_set_flattened(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_phrase_set), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = cloud_speech_adaptation.ListPhraseSetResponse() + + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_phrase_set(parent="parent_value",) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0].parent == "parent_value" + + +def test_list_phrase_set_flattened_error(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_phrase_set( + cloud_speech_adaptation.ListPhraseSetRequest(), parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_phrase_set_flattened_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_phrase_set), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = cloud_speech_adaptation.ListPhraseSetResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + cloud_speech_adaptation.ListPhraseSetResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_phrase_set(parent="parent_value",) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0].parent == "parent_value" + + +@pytest.mark.asyncio +async def test_list_phrase_set_flattened_error_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_phrase_set( + cloud_speech_adaptation.ListPhraseSetRequest(), parent="parent_value", + ) + + +def test_list_phrase_set_pager(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_phrase_set), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + cloud_speech_adaptation.ListPhraseSetResponse( + phrase_sets=[ + resource.PhraseSet(), + resource.PhraseSet(), + resource.PhraseSet(), + ], + next_page_token="abc", + ), + cloud_speech_adaptation.ListPhraseSetResponse( + phrase_sets=[], next_page_token="def", + ), + cloud_speech_adaptation.ListPhraseSetResponse( + phrase_sets=[resource.PhraseSet(),], next_page_token="ghi", + ), + cloud_speech_adaptation.ListPhraseSetResponse( + phrase_sets=[resource.PhraseSet(), resource.PhraseSet(),], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_phrase_set(request={}) + + assert pager._metadata == metadata + + results = [i for i in pager] + assert len(results) == 6 + assert all(isinstance(i, resource.PhraseSet) for i in results) + + +def test_list_phrase_set_pages(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_phrase_set), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + cloud_speech_adaptation.ListPhraseSetResponse( + phrase_sets=[ + resource.PhraseSet(), + resource.PhraseSet(), + resource.PhraseSet(), + ], + next_page_token="abc", + ), + cloud_speech_adaptation.ListPhraseSetResponse( + phrase_sets=[], next_page_token="def", + ), + cloud_speech_adaptation.ListPhraseSetResponse( + phrase_sets=[resource.PhraseSet(),], next_page_token="ghi", + ), + cloud_speech_adaptation.ListPhraseSetResponse( + phrase_sets=[resource.PhraseSet(), resource.PhraseSet(),], + ), + RuntimeError, + ) + pages = list(client.list_phrase_set(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_phrase_set_async_pager(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_phrase_set), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + cloud_speech_adaptation.ListPhraseSetResponse( + phrase_sets=[ + resource.PhraseSet(), + resource.PhraseSet(), + resource.PhraseSet(), + ], + next_page_token="abc", + ), + cloud_speech_adaptation.ListPhraseSetResponse( + phrase_sets=[], next_page_token="def", + ), + cloud_speech_adaptation.ListPhraseSetResponse( + phrase_sets=[resource.PhraseSet(),], next_page_token="ghi", + ), + cloud_speech_adaptation.ListPhraseSetResponse( + phrase_sets=[resource.PhraseSet(), resource.PhraseSet(),], + ), + RuntimeError, + ) + async_pager = await client.list_phrase_set(request={},) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, resource.PhraseSet) for i in responses) + + +@pytest.mark.asyncio +async def test_list_phrase_set_async_pages(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_phrase_set), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + cloud_speech_adaptation.ListPhraseSetResponse( + phrase_sets=[ + resource.PhraseSet(), + resource.PhraseSet(), + resource.PhraseSet(), + ], + next_page_token="abc", + ), + cloud_speech_adaptation.ListPhraseSetResponse( + phrase_sets=[], next_page_token="def", + ), + cloud_speech_adaptation.ListPhraseSetResponse( + phrase_sets=[resource.PhraseSet(),], next_page_token="ghi", + ), + cloud_speech_adaptation.ListPhraseSetResponse( + phrase_sets=[resource.PhraseSet(), resource.PhraseSet(),], + ), + RuntimeError, + ) + pages = [] + async for page_ in (await client.list_phrase_set(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_update_phrase_set( + transport: str = "grpc", request_type=cloud_speech_adaptation.UpdatePhraseSetRequest +): + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_phrase_set), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = resource.PhraseSet(name="name_value", boost=0.551,) + + response = client.update_phrase_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.UpdatePhraseSetRequest() + + # Establish that the response is the type that we expect. + + assert isinstance(response, resource.PhraseSet) + + assert response.name == "name_value" + + assert math.isclose(response.boost, 0.551, rel_tol=1e-6) + + +def test_update_phrase_set_from_dict(): + test_update_phrase_set(request_type=dict) + + +def test_update_phrase_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_phrase_set), "__call__" + ) as call: + client.update_phrase_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.UpdatePhraseSetRequest() + + +@pytest.mark.asyncio +async def test_update_phrase_set_async( + transport: str = "grpc_asyncio", + request_type=cloud_speech_adaptation.UpdatePhraseSetRequest, +): + client = AdaptationAsyncClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_phrase_set), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + resource.PhraseSet(name="name_value", boost=0.551,) + ) + + response = await client.update_phrase_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.UpdatePhraseSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, resource.PhraseSet) + + assert response.name == "name_value" + + assert math.isclose(response.boost, 0.551, rel_tol=1e-6) + + +@pytest.mark.asyncio +async def test_update_phrase_set_async_from_dict(): + await test_update_phrase_set_async(request_type=dict) + + +def test_update_phrase_set_field_headers(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cloud_speech_adaptation.UpdatePhraseSetRequest() + request.phrase_set.name = "phrase_set.name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_phrase_set), "__call__" + ) as call: + call.return_value = resource.PhraseSet() + + client.update_phrase_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "phrase_set.name=phrase_set.name/value",) in kw[ + "metadata" + ] + + +@pytest.mark.asyncio +async def test_update_phrase_set_field_headers_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cloud_speech_adaptation.UpdatePhraseSetRequest() + request.phrase_set.name = "phrase_set.name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_phrase_set), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(resource.PhraseSet()) + + await client.update_phrase_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "phrase_set.name=phrase_set.name/value",) in kw[ + "metadata" + ] + + +def test_delete_phrase_set( + transport: str = "grpc", request_type=cloud_speech_adaptation.DeletePhraseSetRequest +): + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_phrase_set), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + + response = client.delete_phrase_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.DeletePhraseSetRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_phrase_set_from_dict(): + test_delete_phrase_set(request_type=dict) + + +def test_delete_phrase_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_phrase_set), "__call__" + ) as call: + client.delete_phrase_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.DeletePhraseSetRequest() + + +@pytest.mark.asyncio +async def test_delete_phrase_set_async( + transport: str = "grpc_asyncio", + request_type=cloud_speech_adaptation.DeletePhraseSetRequest, +): + client = AdaptationAsyncClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_phrase_set), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + + response = await client.delete_phrase_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.DeletePhraseSetRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_phrase_set_async_from_dict(): + await test_delete_phrase_set_async(request_type=dict) + + +def test_delete_phrase_set_field_headers(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cloud_speech_adaptation.DeletePhraseSetRequest() + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_phrase_set), "__call__" + ) as call: + call.return_value = None + + client.delete_phrase_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "name=name/value",) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_delete_phrase_set_field_headers_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cloud_speech_adaptation.DeletePhraseSetRequest() + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_phrase_set), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + + await client.delete_phrase_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "name=name/value",) in kw["metadata"] + + +def test_delete_phrase_set_flattened(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_phrase_set), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_phrase_set(name="name_value",) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0].name == "name_value" + + +def test_delete_phrase_set_flattened_error(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_phrase_set( + cloud_speech_adaptation.DeletePhraseSetRequest(), name="name_value", + ) + + +@pytest.mark.asyncio +async def test_delete_phrase_set_flattened_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_phrase_set), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_phrase_set(name="name_value",) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0].name == "name_value" + + +@pytest.mark.asyncio +async def test_delete_phrase_set_flattened_error_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_phrase_set( + cloud_speech_adaptation.DeletePhraseSetRequest(), name="name_value", + ) + + +def test_create_custom_class( + transport: str = "grpc", + request_type=cloud_speech_adaptation.CreateCustomClassRequest, +): + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_custom_class), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = resource.CustomClass( + name="name_value", custom_class_id="custom_class_id_value", + ) + + response = client.create_custom_class(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.CreateCustomClassRequest() + + # Establish that the response is the type that we expect. + + assert isinstance(response, resource.CustomClass) + + assert response.name == "name_value" + + assert response.custom_class_id == "custom_class_id_value" + + +def test_create_custom_class_from_dict(): + test_create_custom_class(request_type=dict) + + +def test_create_custom_class_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_custom_class), "__call__" + ) as call: + client.create_custom_class() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.CreateCustomClassRequest() + + +@pytest.mark.asyncio +async def test_create_custom_class_async( + transport: str = "grpc_asyncio", + request_type=cloud_speech_adaptation.CreateCustomClassRequest, +): + client = AdaptationAsyncClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_custom_class), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + resource.CustomClass( + name="name_value", custom_class_id="custom_class_id_value", + ) + ) + + response = await client.create_custom_class(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.CreateCustomClassRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, resource.CustomClass) + + assert response.name == "name_value" + + assert response.custom_class_id == "custom_class_id_value" + + +@pytest.mark.asyncio +async def test_create_custom_class_async_from_dict(): + await test_create_custom_class_async(request_type=dict) + + +def test_create_custom_class_field_headers(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cloud_speech_adaptation.CreateCustomClassRequest() + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_custom_class), "__call__" + ) as call: + call.return_value = resource.CustomClass() + + client.create_custom_class(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_create_custom_class_field_headers_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cloud_speech_adaptation.CreateCustomClassRequest() + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_custom_class), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + resource.CustomClass() + ) + + await client.create_custom_class(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + + +def test_create_custom_class_flattened(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_custom_class), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = resource.CustomClass() + + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_custom_class( + parent="parent_value", + custom_class=resource.CustomClass(name="name_value"), + custom_class_id="custom_class_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0].parent == "parent_value" + + assert args[0].custom_class == resource.CustomClass(name="name_value") + + assert args[0].custom_class_id == "custom_class_id_value" + + +def test_create_custom_class_flattened_error(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_custom_class( + cloud_speech_adaptation.CreateCustomClassRequest(), + parent="parent_value", + custom_class=resource.CustomClass(name="name_value"), + custom_class_id="custom_class_id_value", + ) + + +@pytest.mark.asyncio +async def test_create_custom_class_flattened_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_custom_class), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = resource.CustomClass() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + resource.CustomClass() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_custom_class( + parent="parent_value", + custom_class=resource.CustomClass(name="name_value"), + custom_class_id="custom_class_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0].parent == "parent_value" + + assert args[0].custom_class == resource.CustomClass(name="name_value") + + assert args[0].custom_class_id == "custom_class_id_value" + + +@pytest.mark.asyncio +async def test_create_custom_class_flattened_error_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_custom_class( + cloud_speech_adaptation.CreateCustomClassRequest(), + parent="parent_value", + custom_class=resource.CustomClass(name="name_value"), + custom_class_id="custom_class_id_value", + ) + + +def test_get_custom_class( + transport: str = "grpc", request_type=cloud_speech_adaptation.GetCustomClassRequest +): + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_custom_class), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = resource.CustomClass( + name="name_value", custom_class_id="custom_class_id_value", + ) + + response = client.get_custom_class(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.GetCustomClassRequest() + + # Establish that the response is the type that we expect. + + assert isinstance(response, resource.CustomClass) + + assert response.name == "name_value" + + assert response.custom_class_id == "custom_class_id_value" + + +def test_get_custom_class_from_dict(): + test_get_custom_class(request_type=dict) + + +def test_get_custom_class_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_custom_class), "__call__") as call: + client.get_custom_class() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.GetCustomClassRequest() + + +@pytest.mark.asyncio +async def test_get_custom_class_async( + transport: str = "grpc_asyncio", + request_type=cloud_speech_adaptation.GetCustomClassRequest, +): + client = AdaptationAsyncClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_custom_class), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + resource.CustomClass( + name="name_value", custom_class_id="custom_class_id_value", + ) + ) + + response = await client.get_custom_class(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.GetCustomClassRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, resource.CustomClass) + + assert response.name == "name_value" + + assert response.custom_class_id == "custom_class_id_value" + + +@pytest.mark.asyncio +async def test_get_custom_class_async_from_dict(): + await test_get_custom_class_async(request_type=dict) + + +def test_get_custom_class_field_headers(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cloud_speech_adaptation.GetCustomClassRequest() + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_custom_class), "__call__") as call: + call.return_value = resource.CustomClass() + + client.get_custom_class(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "name=name/value",) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_custom_class_field_headers_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cloud_speech_adaptation.GetCustomClassRequest() + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_custom_class), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + resource.CustomClass() + ) + + await client.get_custom_class(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "name=name/value",) in kw["metadata"] + + +def test_get_custom_class_flattened(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_custom_class), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = resource.CustomClass() + + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_custom_class(name="name_value",) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0].name == "name_value" + + +def test_get_custom_class_flattened_error(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_custom_class( + cloud_speech_adaptation.GetCustomClassRequest(), name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_custom_class_flattened_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_custom_class), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = resource.CustomClass() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + resource.CustomClass() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_custom_class(name="name_value",) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0].name == "name_value" + + +@pytest.mark.asyncio +async def test_get_custom_class_flattened_error_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_custom_class( + cloud_speech_adaptation.GetCustomClassRequest(), name="name_value", + ) + + +def test_list_custom_classes( + transport: str = "grpc", + request_type=cloud_speech_adaptation.ListCustomClassesRequest, +): + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_custom_classes), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = cloud_speech_adaptation.ListCustomClassesResponse( + next_page_token="next_page_token_value", + ) + + response = client.list_custom_classes(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.ListCustomClassesRequest() + + # Establish that the response is the type that we expect. + + assert isinstance(response, pagers.ListCustomClassesPager) + + assert response.next_page_token == "next_page_token_value" + + +def test_list_custom_classes_from_dict(): + test_list_custom_classes(request_type=dict) + + +def test_list_custom_classes_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_custom_classes), "__call__" + ) as call: + client.list_custom_classes() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.ListCustomClassesRequest() + + +@pytest.mark.asyncio +async def test_list_custom_classes_async( + transport: str = "grpc_asyncio", + request_type=cloud_speech_adaptation.ListCustomClassesRequest, +): + client = AdaptationAsyncClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_custom_classes), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + cloud_speech_adaptation.ListCustomClassesResponse( + next_page_token="next_page_token_value", + ) + ) + + response = await client.list_custom_classes(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.ListCustomClassesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListCustomClassesAsyncPager) + + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_custom_classes_async_from_dict(): + await test_list_custom_classes_async(request_type=dict) + + +def test_list_custom_classes_field_headers(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cloud_speech_adaptation.ListCustomClassesRequest() + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_custom_classes), "__call__" + ) as call: + call.return_value = cloud_speech_adaptation.ListCustomClassesResponse() + + client.list_custom_classes(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_custom_classes_field_headers_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cloud_speech_adaptation.ListCustomClassesRequest() + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_custom_classes), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + cloud_speech_adaptation.ListCustomClassesResponse() + ) + + await client.list_custom_classes(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + + +def test_list_custom_classes_flattened(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_custom_classes), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = cloud_speech_adaptation.ListCustomClassesResponse() + + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_custom_classes(parent="parent_value",) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0].parent == "parent_value" + + +def test_list_custom_classes_flattened_error(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_custom_classes( + cloud_speech_adaptation.ListCustomClassesRequest(), parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_custom_classes_flattened_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_custom_classes), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = cloud_speech_adaptation.ListCustomClassesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + cloud_speech_adaptation.ListCustomClassesResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_custom_classes(parent="parent_value",) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0].parent == "parent_value" + + +@pytest.mark.asyncio +async def test_list_custom_classes_flattened_error_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_custom_classes( + cloud_speech_adaptation.ListCustomClassesRequest(), parent="parent_value", + ) + + +def test_list_custom_classes_pager(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_custom_classes), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + cloud_speech_adaptation.ListCustomClassesResponse( + custom_classes=[ + resource.CustomClass(), + resource.CustomClass(), + resource.CustomClass(), + ], + next_page_token="abc", + ), + cloud_speech_adaptation.ListCustomClassesResponse( + custom_classes=[], next_page_token="def", + ), + cloud_speech_adaptation.ListCustomClassesResponse( + custom_classes=[resource.CustomClass(),], next_page_token="ghi", + ), + cloud_speech_adaptation.ListCustomClassesResponse( + custom_classes=[resource.CustomClass(), resource.CustomClass(),], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_custom_classes(request={}) + + assert pager._metadata == metadata + + results = [i for i in pager] + assert len(results) == 6 + assert all(isinstance(i, resource.CustomClass) for i in results) + + +def test_list_custom_classes_pages(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_custom_classes), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + cloud_speech_adaptation.ListCustomClassesResponse( + custom_classes=[ + resource.CustomClass(), + resource.CustomClass(), + resource.CustomClass(), + ], + next_page_token="abc", + ), + cloud_speech_adaptation.ListCustomClassesResponse( + custom_classes=[], next_page_token="def", + ), + cloud_speech_adaptation.ListCustomClassesResponse( + custom_classes=[resource.CustomClass(),], next_page_token="ghi", + ), + cloud_speech_adaptation.ListCustomClassesResponse( + custom_classes=[resource.CustomClass(), resource.CustomClass(),], + ), + RuntimeError, + ) + pages = list(client.list_custom_classes(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_custom_classes_async_pager(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_custom_classes), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + cloud_speech_adaptation.ListCustomClassesResponse( + custom_classes=[ + resource.CustomClass(), + resource.CustomClass(), + resource.CustomClass(), + ], + next_page_token="abc", + ), + cloud_speech_adaptation.ListCustomClassesResponse( + custom_classes=[], next_page_token="def", + ), + cloud_speech_adaptation.ListCustomClassesResponse( + custom_classes=[resource.CustomClass(),], next_page_token="ghi", + ), + cloud_speech_adaptation.ListCustomClassesResponse( + custom_classes=[resource.CustomClass(), resource.CustomClass(),], + ), + RuntimeError, + ) + async_pager = await client.list_custom_classes(request={},) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, resource.CustomClass) for i in responses) + + +@pytest.mark.asyncio +async def test_list_custom_classes_async_pages(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_custom_classes), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + cloud_speech_adaptation.ListCustomClassesResponse( + custom_classes=[ + resource.CustomClass(), + resource.CustomClass(), + resource.CustomClass(), + ], + next_page_token="abc", + ), + cloud_speech_adaptation.ListCustomClassesResponse( + custom_classes=[], next_page_token="def", + ), + cloud_speech_adaptation.ListCustomClassesResponse( + custom_classes=[resource.CustomClass(),], next_page_token="ghi", + ), + cloud_speech_adaptation.ListCustomClassesResponse( + custom_classes=[resource.CustomClass(), resource.CustomClass(),], + ), + RuntimeError, + ) + pages = [] + async for page_ in (await client.list_custom_classes(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_update_custom_class( + transport: str = "grpc", + request_type=cloud_speech_adaptation.UpdateCustomClassRequest, +): + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_custom_class), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = resource.CustomClass( + name="name_value", custom_class_id="custom_class_id_value", + ) + + response = client.update_custom_class(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.UpdateCustomClassRequest() + + # Establish that the response is the type that we expect. + + assert isinstance(response, resource.CustomClass) + + assert response.name == "name_value" + + assert response.custom_class_id == "custom_class_id_value" + + +def test_update_custom_class_from_dict(): + test_update_custom_class(request_type=dict) + + +def test_update_custom_class_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_custom_class), "__call__" + ) as call: + client.update_custom_class() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.UpdateCustomClassRequest() + + +@pytest.mark.asyncio +async def test_update_custom_class_async( + transport: str = "grpc_asyncio", + request_type=cloud_speech_adaptation.UpdateCustomClassRequest, +): + client = AdaptationAsyncClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_custom_class), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + resource.CustomClass( + name="name_value", custom_class_id="custom_class_id_value", + ) + ) + + response = await client.update_custom_class(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.UpdateCustomClassRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, resource.CustomClass) + + assert response.name == "name_value" + + assert response.custom_class_id == "custom_class_id_value" + + +@pytest.mark.asyncio +async def test_update_custom_class_async_from_dict(): + await test_update_custom_class_async(request_type=dict) + + +def test_update_custom_class_field_headers(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cloud_speech_adaptation.UpdateCustomClassRequest() + request.custom_class.name = "custom_class.name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_custom_class), "__call__" + ) as call: + call.return_value = resource.CustomClass() + + client.update_custom_class(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "custom_class.name=custom_class.name/value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_custom_class_field_headers_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cloud_speech_adaptation.UpdateCustomClassRequest() + request.custom_class.name = "custom_class.name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_custom_class), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + resource.CustomClass() + ) + + await client.update_custom_class(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "custom_class.name=custom_class.name/value", + ) in kw["metadata"] + + +def test_delete_custom_class( + transport: str = "grpc", + request_type=cloud_speech_adaptation.DeleteCustomClassRequest, +): + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_custom_class), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + + response = client.delete_custom_class(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.DeleteCustomClassRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_custom_class_from_dict(): + test_delete_custom_class(request_type=dict) + + +def test_delete_custom_class_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_custom_class), "__call__" + ) as call: + client.delete_custom_class() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.DeleteCustomClassRequest() + + +@pytest.mark.asyncio +async def test_delete_custom_class_async( + transport: str = "grpc_asyncio", + request_type=cloud_speech_adaptation.DeleteCustomClassRequest, +): + client = AdaptationAsyncClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_custom_class), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + + response = await client.delete_custom_class(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech_adaptation.DeleteCustomClassRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_custom_class_async_from_dict(): + await test_delete_custom_class_async(request_type=dict) + + +def test_delete_custom_class_field_headers(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cloud_speech_adaptation.DeleteCustomClassRequest() + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_custom_class), "__call__" + ) as call: + call.return_value = None + + client.delete_custom_class(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "name=name/value",) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_delete_custom_class_field_headers_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cloud_speech_adaptation.DeleteCustomClassRequest() + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_custom_class), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + + await client.delete_custom_class(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "name=name/value",) in kw["metadata"] + + +def test_delete_custom_class_flattened(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_custom_class), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_custom_class(name="name_value",) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0].name == "name_value" + + +def test_delete_custom_class_flattened_error(): + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_custom_class( + cloud_speech_adaptation.DeleteCustomClassRequest(), name="name_value", + ) + + +@pytest.mark.asyncio +async def test_delete_custom_class_flattened_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_custom_class), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_custom_class(name="name_value",) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0].name == "name_value" + + +@pytest.mark.asyncio +async def test_delete_custom_class_flattened_error_async(): + client = AdaptationAsyncClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_custom_class( + cloud_speech_adaptation.DeleteCustomClassRequest(), name="name_value", + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.AdaptationGrpcTransport( + credentials=credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.AdaptationGrpcTransport( + credentials=credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AdaptationClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.AdaptationGrpcTransport( + credentials=credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AdaptationClient( + client_options={"scopes": ["1", "2"]}, transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.AdaptationGrpcTransport( + credentials=credentials.AnonymousCredentials(), + ) + client = AdaptationClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.AdaptationGrpcTransport( + credentials=credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.AdaptationGrpcAsyncIOTransport( + credentials=credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [transports.AdaptationGrpcTransport, transports.AdaptationGrpcAsyncIOTransport,], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(auth, "default") as adc: + adc.return_value = (credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = AdaptationClient(credentials=credentials.AnonymousCredentials(),) + assert isinstance(client.transport, transports.AdaptationGrpcTransport,) + + +def test_adaptation_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(exceptions.DuplicateCredentialArgs): + transport = transports.AdaptationTransport( + credentials=credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_adaptation_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.cloud.speech_v1p1beta1.services.adaptation.transports.AdaptationTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.AdaptationTransport( + credentials=credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "create_phrase_set", + "get_phrase_set", + "list_phrase_set", + "update_phrase_set", + "delete_phrase_set", + "create_custom_class", + "get_custom_class", + "list_custom_classes", + "update_custom_class", + "delete_custom_class", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + +def test_adaptation_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + auth, "load_credentials_from_file" + ) as load_creds, mock.patch( + "google.cloud.speech_v1p1beta1.services.adaptation.transports.AdaptationTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (credentials.AnonymousCredentials(), None) + transport = transports.AdaptationTransport( + credentials_file="credentials.json", quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +def test_adaptation_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(auth, "default") as adc, mock.patch( + "google.cloud.speech_v1p1beta1.services.adaptation.transports.AdaptationTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (credentials.AnonymousCredentials(), None) + transport = transports.AdaptationTransport() + adc.assert_called_once() + + +def test_adaptation_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(auth, "default") as adc: + adc.return_value = (credentials.AnonymousCredentials(), None) + AdaptationClient() + adc.assert_called_once_with( + scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id=None, + ) + + +def test_adaptation_transport_auth_adc(): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(auth, "default") as adc: + adc.return_value = (credentials.AnonymousCredentials(), None) + transports.AdaptationGrpcTransport( + host="squid.clam.whelk", quota_project_id="octopus" + ) + adc.assert_called_once_with( + scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [transports.AdaptationGrpcTransport, transports.AdaptationGrpcAsyncIOTransport], +) +def test_adaptation_grpc_transport_client_cert_source_for_mtls(transport_class): + cred = credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds, + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback, + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, private_key=expected_key + ) + + +def test_adaptation_host_no_port(): + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="speech.googleapis.com" + ), + ) + assert client.transport._host == "speech.googleapis.com:443" + + +def test_adaptation_host_with_port(): + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="speech.googleapis.com:8000" + ), + ) + assert client.transport._host == "speech.googleapis.com:8000" + + +def test_adaptation_grpc_transport_channel(): + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.AdaptationGrpcTransport( + host="squid.clam.whelk", channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_adaptation_grpc_asyncio_transport_channel(): + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.AdaptationGrpcAsyncIOTransport( + host="squid.clam.whelk", channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize( + "transport_class", + [transports.AdaptationGrpcTransport, transports.AdaptationGrpcAsyncIOTransport], +) +def test_adaptation_transport_channel_mtls_with_client_cert_source(transport_class): + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel" + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize( + "transport_class", + [transports.AdaptationGrpcTransport, transports.AdaptationGrpcAsyncIOTransport], +) +def test_adaptation_transport_channel_mtls_with_adc(transport_class): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object( + transport_class, "create_channel" + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_custom_class_path(): + project = "squid" + location = "clam" + custom_class = "whelk" + + expected = "projects/{project}/locations/{location}/customClasses/{custom_class}".format( + project=project, location=location, custom_class=custom_class, + ) + actual = AdaptationClient.custom_class_path(project, location, custom_class) + assert expected == actual + + +def test_parse_custom_class_path(): + expected = { + "project": "octopus", + "location": "oyster", + "custom_class": "nudibranch", + } + path = AdaptationClient.custom_class_path(**expected) + + # Check that the path construction is reversible. + actual = AdaptationClient.parse_custom_class_path(path) + assert expected == actual + + +def test_phrase_set_path(): + project = "cuttlefish" + location = "mussel" + phrase_set = "winkle" + + expected = "projects/{project}/locations/{location}/phraseSets/{phrase_set}".format( + project=project, location=location, phrase_set=phrase_set, + ) + actual = AdaptationClient.phrase_set_path(project, location, phrase_set) + assert expected == actual + + +def test_parse_phrase_set_path(): + expected = { + "project": "nautilus", + "location": "scallop", + "phrase_set": "abalone", + } + path = AdaptationClient.phrase_set_path(**expected) + + # Check that the path construction is reversible. + actual = AdaptationClient.parse_phrase_set_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "squid" + + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = AdaptationClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "clam", + } + path = AdaptationClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = AdaptationClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "whelk" + + expected = "folders/{folder}".format(folder=folder,) + actual = AdaptationClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "octopus", + } + path = AdaptationClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = AdaptationClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "oyster" + + expected = "organizations/{organization}".format(organization=organization,) + actual = AdaptationClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nudibranch", + } + path = AdaptationClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = AdaptationClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "cuttlefish" + + expected = "projects/{project}".format(project=project,) + actual = AdaptationClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "mussel", + } + path = AdaptationClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = AdaptationClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "winkle" + location = "nautilus" + + expected = "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + actual = AdaptationClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "scallop", + "location": "abalone", + } + path = AdaptationClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = AdaptationClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_withDEFAULT_CLIENT_INFO(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.AdaptationTransport, "_prep_wrapped_messages" + ) as prep: + client = AdaptationClient( + credentials=credentials.AnonymousCredentials(), client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.AdaptationTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = AdaptationClient.get_transport_class() + transport = transport_class( + credentials=credentials.AnonymousCredentials(), client_info=client_info, + ) + prep.assert_called_once_with(client_info) diff --git a/tests/unit/gapic/speech_v1p1beta1/test_speech.py b/tests/unit/gapic/speech_v1p1beta1/test_speech.py index e04fced2..09d260c1 100644 --- a/tests/unit/gapic/speech_v1p1beta1/test_speech.py +++ b/tests/unit/gapic/speech_v1p1beta1/test_speech.py @@ -83,7 +83,22 @@ def test__get_default_mtls_endpoint(): assert SpeechClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi -@pytest.mark.parametrize("client_class", [SpeechClient, SpeechAsyncClient]) +@pytest.mark.parametrize("client_class", [SpeechClient, SpeechAsyncClient,]) +def test_speech_client_from_service_account_info(client_class): + creds = credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == "speech.googleapis.com:443" + + +@pytest.mark.parametrize("client_class", [SpeechClient, SpeechAsyncClient,]) def test_speech_client_from_service_account_file(client_class): creds = credentials.AnonymousCredentials() with mock.patch.object( @@ -92,16 +107,21 @@ def test_speech_client_from_service_account_file(client_class): factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) client = client_class.from_service_account_json("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) assert client.transport._host == "speech.googleapis.com:443" def test_speech_client_get_transport_class(): transport = SpeechClient.get_transport_class() - assert transport == transports.SpeechGrpcTransport + available_transports = [ + transports.SpeechGrpcTransport, + ] + assert transport in available_transports transport = SpeechClient.get_transport_class("grpc") assert transport == transports.SpeechGrpcTransport @@ -142,7 +162,7 @@ def test_speech_client_client_options(client_class, transport_class, transport_n credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -158,7 +178,7 @@ def test_speech_client_client_options(client_class, transport_class, transport_n credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -174,7 +194,7 @@ def test_speech_client_client_options(client_class, transport_class, transport_n credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -202,7 +222,7 @@ def test_speech_client_client_options(client_class, transport_class, transport_n credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id="octopus", client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -249,29 +269,25 @@ def test_speech_client_mtls_env_auto( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - ssl_channel_creds = mock.Mock() - with mock.patch( - "grpc.ssl_channel_credentials", return_value=ssl_channel_creds - ): - patched.return_value = None - client = client_class(client_options=options) + patched.return_value = None + client = client_class(client_options=options) - if use_client_cert_env == "false": - expected_ssl_channel_creds = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_ssl_channel_creds = ssl_channel_creds - expected_host = client.DEFAULT_MTLS_ENDPOINT + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) # Check the case ADC client cert is provided. Whether client cert is used depends on # GOOGLE_API_USE_CLIENT_CERTIFICATE value. @@ -280,66 +296,53 @@ def test_speech_client_mtls_env_auto( ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, ): with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.ssl_credentials", - new_callable=mock.PropertyMock, - ) as ssl_credentials_mock: - if use_client_cert_env == "false": - is_mtls_mock.return_value = False - ssl_credentials_mock.return_value = None - expected_host = client.DEFAULT_ENDPOINT - expected_ssl_channel_creds = None - else: - is_mtls_mock.return_value = True - ssl_credentials_mock.return_value = mock.Mock() - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_ssl_channel_creds = ( - ssl_credentials_mock.return_value - ) - - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None - ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - is_mtls_mock.return_value = False patched.return_value = None client = client_class() patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_ENDPOINT, + host=expected_host, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=expected_client_cert_source, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + @pytest.mark.parametrize( "client_class,transport_class,transport_name", @@ -361,7 +364,7 @@ def test_speech_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -387,7 +390,7 @@ def test_speech_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -404,7 +407,7 @@ def test_speech_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -441,6 +444,22 @@ def test_recognize_from_dict(): test_recognize(request_type=dict) +def test_recognize_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = SpeechClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.recognize), "__call__") as call: + client.recognize() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech.RecognizeRequest() + + @pytest.mark.asyncio async def test_recognize_async( transport: str = "grpc_asyncio", request_type=cloud_speech.RecognizeRequest @@ -604,6 +623,24 @@ def test_long_running_recognize_from_dict(): test_long_running_recognize(request_type=dict) +def test_long_running_recognize_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = SpeechClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.long_running_recognize), "__call__" + ) as call: + client.long_running_recognize() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == cloud_speech.LongRunningRecognizeRequest() + + @pytest.mark.asyncio async def test_long_running_recognize_async( transport: str = "grpc_asyncio", @@ -875,7 +912,7 @@ def test_transport_get_channel(): @pytest.mark.parametrize( "transport_class", - [transports.SpeechGrpcTransport, transports.SpeechGrpcAsyncIOTransport], + [transports.SpeechGrpcTransport, transports.SpeechGrpcAsyncIOTransport,], ) def test_transport_adc(transport_class): # Test default credentials are used if not provided. @@ -982,6 +1019,48 @@ def test_speech_transport_auth_adc(): ) +@pytest.mark.parametrize( + "transport_class", + [transports.SpeechGrpcTransport, transports.SpeechGrpcAsyncIOTransport], +) +def test_speech_grpc_transport_client_cert_source_for_mtls(transport_class): + cred = credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds, + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback, + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, private_key=expected_key + ) + + def test_speech_host_no_port(): client = SpeechClient( credentials=credentials.AnonymousCredentials(), @@ -1003,7 +1082,7 @@ def test_speech_host_with_port(): def test_speech_grpc_transport_channel(): - channel = grpc.insecure_channel("http://localhost/") + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.SpeechGrpcTransport( @@ -1015,7 +1094,7 @@ def test_speech_grpc_transport_channel(): def test_speech_grpc_asyncio_transport_channel(): - channel = aio.insecure_channel("http://localhost/") + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.SpeechGrpcAsyncIOTransport( @@ -1026,6 +1105,8 @@ def test_speech_grpc_asyncio_transport_channel(): assert transport._ssl_channel_credentials == None +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [transports.SpeechGrpcTransport, transports.SpeechGrpcAsyncIOTransport], @@ -1035,7 +1116,7 @@ def test_speech_transport_channel_mtls_with_client_cert_source(transport_class): "grpc.ssl_channel_credentials", autospec=True ) as grpc_ssl_channel_cred: with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_ssl_cred = mock.Mock() grpc_ssl_channel_cred.return_value = mock_ssl_cred @@ -1073,6 +1154,8 @@ def test_speech_transport_channel_mtls_with_client_cert_source(transport_class): assert transport._ssl_channel_credentials == mock_ssl_cred +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [transports.SpeechGrpcTransport, transports.SpeechGrpcAsyncIOTransport], @@ -1085,7 +1168,7 @@ def test_speech_transport_channel_mtls_with_adc(transport_class): ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel