diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index 7d98291c..cb89b2e3 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -1,3 +1,3 @@ docker: image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest - digest: sha256:58f73ba196b5414782605236dd0712a73541b44ff2ff4d3a36ec41092dd6fa5b + digest: sha256:ec49167c606648a063d1222220b48119c912562849a0528f35bfb592a9f72737 diff --git a/.kokoro/docs/common.cfg b/.kokoro/docs/common.cfg index 7c5d93f2..520ba420 100644 --- a/.kokoro/docs/common.cfg +++ b/.kokoro/docs/common.cfg @@ -30,6 +30,7 @@ env_vars: { env_vars: { key: "V2_STAGING_BUCKET" + # Push google cloud library docs to the Cloud RAD bucket `docs-staging-v2` value: "docs-staging-v2" } diff --git a/.repo-metadata.json b/.repo-metadata.json index 8e7854be..24d5ceb2 100644 --- a/.repo-metadata.json +++ b/.repo-metadata.json @@ -1,14 +1,16 @@ { - "name": "language", - "name_pretty": "Natural Language", - "product_documentation": "https://cloud.google.com/natural-language/docs/", - "client_documentation": "https://googleapis.dev/python/language/latest", - "issue_tracker": "https://issuetracker.google.com/savedsearches/559753", - "release_level": "ga", - "language": "python", - "library_type": "GAPIC_AUTO", - "repo": "googleapis/python-language", - "distribution_name": "google-cloud-language", - "api_id": "language.googleapis.com", - "requires_billing": true + "name": "language", + "name_pretty": "Natural Language", + "product_documentation": "https://cloud.google.com/natural-language/docs/", + "client_documentation": "https://googleapis.dev/python/language/latest", + "issue_tracker": "https://issuetracker.google.com/savedsearches/559753", + "release_level": "ga", + "language": "python", + "library_type": "GAPIC_AUTO", + "repo": "googleapis/python-language", + "distribution_name": "google-cloud-language", + "api_id": "language.googleapis.com", + "requires_billing": true, + "default_version": "v1", + "codeowner_team": "" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 646b0782..1a9bbfab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,19 @@ [1]: https://pypi.org/project/google-cloud-language/#history +### [2.3.1](https://www.github.com/googleapis/python-language/compare/v2.3.0...v2.3.1) (2021-11-01) + + +### Bug Fixes + +* **deps:** drop packaging dependency ([6374e7f](https://www.github.com/googleapis/python-language/commit/6374e7fc497897fc44c02cd86f57759874c29e82)) +* **deps:** require google-api-core >= 1.28.0 ([6374e7f](https://www.github.com/googleapis/python-language/commit/6374e7fc497897fc44c02cd86f57759874c29e82)) + + +### Documentation + +* list oneofs in docstring ([6374e7f](https://www.github.com/googleapis/python-language/commit/6374e7fc497897fc44c02cd86f57759874c29e82)) + ## [2.3.0](https://www.github.com/googleapis/python-language/compare/v2.2.2...v2.3.0) (2021-10-09) diff --git a/google/cloud/language_v1/services/language_service/async_client.py b/google/cloud/language_v1/services/language_service/async_client.py index 86d98569..04146200 100644 --- a/google/cloud/language_v1/services/language_service/async_client.py +++ b/google/cloud/language_v1/services/language_service/async_client.py @@ -19,13 +19,15 @@ 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.client_options import ClientOptions # type: ignore from google.api_core import exceptions as core_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 as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore +OptionalRetry = Union[retries.Retry, object] + from google.cloud.language_v1.types import language_service from .transports.base import LanguageServiceTransport, DEFAULT_CLIENT_INFO from .transports.grpc_asyncio import LanguageServiceGrpcAsyncIOTransport @@ -162,18 +164,18 @@ def __init__( async def analyze_sentiment( self, - request: language_service.AnalyzeSentimentRequest = None, + request: Union[language_service.AnalyzeSentimentRequest, dict] = None, *, document: language_service.Document = None, encoding_type: language_service.EncodingType = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.AnalyzeSentimentResponse: r"""Analyzes the sentiment of the provided text. Args: - request (:class:`google.cloud.language_v1.types.AnalyzeSentimentRequest`): + request (Union[google.cloud.language_v1.types.AnalyzeSentimentRequest, dict]): The request object. The sentiment analysis request message. document (:class:`google.cloud.language_v1.types.Document`): @@ -245,11 +247,11 @@ async def analyze_sentiment( async def analyze_entities( self, - request: language_service.AnalyzeEntitiesRequest = None, + request: Union[language_service.AnalyzeEntitiesRequest, dict] = None, *, document: language_service.Document = None, encoding_type: language_service.EncodingType = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.AnalyzeEntitiesResponse: @@ -259,7 +261,7 @@ async def analyze_entities( properties. Args: - request (:class:`google.cloud.language_v1.types.AnalyzeEntitiesRequest`): + request (Union[google.cloud.language_v1.types.AnalyzeEntitiesRequest, dict]): The request object. The entity analysis request message. document (:class:`google.cloud.language_v1.types.Document`): Input document. @@ -328,11 +330,11 @@ async def analyze_entities( async def analyze_entity_sentiment( self, - request: language_service.AnalyzeEntitySentimentRequest = None, + request: Union[language_service.AnalyzeEntitySentimentRequest, dict] = None, *, document: language_service.Document = None, encoding_type: language_service.EncodingType = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.AnalyzeEntitySentimentResponse: @@ -342,7 +344,7 @@ async def analyze_entity_sentiment( and its mentions. Args: - request (:class:`google.cloud.language_v1.types.AnalyzeEntitySentimentRequest`): + request (Union[google.cloud.language_v1.types.AnalyzeEntitySentimentRequest, dict]): The request object. The entity-level sentiment analysis request message. document (:class:`google.cloud.language_v1.types.Document`): @@ -414,11 +416,11 @@ async def analyze_entity_sentiment( async def analyze_syntax( self, - request: language_service.AnalyzeSyntaxRequest = None, + request: Union[language_service.AnalyzeSyntaxRequest, dict] = None, *, document: language_service.Document = None, encoding_type: language_service.EncodingType = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.AnalyzeSyntaxResponse: @@ -427,7 +429,7 @@ async def analyze_syntax( tags, dependency trees, and other properties. Args: - request (:class:`google.cloud.language_v1.types.AnalyzeSyntaxRequest`): + request (Union[google.cloud.language_v1.types.AnalyzeSyntaxRequest, dict]): The request object. The syntax analysis request message. document (:class:`google.cloud.language_v1.types.Document`): Input document. @@ -496,17 +498,17 @@ async def analyze_syntax( async def classify_text( self, - request: language_service.ClassifyTextRequest = None, + request: Union[language_service.ClassifyTextRequest, dict] = None, *, document: language_service.Document = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.ClassifyTextResponse: r"""Classifies a document into categories. Args: - request (:class:`google.cloud.language_v1.types.ClassifyTextRequest`): + request (Union[google.cloud.language_v1.types.ClassifyTextRequest, dict]): The request object. The document classification request message. document (:class:`google.cloud.language_v1.types.Document`): @@ -569,12 +571,12 @@ async def classify_text( async def annotate_text( self, - request: language_service.AnnotateTextRequest = None, + request: Union[language_service.AnnotateTextRequest, dict] = None, *, document: language_service.Document = None, features: language_service.AnnotateTextRequest.Features = None, encoding_type: language_service.EncodingType = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.AnnotateTextResponse: @@ -583,7 +585,7 @@ async def annotate_text( analyzeSyntax provide in one call. Args: - request (:class:`google.cloud.language_v1.types.AnnotateTextRequest`): + request (Union[google.cloud.language_v1.types.AnnotateTextRequest, dict]): The request object. The request message for the text annotation API, which can perform multiple analysis types (sentiment, entities, and syntax) in one call. diff --git a/google/cloud/language_v1/services/language_service/client.py b/google/cloud/language_v1/services/language_service/client.py index 7d4846ec..d2ec0b8e 100644 --- a/google/cloud/language_v1/services/language_service/client.py +++ b/google/cloud/language_v1/services/language_service/client.py @@ -30,6 +30,8 @@ from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore +OptionalRetry = Union[retries.Retry, object] + from google.cloud.language_v1.types import language_service from .transports.base import LanguageServiceTransport, DEFAULT_CLIENT_INFO from .transports.grpc import LanguageServiceGrpcTransport @@ -338,7 +340,7 @@ def analyze_sentiment( *, document: language_service.Document = None, encoding_type: language_service.EncodingType = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.AnalyzeSentimentResponse: @@ -411,7 +413,7 @@ def analyze_entities( *, document: language_service.Document = None, encoding_type: language_service.EncodingType = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.AnalyzeEntitiesResponse: @@ -484,7 +486,7 @@ def analyze_entity_sentiment( *, document: language_service.Document = None, encoding_type: language_service.EncodingType = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.AnalyzeEntitySentimentResponse: @@ -560,7 +562,7 @@ def analyze_syntax( *, document: language_service.Document = None, encoding_type: language_service.EncodingType = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.AnalyzeSyntaxResponse: @@ -631,7 +633,7 @@ def classify_text( request: Union[language_service.ClassifyTextRequest, dict] = None, *, document: language_service.Document = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.ClassifyTextResponse: @@ -696,7 +698,7 @@ def annotate_text( document: language_service.Document = None, features: language_service.AnnotateTextRequest.Features = None, encoding_type: language_service.EncodingType = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.AnnotateTextResponse: diff --git a/google/cloud/language_v1/services/language_service/transports/base.py b/google/cloud/language_v1/services/language_service/transports/base.py index 0e4917a5..b38a9acf 100644 --- a/google/cloud/language_v1/services/language_service/transports/base.py +++ b/google/cloud/language_v1/services/language_service/transports/base.py @@ -15,7 +15,6 @@ # import abc from typing import Awaitable, Callable, Dict, Optional, Sequence, Union -import packaging.version import pkg_resources import google.auth # type: ignore @@ -35,15 +34,6 @@ except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() -try: - # google.auth.__version__ was added in 1.26.0 - _GOOGLE_AUTH_VERSION = google.auth.__version__ -except AttributeError: - try: # try pkg_resources if it is available - _GOOGLE_AUTH_VERSION = pkg_resources.get_distribution("google-auth").version - except pkg_resources.DistributionNotFound: # pragma: NO COVER - _GOOGLE_AUTH_VERSION = None - class LanguageServiceTransport(abc.ABC): """Abstract transport class for LanguageService.""" @@ -96,7 +86,7 @@ def __init__( host += ":443" self._host = host - scopes_kwargs = self._get_scopes_kwargs(self._host, scopes) + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} # Save the scopes. self._scopes = scopes @@ -129,29 +119,6 @@ def __init__( # Save the credentials. self._credentials = credentials - # TODO(busunkim): This method is in the base transport - # to avoid duplicating code across the transport classes. These functions - # should be deleted once the minimum required versions of google-auth is increased. - - # TODO: Remove this function once google-auth >= 1.25.0 is required - @classmethod - def _get_scopes_kwargs( - cls, host: str, scopes: Optional[Sequence[str]] - ) -> Dict[str, Optional[Sequence[str]]]: - """Returns scopes kwargs to pass to google-auth methods depending on the google-auth version""" - - scopes_kwargs = {} - - if _GOOGLE_AUTH_VERSION and ( - packaging.version.parse(_GOOGLE_AUTH_VERSION) - >= packaging.version.parse("1.25.0") - ): - scopes_kwargs = {"scopes": scopes, "default_scopes": cls.AUTH_SCOPES} - else: - scopes_kwargs = {"scopes": scopes or cls.AUTH_SCOPES} - - return scopes_kwargs - def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { diff --git a/google/cloud/language_v1/services/language_service/transports/grpc_asyncio.py b/google/cloud/language_v1/services/language_service/transports/grpc_asyncio.py index 46294075..a9292306 100644 --- a/google/cloud/language_v1/services/language_service/transports/grpc_asyncio.py +++ b/google/cloud/language_v1/services/language_service/transports/grpc_asyncio.py @@ -20,7 +20,6 @@ from google.api_core import grpc_helpers_async # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore -import packaging.version import grpc # type: ignore from grpc.experimental import aio # type: ignore diff --git a/google/cloud/language_v1/types/language_service.py b/google/cloud/language_v1/types/language_service.py index e4ee8e53..c8beb931 100644 --- a/google/cloud/language_v1/types/language_service.py +++ b/google/cloud/language_v1/types/language_service.py @@ -62,6 +62,13 @@ class EncodingType(proto.Enum): class Document(proto.Message): r"""Represents the input to API methods. + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: type_ (google.cloud.language_v1.types.Document.Type): Required. If the type is not set or is ``TYPE_UNSPECIFIED``, @@ -70,12 +77,14 @@ class Document(proto.Message): The content of the input in string format. Cloud audit logging exempt since it is based on user data. + This field is a member of `oneof`_ ``source``. gcs_content_uri (str): The Google Cloud Storage URI where the file content is located. This URI must be of the form: gs://bucket_name/object_name. For more details, see https://cloud.google.com/storage/docs/reference-uris. NOTE: Cloud Storage object versioning is not supported. + This field is a member of `oneof`_ ``source``. language (str): The language of the document (if not specified, the language is automatically detected). Both ISO and BCP-47 language diff --git a/google/cloud/language_v1beta2/services/language_service/async_client.py b/google/cloud/language_v1beta2/services/language_service/async_client.py index c95d4083..c3b06047 100644 --- a/google/cloud/language_v1beta2/services/language_service/async_client.py +++ b/google/cloud/language_v1beta2/services/language_service/async_client.py @@ -19,13 +19,15 @@ 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.client_options import ClientOptions # type: ignore from google.api_core import exceptions as core_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 as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore +OptionalRetry = Union[retries.Retry, object] + from google.cloud.language_v1beta2.types import language_service from .transports.base import LanguageServiceTransport, DEFAULT_CLIENT_INFO from .transports.grpc_asyncio import LanguageServiceGrpcAsyncIOTransport @@ -162,18 +164,18 @@ def __init__( async def analyze_sentiment( self, - request: language_service.AnalyzeSentimentRequest = None, + request: Union[language_service.AnalyzeSentimentRequest, dict] = None, *, document: language_service.Document = None, encoding_type: language_service.EncodingType = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.AnalyzeSentimentResponse: r"""Analyzes the sentiment of the provided text. Args: - request (:class:`google.cloud.language_v1beta2.types.AnalyzeSentimentRequest`): + request (Union[google.cloud.language_v1beta2.types.AnalyzeSentimentRequest, dict]): The request object. The sentiment analysis request message. document (:class:`google.cloud.language_v1beta2.types.Document`): @@ -246,11 +248,11 @@ async def analyze_sentiment( async def analyze_entities( self, - request: language_service.AnalyzeEntitiesRequest = None, + request: Union[language_service.AnalyzeEntitiesRequest, dict] = None, *, document: language_service.Document = None, encoding_type: language_service.EncodingType = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.AnalyzeEntitiesResponse: @@ -260,7 +262,7 @@ async def analyze_entities( properties. Args: - request (:class:`google.cloud.language_v1beta2.types.AnalyzeEntitiesRequest`): + request (Union[google.cloud.language_v1beta2.types.AnalyzeEntitiesRequest, dict]): The request object. The entity analysis request message. document (:class:`google.cloud.language_v1beta2.types.Document`): Required. Input document. @@ -329,11 +331,11 @@ async def analyze_entities( async def analyze_entity_sentiment( self, - request: language_service.AnalyzeEntitySentimentRequest = None, + request: Union[language_service.AnalyzeEntitySentimentRequest, dict] = None, *, document: language_service.Document = None, encoding_type: language_service.EncodingType = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.AnalyzeEntitySentimentResponse: @@ -343,7 +345,7 @@ async def analyze_entity_sentiment( and its mentions. Args: - request (:class:`google.cloud.language_v1beta2.types.AnalyzeEntitySentimentRequest`): + request (Union[google.cloud.language_v1beta2.types.AnalyzeEntitySentimentRequest, dict]): The request object. The entity-level sentiment analysis request message. document (:class:`google.cloud.language_v1beta2.types.Document`): @@ -415,11 +417,11 @@ async def analyze_entity_sentiment( async def analyze_syntax( self, - request: language_service.AnalyzeSyntaxRequest = None, + request: Union[language_service.AnalyzeSyntaxRequest, dict] = None, *, document: language_service.Document = None, encoding_type: language_service.EncodingType = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.AnalyzeSyntaxResponse: @@ -428,7 +430,7 @@ async def analyze_syntax( tags, dependency trees, and other properties. Args: - request (:class:`google.cloud.language_v1beta2.types.AnalyzeSyntaxRequest`): + request (Union[google.cloud.language_v1beta2.types.AnalyzeSyntaxRequest, dict]): The request object. The syntax analysis request message. document (:class:`google.cloud.language_v1beta2.types.Document`): Required. Input document. @@ -497,17 +499,17 @@ async def analyze_syntax( async def classify_text( self, - request: language_service.ClassifyTextRequest = None, + request: Union[language_service.ClassifyTextRequest, dict] = None, *, document: language_service.Document = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.ClassifyTextResponse: r"""Classifies a document into categories. Args: - request (:class:`google.cloud.language_v1beta2.types.ClassifyTextRequest`): + request (Union[google.cloud.language_v1beta2.types.ClassifyTextRequest, dict]): The request object. The document classification request message. document (:class:`google.cloud.language_v1beta2.types.Document`): @@ -570,12 +572,12 @@ async def classify_text( async def annotate_text( self, - request: language_service.AnnotateTextRequest = None, + request: Union[language_service.AnnotateTextRequest, dict] = None, *, document: language_service.Document = None, features: language_service.AnnotateTextRequest.Features = None, encoding_type: language_service.EncodingType = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.AnnotateTextResponse: @@ -584,7 +586,7 @@ async def annotate_text( call. Args: - request (:class:`google.cloud.language_v1beta2.types.AnnotateTextRequest`): + request (Union[google.cloud.language_v1beta2.types.AnnotateTextRequest, dict]): The request object. The request message for the text annotation API, which can perform multiple analysis types (sentiment, entities, and syntax) in one call. diff --git a/google/cloud/language_v1beta2/services/language_service/client.py b/google/cloud/language_v1beta2/services/language_service/client.py index 3ed65bb6..e2a0de6e 100644 --- a/google/cloud/language_v1beta2/services/language_service/client.py +++ b/google/cloud/language_v1beta2/services/language_service/client.py @@ -30,6 +30,8 @@ from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore +OptionalRetry = Union[retries.Retry, object] + from google.cloud.language_v1beta2.types import language_service from .transports.base import LanguageServiceTransport, DEFAULT_CLIENT_INFO from .transports.grpc import LanguageServiceGrpcTransport @@ -338,7 +340,7 @@ def analyze_sentiment( *, document: language_service.Document = None, encoding_type: language_service.EncodingType = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.AnalyzeSentimentResponse: @@ -412,7 +414,7 @@ def analyze_entities( *, document: language_service.Document = None, encoding_type: language_service.EncodingType = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.AnalyzeEntitiesResponse: @@ -485,7 +487,7 @@ def analyze_entity_sentiment( *, document: language_service.Document = None, encoding_type: language_service.EncodingType = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.AnalyzeEntitySentimentResponse: @@ -561,7 +563,7 @@ def analyze_syntax( *, document: language_service.Document = None, encoding_type: language_service.EncodingType = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.AnalyzeSyntaxResponse: @@ -632,7 +634,7 @@ def classify_text( request: Union[language_service.ClassifyTextRequest, dict] = None, *, document: language_service.Document = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.ClassifyTextResponse: @@ -697,7 +699,7 @@ def annotate_text( document: language_service.Document = None, features: language_service.AnnotateTextRequest.Features = None, encoding_type: language_service.EncodingType = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> language_service.AnnotateTextResponse: diff --git a/google/cloud/language_v1beta2/services/language_service/transports/base.py b/google/cloud/language_v1beta2/services/language_service/transports/base.py index 59be86ca..99b2bd55 100644 --- a/google/cloud/language_v1beta2/services/language_service/transports/base.py +++ b/google/cloud/language_v1beta2/services/language_service/transports/base.py @@ -15,7 +15,6 @@ # import abc from typing import Awaitable, Callable, Dict, Optional, Sequence, Union -import packaging.version import pkg_resources import google.auth # type: ignore @@ -35,15 +34,6 @@ except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() -try: - # google.auth.__version__ was added in 1.26.0 - _GOOGLE_AUTH_VERSION = google.auth.__version__ -except AttributeError: - try: # try pkg_resources if it is available - _GOOGLE_AUTH_VERSION = pkg_resources.get_distribution("google-auth").version - except pkg_resources.DistributionNotFound: # pragma: NO COVER - _GOOGLE_AUTH_VERSION = None - class LanguageServiceTransport(abc.ABC): """Abstract transport class for LanguageService.""" @@ -96,7 +86,7 @@ def __init__( host += ":443" self._host = host - scopes_kwargs = self._get_scopes_kwargs(self._host, scopes) + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} # Save the scopes. self._scopes = scopes @@ -129,29 +119,6 @@ def __init__( # Save the credentials. self._credentials = credentials - # TODO(busunkim): This method is in the base transport - # to avoid duplicating code across the transport classes. These functions - # should be deleted once the minimum required versions of google-auth is increased. - - # TODO: Remove this function once google-auth >= 1.25.0 is required - @classmethod - def _get_scopes_kwargs( - cls, host: str, scopes: Optional[Sequence[str]] - ) -> Dict[str, Optional[Sequence[str]]]: - """Returns scopes kwargs to pass to google-auth methods depending on the google-auth version""" - - scopes_kwargs = {} - - if _GOOGLE_AUTH_VERSION and ( - packaging.version.parse(_GOOGLE_AUTH_VERSION) - >= packaging.version.parse("1.25.0") - ): - scopes_kwargs = {"scopes": scopes, "default_scopes": cls.AUTH_SCOPES} - else: - scopes_kwargs = {"scopes": scopes or cls.AUTH_SCOPES} - - return scopes_kwargs - def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { diff --git a/google/cloud/language_v1beta2/services/language_service/transports/grpc_asyncio.py b/google/cloud/language_v1beta2/services/language_service/transports/grpc_asyncio.py index 2c48f9bc..331a9b1b 100644 --- a/google/cloud/language_v1beta2/services/language_service/transports/grpc_asyncio.py +++ b/google/cloud/language_v1beta2/services/language_service/transports/grpc_asyncio.py @@ -20,7 +20,6 @@ from google.api_core import grpc_helpers_async # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore -import packaging.version import grpc # type: ignore from grpc.experimental import aio # type: ignore diff --git a/google/cloud/language_v1beta2/types/language_service.py b/google/cloud/language_v1beta2/types/language_service.py index 0aabe4a9..840ae888 100644 --- a/google/cloud/language_v1beta2/types/language_service.py +++ b/google/cloud/language_v1beta2/types/language_service.py @@ -62,6 +62,13 @@ class EncodingType(proto.Enum): class Document(proto.Message): r"""Represents the input to API methods. + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: type_ (google.cloud.language_v1beta2.types.Document.Type): Required. If the type is not set or is ``TYPE_UNSPECIFIED``, @@ -70,12 +77,14 @@ class Document(proto.Message): The content of the input in string format. Cloud audit logging exempt since it is based on user data. + This field is a member of `oneof`_ ``source``. gcs_content_uri (str): The Google Cloud Storage URI where the file content is located. This URI must be of the form: gs://bucket_name/object_name. For more details, see https://cloud.google.com/storage/docs/reference-uris. NOTE: Cloud Storage object versioning is not supported. + This field is a member of `oneof`_ ``source``. language (str): The language of the document (if not specified, the language is automatically detected). Both ISO and BCP-47 language diff --git a/noxfile.py b/noxfile.py index 672b28d6..f041f1f5 100644 --- a/noxfile.py +++ b/noxfile.py @@ -101,7 +101,7 @@ def default(session): "py.test", "--quiet", f"--junitxml=unit_{session.python}_sponge_log.xml", - "--cov=google/cloud", + "--cov=google", "--cov=tests/unit", "--cov-append", "--cov-config=.coveragerc", diff --git a/setup.py b/setup.py index 708e6149..04e3a675 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ name = "google-cloud-language" description = "Google Cloud Natural Language API client library" -version = "2.3.0" +version = "2.3.1" # Should be one of: # 'Development Status :: 3 - Alpha' # 'Development Status :: 4 - Beta' @@ -32,9 +32,8 @@ # NOTE: Maintainers, please do not require google-api-core>=2.x.x # Until this issue is closed # https://github.com/googleapis/google-cloud-python/issues/10566 - "google-api-core[grpc] >= 1.26.0, <3.0.0dev", + "google-api-core[grpc] >= 1.28.0, <3.0.0dev", "proto-plus >= 1.10.0", - "packaging >= 14.3", ] extras = {"libcst": "libcst >= 0.2.5"} diff --git a/testing/constraints-3.6.txt b/testing/constraints-3.6.txt index 90b6c319..9e0fb5ad 100644 --- a/testing/constraints-3.6.txt +++ b/testing/constraints-3.6.txt @@ -4,8 +4,6 @@ # Pin the version to the lower bound. # e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0dev", # Then this file should have google-cloud-foo==1.14.0 -google-api-core==1.26.0 +google-api-core==1.28.0 proto-plus==1.10.0 libcst==0.2.5 -packaging==14.3 -google-auth==1.24.0 # TODO: remove when google-auth>=1.25.0 si transitively required through google-api-core diff --git a/tests/unit/gapic/language_v1/test_language_service.py b/tests/unit/gapic/language_v1/test_language_service.py index a2a061a3..9be55b98 100644 --- a/tests/unit/gapic/language_v1/test_language_service.py +++ b/tests/unit/gapic/language_v1/test_language_service.py @@ -15,7 +15,6 @@ # import os import mock -import packaging.version import grpc from grpc.experimental import aio @@ -37,28 +36,11 @@ ) from google.cloud.language_v1.services.language_service import LanguageServiceClient from google.cloud.language_v1.services.language_service import transports -from google.cloud.language_v1.services.language_service.transports.base import ( - _GOOGLE_AUTH_VERSION, -) from google.cloud.language_v1.types import language_service from google.oauth2 import service_account import google.auth -# TODO(busunkim): Once google-auth >= 1.25.0 is required transitively -# through google-api-core: -# - Delete the auth "less than" test cases -# - Delete these pytest markers (Make the "greater than or equal to" tests the default). -requires_google_auth_lt_1_25_0 = pytest.mark.skipif( - packaging.version.parse(_GOOGLE_AUTH_VERSION) >= packaging.version.parse("1.25.0"), - reason="This test requires google-auth < 1.25.0", -) -requires_google_auth_gte_1_25_0 = pytest.mark.skipif( - packaging.version.parse(_GOOGLE_AUTH_VERSION) < packaging.version.parse("1.25.0"), - reason="This test requires google-auth >= 1.25.0", -) - - def client_cert_source_callback(): return b"cert bytes", b"key bytes" @@ -215,7 +197,7 @@ def test_language_service_client_client_options( 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) + client = client_class(transport=transport_name, client_options=options) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -232,7 +214,7 @@ def test_language_service_client_client_options( 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() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -249,7 +231,7 @@ def test_language_service_client_client_options( 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() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -278,7 +260,7 @@ def test_language_service_client_client_options( 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) + client = client_class(transport=transport_name, client_options=options) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -347,7 +329,7 @@ def test_language_service_client_mtls_env_auto( ) with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None - client = client_class(client_options=options) + client = client_class(transport=transport_name, client_options=options) if use_client_cert_env == "false": expected_client_cert_source = None @@ -389,7 +371,7 @@ def test_language_service_client_mtls_env_auto( expected_client_cert_source = client_cert_source_callback patched.return_value = None - client = client_class() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -411,7 +393,7 @@ def test_language_service_client_mtls_env_auto( return_value=False, ): patched.return_value = None - client = client_class() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -442,7 +424,7 @@ def test_language_service_client_client_options_scopes( 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) + client = client_class(transport=transport_name, client_options=options) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -473,7 +455,7 @@ def test_language_service_client_client_options_credentials_file( 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) + client = client_class(transport=transport_name, client_options=options) patched.assert_called_once_with( credentials=None, credentials_file="credentials.json", @@ -1691,7 +1673,6 @@ def test_language_service_base_transport(): transport.close() -@requires_google_auth_gte_1_25_0 def test_language_service_base_transport_with_credentials_file(): # Instantiate the base transport with a credentials file with mock.patch.object( @@ -1715,29 +1696,6 @@ def test_language_service_base_transport_with_credentials_file(): ) -@requires_google_auth_lt_1_25_0 -def test_language_service_base_transport_with_credentials_file_old_google_auth(): - # Instantiate the base transport with a credentials file - with mock.patch.object( - google.auth, "load_credentials_from_file", autospec=True - ) as load_creds, mock.patch( - "google.cloud.language_v1.services.language_service.transports.LanguageServiceTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.LanguageServiceTransport( - credentials_file="credentials.json", quota_project_id="octopus", - ) - load_creds.assert_called_once_with( - "credentials.json", - scopes=( - "https://www.googleapis.com/auth/cloud-language", - "https://www.googleapis.com/auth/cloud-platform", - ), - quota_project_id="octopus", - ) - - def test_language_service_base_transport_with_adc(): # Test the default credentials are used if credentials and credentials_file are None. with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( @@ -1749,7 +1707,6 @@ def test_language_service_base_transport_with_adc(): adc.assert_called_once() -@requires_google_auth_gte_1_25_0 def test_language_service_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(google.auth, "default", autospec=True) as adc: @@ -1765,21 +1722,6 @@ def test_language_service_auth_adc(): ) -@requires_google_auth_lt_1_25_0 -def test_language_service_auth_adc_old_google_auth(): - # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - LanguageServiceClient() - adc.assert_called_once_with( - scopes=( - "https://www.googleapis.com/auth/cloud-language", - "https://www.googleapis.com/auth/cloud-platform", - ), - quota_project_id=None, - ) - - @pytest.mark.parametrize( "transport_class", [ @@ -1787,7 +1729,6 @@ def test_language_service_auth_adc_old_google_auth(): transports.LanguageServiceGrpcAsyncIOTransport, ], ) -@requires_google_auth_gte_1_25_0 def test_language_service_transport_auth_adc(transport_class): # If credentials and host are not provided, the transport class should use # ADC credentials. @@ -1804,29 +1745,6 @@ def test_language_service_transport_auth_adc(transport_class): ) -@pytest.mark.parametrize( - "transport_class", - [ - transports.LanguageServiceGrpcTransport, - transports.LanguageServiceGrpcAsyncIOTransport, - ], -) -@requires_google_auth_lt_1_25_0 -def test_language_service_transport_auth_adc_old_google_auth(transport_class): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class(quota_project_id="octopus") - adc.assert_called_once_with( - scopes=( - "https://www.googleapis.com/auth/cloud-language", - "https://www.googleapis.com/auth/cloud-platform", - ), - quota_project_id="octopus", - ) - - @pytest.mark.parametrize( "transport_class,grpc_helpers", [ diff --git a/tests/unit/gapic/language_v1beta2/test_language_service.py b/tests/unit/gapic/language_v1beta2/test_language_service.py index 729ad8c1..5b0fd659 100644 --- a/tests/unit/gapic/language_v1beta2/test_language_service.py +++ b/tests/unit/gapic/language_v1beta2/test_language_service.py @@ -15,7 +15,6 @@ # import os import mock -import packaging.version import grpc from grpc.experimental import aio @@ -39,28 +38,11 @@ LanguageServiceClient, ) from google.cloud.language_v1beta2.services.language_service import transports -from google.cloud.language_v1beta2.services.language_service.transports.base import ( - _GOOGLE_AUTH_VERSION, -) from google.cloud.language_v1beta2.types import language_service from google.oauth2 import service_account import google.auth -# TODO(busunkim): Once google-auth >= 1.25.0 is required transitively -# through google-api-core: -# - Delete the auth "less than" test cases -# - Delete these pytest markers (Make the "greater than or equal to" tests the default). -requires_google_auth_lt_1_25_0 = pytest.mark.skipif( - packaging.version.parse(_GOOGLE_AUTH_VERSION) >= packaging.version.parse("1.25.0"), - reason="This test requires google-auth < 1.25.0", -) -requires_google_auth_gte_1_25_0 = pytest.mark.skipif( - packaging.version.parse(_GOOGLE_AUTH_VERSION) < packaging.version.parse("1.25.0"), - reason="This test requires google-auth >= 1.25.0", -) - - def client_cert_source_callback(): return b"cert bytes", b"key bytes" @@ -217,7 +199,7 @@ def test_language_service_client_client_options( 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) + client = client_class(transport=transport_name, client_options=options) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -234,7 +216,7 @@ def test_language_service_client_client_options( 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() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -251,7 +233,7 @@ def test_language_service_client_client_options( 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() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -280,7 +262,7 @@ def test_language_service_client_client_options( 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) + client = client_class(transport=transport_name, client_options=options) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -349,7 +331,7 @@ def test_language_service_client_mtls_env_auto( ) with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None - client = client_class(client_options=options) + client = client_class(transport=transport_name, client_options=options) if use_client_cert_env == "false": expected_client_cert_source = None @@ -391,7 +373,7 @@ def test_language_service_client_mtls_env_auto( expected_client_cert_source = client_cert_source_callback patched.return_value = None - client = client_class() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -413,7 +395,7 @@ def test_language_service_client_mtls_env_auto( return_value=False, ): patched.return_value = None - client = client_class() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -444,7 +426,7 @@ def test_language_service_client_client_options_scopes( 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) + client = client_class(transport=transport_name, client_options=options) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -475,7 +457,7 @@ def test_language_service_client_client_options_credentials_file( 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) + client = client_class(transport=transport_name, client_options=options) patched.assert_called_once_with( credentials=None, credentials_file="credentials.json", @@ -1693,7 +1675,6 @@ def test_language_service_base_transport(): transport.close() -@requires_google_auth_gte_1_25_0 def test_language_service_base_transport_with_credentials_file(): # Instantiate the base transport with a credentials file with mock.patch.object( @@ -1717,29 +1698,6 @@ def test_language_service_base_transport_with_credentials_file(): ) -@requires_google_auth_lt_1_25_0 -def test_language_service_base_transport_with_credentials_file_old_google_auth(): - # Instantiate the base transport with a credentials file - with mock.patch.object( - google.auth, "load_credentials_from_file", autospec=True - ) as load_creds, mock.patch( - "google.cloud.language_v1beta2.services.language_service.transports.LanguageServiceTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.LanguageServiceTransport( - credentials_file="credentials.json", quota_project_id="octopus", - ) - load_creds.assert_called_once_with( - "credentials.json", - scopes=( - "https://www.googleapis.com/auth/cloud-language", - "https://www.googleapis.com/auth/cloud-platform", - ), - quota_project_id="octopus", - ) - - def test_language_service_base_transport_with_adc(): # Test the default credentials are used if credentials and credentials_file are None. with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( @@ -1751,7 +1709,6 @@ def test_language_service_base_transport_with_adc(): adc.assert_called_once() -@requires_google_auth_gte_1_25_0 def test_language_service_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(google.auth, "default", autospec=True) as adc: @@ -1767,21 +1724,6 @@ def test_language_service_auth_adc(): ) -@requires_google_auth_lt_1_25_0 -def test_language_service_auth_adc_old_google_auth(): - # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - LanguageServiceClient() - adc.assert_called_once_with( - scopes=( - "https://www.googleapis.com/auth/cloud-language", - "https://www.googleapis.com/auth/cloud-platform", - ), - quota_project_id=None, - ) - - @pytest.mark.parametrize( "transport_class", [ @@ -1789,7 +1731,6 @@ def test_language_service_auth_adc_old_google_auth(): transports.LanguageServiceGrpcAsyncIOTransport, ], ) -@requires_google_auth_gte_1_25_0 def test_language_service_transport_auth_adc(transport_class): # If credentials and host are not provided, the transport class should use # ADC credentials. @@ -1806,29 +1747,6 @@ def test_language_service_transport_auth_adc(transport_class): ) -@pytest.mark.parametrize( - "transport_class", - [ - transports.LanguageServiceGrpcTransport, - transports.LanguageServiceGrpcAsyncIOTransport, - ], -) -@requires_google_auth_lt_1_25_0 -def test_language_service_transport_auth_adc_old_google_auth(transport_class): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class(quota_project_id="octopus") - adc.assert_called_once_with( - scopes=( - "https://www.googleapis.com/auth/cloud-language", - "https://www.googleapis.com/auth/cloud-platform", - ), - quota_project_id="octopus", - ) - - @pytest.mark.parametrize( "transport_class,grpc_helpers", [