diff --git a/google/cloud/videointelligence/__init__.py b/google/cloud/videointelligence/__init__.py index 5429a65f..91e6a95e 100644 --- a/google/cloud/videointelligence/__init__.py +++ b/google/cloud/videointelligence/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,12 +14,13 @@ # limitations under the License. # -from google.cloud.videointelligence_v1.services.video_intelligence_service.async_client import ( - VideoIntelligenceServiceAsyncClient, -) from google.cloud.videointelligence_v1.services.video_intelligence_service.client import ( VideoIntelligenceServiceClient, ) +from google.cloud.videointelligence_v1.services.video_intelligence_service.async_client import ( + VideoIntelligenceServiceAsyncClient, +) + from google.cloud.videointelligence_v1.types.video_intelligence import ( AnnotateVideoProgress, ) @@ -51,17 +51,12 @@ ) from google.cloud.videointelligence_v1.types.video_intelligence import FaceFrame from google.cloud.videointelligence_v1.types.video_intelligence import FaceSegment -from google.cloud.videointelligence_v1.types.video_intelligence import Feature from google.cloud.videointelligence_v1.types.video_intelligence import LabelAnnotation from google.cloud.videointelligence_v1.types.video_intelligence import ( LabelDetectionConfig, ) -from google.cloud.videointelligence_v1.types.video_intelligence import ( - LabelDetectionMode, -) from google.cloud.videointelligence_v1.types.video_intelligence import LabelFrame from google.cloud.videointelligence_v1.types.video_intelligence import LabelSegment -from google.cloud.videointelligence_v1.types.video_intelligence import Likelihood from google.cloud.videointelligence_v1.types.video_intelligence import ( LogoRecognitionAnnotation, ) @@ -117,8 +112,15 @@ from google.cloud.videointelligence_v1.types.video_intelligence import VideoContext from google.cloud.videointelligence_v1.types.video_intelligence import VideoSegment from google.cloud.videointelligence_v1.types.video_intelligence import WordInfo +from google.cloud.videointelligence_v1.types.video_intelligence import Feature +from google.cloud.videointelligence_v1.types.video_intelligence import ( + LabelDetectionMode, +) +from google.cloud.videointelligence_v1.types.video_intelligence import Likelihood __all__ = ( + "VideoIntelligenceServiceClient", + "VideoIntelligenceServiceAsyncClient", "AnnotateVideoProgress", "AnnotateVideoRequest", "AnnotateVideoResponse", @@ -133,13 +135,10 @@ "FaceDetectionConfig", "FaceFrame", "FaceSegment", - "Feature", "LabelAnnotation", "LabelDetectionConfig", - "LabelDetectionMode", "LabelFrame", "LabelSegment", - "Likelihood", "LogoRecognitionAnnotation", "NormalizedBoundingBox", "NormalizedBoundingPoly", @@ -163,8 +162,9 @@ "VideoAnnotationProgress", "VideoAnnotationResults", "VideoContext", - "VideoIntelligenceServiceAsyncClient", - "VideoIntelligenceServiceClient", "VideoSegment", "WordInfo", + "Feature", + "LabelDetectionMode", + "Likelihood", ) diff --git a/google/cloud/videointelligence_v1/__init__.py b/google/cloud/videointelligence_v1/__init__.py index 4d4929e1..2fda0e16 100644 --- a/google/cloud/videointelligence_v1/__init__.py +++ b/google/cloud/videointelligence_v1/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,6 +15,8 @@ # from .services.video_intelligence_service import VideoIntelligenceServiceClient +from .services.video_intelligence_service import VideoIntelligenceServiceAsyncClient + from .types.video_intelligence import AnnotateVideoProgress from .types.video_intelligence import AnnotateVideoRequest from .types.video_intelligence import AnnotateVideoResponse @@ -30,13 +31,10 @@ from .types.video_intelligence import FaceDetectionConfig from .types.video_intelligence import FaceFrame from .types.video_intelligence import FaceSegment -from .types.video_intelligence import Feature from .types.video_intelligence import LabelAnnotation from .types.video_intelligence import LabelDetectionConfig -from .types.video_intelligence import LabelDetectionMode from .types.video_intelligence import LabelFrame from .types.video_intelligence import LabelSegment -from .types.video_intelligence import Likelihood from .types.video_intelligence import LogoRecognitionAnnotation from .types.video_intelligence import NormalizedBoundingBox from .types.video_intelligence import NormalizedBoundingPoly @@ -62,9 +60,12 @@ from .types.video_intelligence import VideoContext from .types.video_intelligence import VideoSegment from .types.video_intelligence import WordInfo - +from .types.video_intelligence import Feature +from .types.video_intelligence import LabelDetectionMode +from .types.video_intelligence import Likelihood __all__ = ( + "VideoIntelligenceServiceAsyncClient", "AnnotateVideoProgress", "AnnotateVideoRequest", "AnnotateVideoResponse", @@ -109,7 +110,7 @@ "VideoAnnotationProgress", "VideoAnnotationResults", "VideoContext", + "VideoIntelligenceServiceClient", "VideoSegment", "WordInfo", - "VideoIntelligenceServiceClient", ) diff --git a/google/cloud/videointelligence_v1/gapic_metadata.json b/google/cloud/videointelligence_v1/gapic_metadata.json new file mode 100644 index 00000000..016f216f --- /dev/null +++ b/google/cloud/videointelligence_v1/gapic_metadata.json @@ -0,0 +1,33 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.cloud.videointelligence_v1", + "protoPackage": "google.cloud.videointelligence.v1", + "schema": "1.0", + "services": { + "VideoIntelligenceService": { + "clients": { + "grpc": { + "libraryClient": "VideoIntelligenceServiceClient", + "rpcs": { + "AnnotateVideo": { + "methods": [ + "annotate_video" + ] + } + } + }, + "grpc-async": { + "libraryClient": "VideoIntelligenceServiceAsyncClient", + "rpcs": { + "AnnotateVideo": { + "methods": [ + "annotate_video" + ] + } + } + } + } + } + } +} diff --git a/google/cloud/videointelligence_v1/services/__init__.py b/google/cloud/videointelligence_v1/services/__init__.py index 42ffdf2b..4de65971 100644 --- a/google/cloud/videointelligence_v1/services/__init__.py +++ b/google/cloud/videointelligence_v1/services/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/google/cloud/videointelligence_v1/services/video_intelligence_service/__init__.py b/google/cloud/videointelligence_v1/services/video_intelligence_service/__init__.py index 55932028..02e942f8 100644 --- a/google/cloud/videointelligence_v1/services/video_intelligence_service/__init__.py +++ b/google/cloud/videointelligence_v1/services/video_intelligence_service/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .client import VideoIntelligenceServiceClient from .async_client import VideoIntelligenceServiceAsyncClient diff --git a/google/cloud/videointelligence_v1/services/video_intelligence_service/async_client.py b/google/cloud/videointelligence_v1/services/video_intelligence_service/async_client.py index a0030e47..1e72bd8f 100644 --- a/google/cloud/videointelligence_v1/services/video_intelligence_service/async_client.py +++ b/google/cloud/videointelligence_v1/services/video_intelligence_service/async_client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict import functools import re @@ -22,16 +20,15 @@ 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 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 # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore from google.cloud.videointelligence_v1.types import video_intelligence - from .transports.base import VideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO from .transports.grpc_asyncio import VideoIntelligenceServiceGrpcAsyncIOTransport from .client import VideoIntelligenceServiceClient @@ -51,26 +48,22 @@ class VideoIntelligenceServiceAsyncClient: parse_common_billing_account_path = staticmethod( VideoIntelligenceServiceClient.parse_common_billing_account_path ) - common_folder_path = staticmethod(VideoIntelligenceServiceClient.common_folder_path) parse_common_folder_path = staticmethod( VideoIntelligenceServiceClient.parse_common_folder_path ) - common_organization_path = staticmethod( VideoIntelligenceServiceClient.common_organization_path ) parse_common_organization_path = staticmethod( VideoIntelligenceServiceClient.parse_common_organization_path ) - common_project_path = staticmethod( VideoIntelligenceServiceClient.common_project_path ) parse_common_project_path = staticmethod( VideoIntelligenceServiceClient.parse_common_project_path ) - common_location_path = staticmethod( VideoIntelligenceServiceClient.common_location_path ) @@ -80,7 +73,8 @@ class VideoIntelligenceServiceAsyncClient: @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -95,7 +89,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -112,7 +106,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> VideoIntelligenceServiceTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: VideoIntelligenceServiceTransport: The transport used by the client instance. @@ -127,12 +121,12 @@ def transport(self) -> VideoIntelligenceServiceTransport: def __init__( self, *, - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, transport: Union[str, VideoIntelligenceServiceTransport] = "grpc_asyncio", client_options: ClientOptions = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the video intelligence service client. + """Instantiates the video intelligence service client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -164,7 +158,6 @@ def __init__( google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport creation failed for any reason. """ - self._client = VideoIntelligenceServiceClient( credentials=credentials, transport=transport, @@ -217,7 +210,6 @@ async def annotate_video( This corresponds to the ``features`` 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. @@ -247,10 +239,8 @@ async def annotate_video( # If we have keyword arguments corresponding to fields on the # request, apply these. - if input_uri is not None: request.input_uri = input_uri - if features: request.features.extend(features) @@ -263,7 +253,8 @@ async def annotate_video( maximum=120.0, multiplier=2.5, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=600.0, ), diff --git a/google/cloud/videointelligence_v1/services/video_intelligence_service/client.py b/google/cloud/videointelligence_v1/services/video_intelligence_service/client.py index 38715885..11d7655d 100644 --- a/google/cloud/videointelligence_v1/services/video_intelligence_service/client.py +++ b/google/cloud/videointelligence_v1/services/video_intelligence_service/client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from distutils import util import os @@ -23,10 +21,10 @@ 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 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 # type: ignore +from google.auth import credentials as ga_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 @@ -35,7 +33,6 @@ from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore from google.cloud.videointelligence_v1.types import video_intelligence - from .transports.base import VideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO from .transports.grpc import VideoIntelligenceServiceGrpcTransport from .transports.grpc_asyncio import VideoIntelligenceServiceGrpcAsyncIOTransport @@ -58,7 +55,7 @@ class VideoIntelligenceServiceClientMeta(type): def get_transport_class( cls, label: str = None, ) -> Type[VideoIntelligenceServiceTransport]: - """Return an appropriate transport class. + """Returns an appropriate transport class. Args: label: The name of the desired transport. If none is @@ -81,7 +78,8 @@ class VideoIntelligenceServiceClient(metaclass=VideoIntelligenceServiceClientMet @staticmethod def _get_default_mtls_endpoint(api_endpoint): - """Convert api endpoint to mTLS endpoint. + """Converts api endpoint to mTLS endpoint. + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. Args: @@ -115,7 +113,8 @@ def _get_default_mtls_endpoint(api_endpoint): @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -132,7 +131,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -151,16 +150,17 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> VideoIntelligenceServiceTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: - VideoIntelligenceServiceTransport: The transport used by the client instance. + VideoIntelligenceServiceTransport: The transport used by the client + instance. """ return self._transport @staticmethod def common_billing_account_path(billing_account: str,) -> str: - """Return a fully-qualified billing_account string.""" + """Returns a fully-qualified billing_account string.""" return "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -173,7 +173,7 @@ def parse_common_billing_account_path(path: str) -> Dict[str, str]: @staticmethod def common_folder_path(folder: str,) -> str: - """Return a fully-qualified folder string.""" + """Returns a fully-qualified folder string.""" return "folders/{folder}".format(folder=folder,) @staticmethod @@ -184,7 +184,7 @@ def parse_common_folder_path(path: str) -> Dict[str, str]: @staticmethod def common_organization_path(organization: str,) -> str: - """Return a fully-qualified organization string.""" + """Returns a fully-qualified organization string.""" return "organizations/{organization}".format(organization=organization,) @staticmethod @@ -195,7 +195,7 @@ def parse_common_organization_path(path: str) -> Dict[str, str]: @staticmethod def common_project_path(project: str,) -> str: - """Return a fully-qualified project string.""" + """Returns a fully-qualified project string.""" return "projects/{project}".format(project=project,) @staticmethod @@ -206,7 +206,7 @@ def parse_common_project_path(path: str) -> Dict[str, str]: @staticmethod def common_location_path(project: str, location: str,) -> str: - """Return a fully-qualified location string.""" + """Returns a fully-qualified location string.""" return "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -220,12 +220,12 @@ def parse_common_location_path(path: str) -> Dict[str, str]: def __init__( self, *, - credentials: Optional[credentials.Credentials] = None, + credentials: Optional[ga_credentials.Credentials] = None, transport: Union[str, VideoIntelligenceServiceTransport, None] = None, client_options: Optional[client_options_lib.ClientOptions] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the video intelligence service client. + """Instantiates the video intelligence service client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -280,9 +280,10 @@ def __init__( 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 - ) + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None # Figure out which api endpoint to use. if client_options.api_endpoint is not None: @@ -294,12 +295,14 @@ def __init__( 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 - ) + if is_mtls: + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = self.DEFAULT_ENDPOINT else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" ) # Save or instantiate the transport. @@ -314,8 +317,8 @@ def __init__( ) if client_options.scopes: raise ValueError( - "When providing a transport instance, " - "provide its scopes directly." + "When providing a transport instance, provide its scopes " + "directly." ) self._transport = transport else: @@ -375,7 +378,6 @@ def annotate_video( This corresponds to the ``features`` 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. @@ -407,10 +409,8 @@ def annotate_video( # there are no flattened fields. if not isinstance(request, video_intelligence.AnnotateVideoRequest): request = video_intelligence.AnnotateVideoRequest(request) - # If we have keyword arguments corresponding to fields on the # request, apply these. - if input_uri is not None: request.input_uri = input_uri if features is not None: diff --git a/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/__init__.py b/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/__init__.py index fef86838..8ae3c6cb 100644 --- a/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/__init__.py +++ b/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from typing import Dict, Type diff --git a/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/base.py b/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/base.py index c0b9f3fd..faa00701 100644 --- a/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/base.py +++ b/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/base.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,21 +13,21 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import abc -import typing +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union +import packaging.version import pkg_resources -from google import auth # type: ignore -from google.api_core import exceptions # type: ignore +import google.auth # type: ignore +import google.api_core # 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.api_core import operations_v1 # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.cloud.videointelligence_v1.types import video_intelligence -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( @@ -39,27 +38,41 @@ 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 + +_API_CORE_VERSION = google.api_core.__version__ + class VideoIntelligenceServiceTransport(abc.ABC): """Abstract transport class for VideoIntelligenceService.""" AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + DEFAULT_HOST: str = "videointelligence.googleapis.com" + def __init__( self, *, - host: str = "videointelligence.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, + host: str = DEFAULT_HOST, + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: 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. + 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 @@ -68,7 +81,7 @@ def __init__( 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. + scopes (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): @@ -82,29 +95,76 @@ def __init__( host += ":443" self._host = host + scopes_kwargs = self._get_scopes_kwargs(self._host, scopes) + # Save the scopes. self._scopes = scopes or self.AUTH_SCOPES # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: - raise exceptions.DuplicateCredentialArgs( + raise core_exceptions.DuplicateCredentialArgs( "'credentials_file' and 'credentials' are mutually exclusive" ) if credentials_file is not None: - credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, **scopes_kwargs, quota_project_id=quota_project_id ) elif credentials is None: - credentials, _ = auth.default( - scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials + # TODO(busunkim): These two class methods are in the base transport + # to avoid duplicating code across the transport classes. These functions + # should be deleted once the minimum required versions of google-api-core + # and google-auth are 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 + + # TODO: Remove this function once google-api-core >= 1.26.0 is required + @classmethod + def _get_self_signed_jwt_kwargs( + cls, host: str, scopes: Optional[Sequence[str]] + ) -> Dict[str, Union[Optional[Sequence[str]], str]]: + """Returns kwargs to pass to grpc_helpers.create_channel depending on the google-api-core version""" + + self_signed_jwt_kwargs: Dict[str, Union[Optional[Sequence[str]], str]] = {} + + if _API_CORE_VERSION and ( + packaging.version.parse(_API_CORE_VERSION) + >= packaging.version.parse("1.26.0") + ): + self_signed_jwt_kwargs["default_scopes"] = cls.AUTH_SCOPES + self_signed_jwt_kwargs["scopes"] = scopes + self_signed_jwt_kwargs["default_host"] = cls.DEFAULT_HOST + else: + self_signed_jwt_kwargs["scopes"] = scopes or cls.AUTH_SCOPES + + return self_signed_jwt_kwargs + def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { @@ -115,7 +175,8 @@ def _prep_wrapped_messages(self, client_info): maximum=120.0, multiplier=2.5, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=600.0, ), @@ -132,9 +193,9 @@ def operations_client(self) -> operations_v1.OperationsClient: @property def annotate_video( self, - ) -> typing.Callable[ + ) -> Callable[ [video_intelligence.AnnotateVideoRequest], - typing.Union[operations.Operation, typing.Awaitable[operations.Operation]], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], ]: raise NotImplementedError() diff --git a/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/grpc.py b/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/grpc.py index 6d7952b9..2a55bf9d 100644 --- a/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/grpc.py +++ b/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/grpc.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,22 +13,20 @@ # 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 typing import Callable, Dict, Optional, Sequence, Tuple, Union from google.api_core import grpc_helpers # type: ignore from google.api_core import operations_v1 # type: ignore from google.api_core import gapic_v1 # type: ignore -from google import auth # type: ignore -from google.auth import credentials # type: ignore +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore import grpc # type: ignore from google.cloud.videointelligence_v1.types import video_intelligence -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore from .base import VideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO @@ -52,7 +49,7 @@ def __init__( self, *, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Sequence[str] = None, channel: grpc.Channel = None, @@ -66,7 +63,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + 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 @@ -177,7 +175,7 @@ def __init__( def create_channel( cls, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -208,13 +206,15 @@ def create_channel( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) @@ -241,7 +241,7 @@ def operations_client(self) -> operations_v1.OperationsClient: @property def annotate_video( self, - ) -> Callable[[video_intelligence.AnnotateVideoRequest], operations.Operation]: + ) -> Callable[[video_intelligence.AnnotateVideoRequest], operations_pb2.Operation]: r"""Return a callable for the annotate video method over gRPC. Performs asynchronous video annotation. Progress and results can @@ -264,7 +264,7 @@ def annotate_video( self._stubs["annotate_video"] = self.grpc_channel.unary_unary( "/google.cloud.videointelligence.v1.VideoIntelligenceService/AnnotateVideo", request_serializer=video_intelligence.AnnotateVideoRequest.serialize, - response_deserializer=operations.Operation.FromString, + response_deserializer=operations_pb2.Operation.FromString, ) return self._stubs["annotate_video"] diff --git a/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/grpc_asyncio.py b/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/grpc_asyncio.py index 0a957cf2..2ee0b180 100644 --- a/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/grpc_asyncio.py +++ b/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/grpc_asyncio.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,23 +13,21 @@ # 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 typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore -from google import auth # type: ignore -from google.auth import credentials # 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 from google.cloud.videointelligence_v1.types import video_intelligence -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore from .base import VideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO from .grpc import VideoIntelligenceServiceGrpcTransport @@ -55,7 +52,7 @@ class VideoIntelligenceServiceGrpcAsyncIOTransport(VideoIntelligenceServiceTrans def create_channel( cls, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -82,13 +79,15 @@ def create_channel( Returns: aio.Channel: A gRPC AsyncIO channel object. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers_async.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) @@ -96,7 +95,7 @@ def __init__( self, *, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, channel: aio.Channel = None, @@ -110,7 +109,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + 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 @@ -169,7 +169,6 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - else: if api_mtls_endpoint: host = api_mtls_endpoint @@ -248,7 +247,7 @@ def operations_client(self) -> operations_v1.OperationsAsyncClient: def annotate_video( self, ) -> Callable[ - [video_intelligence.AnnotateVideoRequest], Awaitable[operations.Operation] + [video_intelligence.AnnotateVideoRequest], Awaitable[operations_pb2.Operation] ]: r"""Return a callable for the annotate video method over gRPC. @@ -272,7 +271,7 @@ def annotate_video( self._stubs["annotate_video"] = self.grpc_channel.unary_unary( "/google.cloud.videointelligence.v1.VideoIntelligenceService/AnnotateVideo", request_serializer=video_intelligence.AnnotateVideoRequest.serialize, - response_deserializer=operations.Operation.FromString, + response_deserializer=operations_pb2.Operation.FromString, ) return self._stubs["annotate_video"] diff --git a/google/cloud/videointelligence_v1/types/__init__.py b/google/cloud/videointelligence_v1/types/__init__.py index 74505105..1e3503fa 100644 --- a/google/cloud/videointelligence_v1/types/__init__.py +++ b/google/cloud/videointelligence_v1/types/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .video_intelligence import ( AnnotateVideoProgress, AnnotateVideoRequest, diff --git a/google/cloud/videointelligence_v1/types/video_intelligence.py b/google/cloud/videointelligence_v1/types/video_intelligence.py index ece4d640..078f5f0c 100644 --- a/google/cloud/videointelligence_v1/types/video_intelligence.py +++ b/google/cloud/videointelligence_v1/types/video_intelligence.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,13 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore - -from google.protobuf import duration_pb2 as duration # type: ignore -from google.protobuf import timestamp_pb2 as timestamp # type: ignore -from google.rpc import status_pb2 as status # type: ignore +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( @@ -110,7 +107,6 @@ class Likelihood(proto.Enum): class AnnotateVideoRequest(proto.Message): r"""Video annotation request. - Attributes: input_uri (str): Input video location. Currently, only `Cloud @@ -151,22 +147,16 @@ class AnnotateVideoRequest(proto.Message): the region will be determined based on video file location. """ - input_uri = proto.Field(proto.STRING, number=1) - - input_content = proto.Field(proto.BYTES, number=6) - + input_uri = proto.Field(proto.STRING, number=1,) + input_content = proto.Field(proto.BYTES, number=6,) features = proto.RepeatedField(proto.ENUM, number=2, enum="Feature",) - video_context = proto.Field(proto.MESSAGE, number=3, message="VideoContext",) - - output_uri = proto.Field(proto.STRING, number=4) - - location_id = proto.Field(proto.STRING, number=5) + output_uri = proto.Field(proto.STRING, number=4,) + location_id = proto.Field(proto.STRING, number=5,) class VideoContext(proto.Message): r"""Video context and/or feature-specific parameters. - Attributes: segments (Sequence[google.cloud.videointelligence_v1.types.VideoSegment]): Video segments to annotate. The segments may @@ -192,35 +182,27 @@ class VideoContext(proto.Message): """ segments = proto.RepeatedField(proto.MESSAGE, number=1, message="VideoSegment",) - label_detection_config = proto.Field( proto.MESSAGE, number=2, message="LabelDetectionConfig", ) - shot_change_detection_config = proto.Field( proto.MESSAGE, number=3, message="ShotChangeDetectionConfig", ) - explicit_content_detection_config = proto.Field( proto.MESSAGE, number=4, message="ExplicitContentDetectionConfig", ) - face_detection_config = proto.Field( proto.MESSAGE, number=5, message="FaceDetectionConfig", ) - speech_transcription_config = proto.Field( proto.MESSAGE, number=6, message="SpeechTranscriptionConfig", ) - text_detection_config = proto.Field( proto.MESSAGE, number=8, message="TextDetectionConfig", ) - person_detection_config = proto.Field( proto.MESSAGE, number=11, message="PersonDetectionConfig", ) - object_tracking_config = proto.Field( proto.MESSAGE, number=13, message="ObjectTrackingConfig", ) @@ -228,7 +210,6 @@ class VideoContext(proto.Message): class LabelDetectionConfig(proto.Message): r"""Config for LABEL_DETECTION. - Attributes: label_detection_mode (google.cloud.videointelligence_v1.types.LabelDetectionMode): What labels should be detected with LABEL_DETECTION, in @@ -262,19 +243,14 @@ class LabelDetectionConfig(proto.Message): """ label_detection_mode = proto.Field(proto.ENUM, number=1, enum="LabelDetectionMode",) - - stationary_camera = proto.Field(proto.BOOL, number=2) - - model = proto.Field(proto.STRING, number=3) - - frame_confidence_threshold = proto.Field(proto.FLOAT, number=4) - - video_confidence_threshold = proto.Field(proto.FLOAT, number=5) + stationary_camera = proto.Field(proto.BOOL, number=2,) + model = proto.Field(proto.STRING, number=3,) + frame_confidence_threshold = proto.Field(proto.FLOAT, number=4,) + video_confidence_threshold = proto.Field(proto.FLOAT, number=5,) class ShotChangeDetectionConfig(proto.Message): r"""Config for SHOT_CHANGE_DETECTION. - Attributes: model (str): Model to use for shot change detection. @@ -282,12 +258,11 @@ class ShotChangeDetectionConfig(proto.Message): if unset) and "builtin/latest". """ - model = proto.Field(proto.STRING, number=1) + model = proto.Field(proto.STRING, number=1,) class ObjectTrackingConfig(proto.Message): r"""Config for OBJECT_TRACKING. - Attributes: model (str): Model to use for object tracking. @@ -295,12 +270,11 @@ class ObjectTrackingConfig(proto.Message): if unset) and "builtin/latest". """ - model = proto.Field(proto.STRING, number=1) + model = proto.Field(proto.STRING, number=1,) class FaceDetectionConfig(proto.Message): r"""Config for FACE_DETECTION. - Attributes: model (str): Model to use for face detection. @@ -315,16 +289,13 @@ class FaceDetectionConfig(proto.Message): 'include_bounding_boxes' is set to false. """ - model = proto.Field(proto.STRING, number=1) - - include_bounding_boxes = proto.Field(proto.BOOL, number=2) - - include_attributes = proto.Field(proto.BOOL, number=5) + model = proto.Field(proto.STRING, number=1,) + include_bounding_boxes = proto.Field(proto.BOOL, number=2,) + include_attributes = proto.Field(proto.BOOL, number=5,) class PersonDetectionConfig(proto.Message): r"""Config for PERSON_DETECTION. - Attributes: include_bounding_boxes (bool): Whether bounding boxes are included in the @@ -339,16 +310,13 @@ class PersonDetectionConfig(proto.Message): 'include_bounding_boxes' is set to false. """ - include_bounding_boxes = proto.Field(proto.BOOL, number=1) - - include_pose_landmarks = proto.Field(proto.BOOL, number=2) - - include_attributes = proto.Field(proto.BOOL, number=3) + include_bounding_boxes = proto.Field(proto.BOOL, number=1,) + include_pose_landmarks = proto.Field(proto.BOOL, number=2,) + include_attributes = proto.Field(proto.BOOL, number=3,) class ExplicitContentDetectionConfig(proto.Message): r"""Config for EXPLICIT_CONTENT_DETECTION. - Attributes: model (str): Model to use for explicit content detection. @@ -356,12 +324,11 @@ class ExplicitContentDetectionConfig(proto.Message): if unset) and "builtin/latest". """ - model = proto.Field(proto.STRING, number=1) + model = proto.Field(proto.STRING, number=1,) class TextDetectionConfig(proto.Message): r"""Config for TEXT_DETECTION. - Attributes: language_hints (Sequence[str]): Language hint can be specified if the @@ -378,14 +345,12 @@ class TextDetectionConfig(proto.Message): if unset) and "builtin/latest". """ - language_hints = proto.RepeatedField(proto.STRING, number=1) - - model = proto.Field(proto.STRING, number=2) + language_hints = proto.RepeatedField(proto.STRING, number=1,) + model = proto.Field(proto.STRING, number=2,) class VideoSegment(proto.Message): r"""Video segment. - Attributes: start_time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the @@ -397,14 +362,16 @@ class VideoSegment(proto.Message): (inclusive). """ - start_time_offset = proto.Field(proto.MESSAGE, number=1, message=duration.Duration,) - - end_time_offset = proto.Field(proto.MESSAGE, number=2, message=duration.Duration,) + start_time_offset = proto.Field( + proto.MESSAGE, number=1, message=duration_pb2.Duration, + ) + end_time_offset = proto.Field( + proto.MESSAGE, number=2, message=duration_pb2.Duration, + ) class LabelSegment(proto.Message): r"""Video segment level annotation results for label detection. - Attributes: segment (google.cloud.videointelligence_v1.types.VideoSegment): Video segment where a label was detected. @@ -413,13 +380,11 @@ class LabelSegment(proto.Message): """ segment = proto.Field(proto.MESSAGE, number=1, message="VideoSegment",) - - confidence = proto.Field(proto.FLOAT, number=2) + confidence = proto.Field(proto.FLOAT, number=2,) class LabelFrame(proto.Message): r"""Video frame level annotation results for label detection. - Attributes: time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the @@ -429,14 +394,12 @@ class LabelFrame(proto.Message): Confidence that the label is accurate. Range: [0, 1]. """ - time_offset = proto.Field(proto.MESSAGE, number=1, message=duration.Duration,) - - confidence = proto.Field(proto.FLOAT, number=2) + time_offset = proto.Field(proto.MESSAGE, number=1, message=duration_pb2.Duration,) + confidence = proto.Field(proto.FLOAT, number=2,) class Entity(proto.Message): r"""Detected entity from video analysis. - Attributes: entity_id (str): Opaque entity ID. Some IDs may be available in `Google @@ -448,16 +411,13 @@ class Entity(proto.Message): Language code for ``description`` in BCP-47 format. """ - entity_id = proto.Field(proto.STRING, number=1) - - description = proto.Field(proto.STRING, number=2) - - language_code = proto.Field(proto.STRING, number=3) + entity_id = proto.Field(proto.STRING, number=1,) + description = proto.Field(proto.STRING, number=2,) + language_code = proto.Field(proto.STRING, number=3,) class LabelAnnotation(proto.Message): r"""Label annotation. - Attributes: entity (google.cloud.videointelligence_v1.types.Entity): Detected entity. @@ -476,19 +436,14 @@ class LabelAnnotation(proto.Message): """ entity = proto.Field(proto.MESSAGE, number=1, message="Entity",) - category_entities = proto.RepeatedField(proto.MESSAGE, number=2, message="Entity",) - segments = proto.RepeatedField(proto.MESSAGE, number=3, message="LabelSegment",) - frames = proto.RepeatedField(proto.MESSAGE, number=4, message="LabelFrame",) - - version = proto.Field(proto.STRING, number=5) + version = proto.Field(proto.STRING, number=5,) class ExplicitContentFrame(proto.Message): r"""Video frame level annotation results for explicit content. - Attributes: time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the @@ -498,8 +453,7 @@ class ExplicitContentFrame(proto.Message): Likelihood of the pornography content.. """ - time_offset = proto.Field(proto.MESSAGE, number=1, message=duration.Duration,) - + time_offset = proto.Field(proto.MESSAGE, number=1, message=duration_pb2.Duration,) pornography_likelihood = proto.Field(proto.ENUM, number=2, enum="Likelihood",) @@ -519,8 +473,7 @@ class ExplicitContentAnnotation(proto.Message): frames = proto.RepeatedField( proto.MESSAGE, number=1, message="ExplicitContentFrame", ) - - version = proto.Field(proto.STRING, number=2) + version = proto.Field(proto.STRING, number=2,) class NormalizedBoundingBox(proto.Message): @@ -538,18 +491,14 @@ class NormalizedBoundingBox(proto.Message): Bottom Y coordinate. """ - left = proto.Field(proto.FLOAT, number=1) - - top = proto.Field(proto.FLOAT, number=2) - - right = proto.Field(proto.FLOAT, number=3) - - bottom = proto.Field(proto.FLOAT, number=4) + left = proto.Field(proto.FLOAT, number=1,) + top = proto.Field(proto.FLOAT, number=2,) + right = proto.Field(proto.FLOAT, number=3,) + bottom = proto.Field(proto.FLOAT, number=4,) class FaceDetectionAnnotation(proto.Message): r"""Face detection annotation. - Attributes: tracks (Sequence[google.cloud.videointelligence_v1.types.Track]): The face tracks with attributes. @@ -560,15 +509,12 @@ class FaceDetectionAnnotation(proto.Message): """ tracks = proto.RepeatedField(proto.MESSAGE, number=3, message="Track",) - - thumbnail = proto.Field(proto.BYTES, number=4) - - version = proto.Field(proto.STRING, number=5) + thumbnail = proto.Field(proto.BYTES, number=4,) + version = proto.Field(proto.STRING, number=5,) class PersonDetectionAnnotation(proto.Message): r"""Person detection annotation per video. - Attributes: tracks (Sequence[google.cloud.videointelligence_v1.types.Track]): The detected tracks of a person. @@ -577,13 +523,11 @@ class PersonDetectionAnnotation(proto.Message): """ tracks = proto.RepeatedField(proto.MESSAGE, number=1, message="Track",) - - version = proto.Field(proto.STRING, number=2) + version = proto.Field(proto.STRING, number=2,) class FaceSegment(proto.Message): r"""Video segment level annotation results for face detection. - Attributes: segment (google.cloud.videointelligence_v1.types.VideoSegment): Video segment where a face was detected. @@ -594,7 +538,6 @@ class FaceSegment(proto.Message): class FaceFrame(proto.Message): r"""Deprecated. No effect. - Attributes: normalized_bounding_boxes (Sequence[google.cloud.videointelligence_v1.types.NormalizedBoundingBox]): Normalized Bounding boxes in a frame. @@ -610,13 +553,11 @@ class FaceFrame(proto.Message): normalized_bounding_boxes = proto.RepeatedField( proto.MESSAGE, number=1, message="NormalizedBoundingBox", ) - - time_offset = proto.Field(proto.MESSAGE, number=2, message=duration.Duration,) + time_offset = proto.Field(proto.MESSAGE, number=2, message=duration_pb2.Duration,) class FaceAnnotation(proto.Message): r"""Deprecated. No effect. - Attributes: thumbnail (bytes): Thumbnail of a representative face view (in @@ -627,10 +568,8 @@ class FaceAnnotation(proto.Message): All video frames where a face was detected. """ - thumbnail = proto.Field(proto.BYTES, number=1) - + thumbnail = proto.Field(proto.BYTES, number=1,) segments = proto.RepeatedField(proto.MESSAGE, number=2, message="FaceSegment",) - frames = proto.RepeatedField(proto.MESSAGE, number=3, message="FaceFrame",) @@ -656,13 +595,10 @@ class TimestampedObject(proto.Message): normalized_bounding_box = proto.Field( proto.MESSAGE, number=1, message="NormalizedBoundingBox", ) - - time_offset = proto.Field(proto.MESSAGE, number=2, message=duration.Duration,) - + time_offset = proto.Field(proto.MESSAGE, number=2, message=duration_pb2.Duration,) attributes = proto.RepeatedField( proto.MESSAGE, number=3, message="DetectedAttribute", ) - landmarks = proto.RepeatedField( proto.MESSAGE, number=4, message="DetectedLandmark", ) @@ -670,7 +606,6 @@ class TimestampedObject(proto.Message): class Track(proto.Message): r"""A track of an object instance. - Attributes: segment (google.cloud.videointelligence_v1.types.VideoSegment): Video segment of a track. @@ -685,16 +620,13 @@ class Track(proto.Message): """ segment = proto.Field(proto.MESSAGE, number=1, message="VideoSegment",) - timestamped_objects = proto.RepeatedField( proto.MESSAGE, number=2, message="TimestampedObject", ) - attributes = proto.RepeatedField( proto.MESSAGE, number=3, message="DetectedAttribute", ) - - confidence = proto.Field(proto.FLOAT, number=4) + confidence = proto.Field(proto.FLOAT, number=4,) class DetectedAttribute(proto.Message): @@ -714,11 +646,9 @@ class DetectedAttribute(proto.Message): "black", "blonde", etc. """ - name = proto.Field(proto.STRING, number=1) - - confidence = proto.Field(proto.FLOAT, number=2) - - value = proto.Field(proto.STRING, number=3) + name = proto.Field(proto.STRING, number=1,) + confidence = proto.Field(proto.FLOAT, number=2,) + value = proto.Field(proto.STRING, number=3,) class DetectedLandmark(proto.Message): @@ -738,16 +668,13 @@ class DetectedLandmark(proto.Message): The confidence score of the detected landmark. Range [0, 1]. """ - name = proto.Field(proto.STRING, number=1) - + name = proto.Field(proto.STRING, number=1,) point = proto.Field(proto.MESSAGE, number=2, message="NormalizedVertex",) - - confidence = proto.Field(proto.FLOAT, number=3) + confidence = proto.Field(proto.FLOAT, number=3,) class VideoAnnotationResults(proto.Message): r"""Annotation results for a single video. - Attributes: input_uri (str): Video file location in `Cloud @@ -814,67 +741,51 @@ class VideoAnnotationResults(proto.Message): may fail. """ - input_uri = proto.Field(proto.STRING, number=1) - + input_uri = proto.Field(proto.STRING, number=1,) segment = proto.Field(proto.MESSAGE, number=10, message="VideoSegment",) - segment_label_annotations = proto.RepeatedField( proto.MESSAGE, number=2, message="LabelAnnotation", ) - segment_presence_label_annotations = proto.RepeatedField( proto.MESSAGE, number=23, message="LabelAnnotation", ) - shot_label_annotations = proto.RepeatedField( proto.MESSAGE, number=3, message="LabelAnnotation", ) - shot_presence_label_annotations = proto.RepeatedField( proto.MESSAGE, number=24, message="LabelAnnotation", ) - frame_label_annotations = proto.RepeatedField( proto.MESSAGE, number=4, message="LabelAnnotation", ) - face_annotations = proto.RepeatedField( proto.MESSAGE, number=5, message="FaceAnnotation", ) - face_detection_annotations = proto.RepeatedField( proto.MESSAGE, number=13, message="FaceDetectionAnnotation", ) - shot_annotations = proto.RepeatedField( proto.MESSAGE, number=6, message="VideoSegment", ) - explicit_annotation = proto.Field( proto.MESSAGE, number=7, message="ExplicitContentAnnotation", ) - speech_transcriptions = proto.RepeatedField( proto.MESSAGE, number=11, message="SpeechTranscription", ) - text_annotations = proto.RepeatedField( proto.MESSAGE, number=12, message="TextAnnotation", ) - object_annotations = proto.RepeatedField( proto.MESSAGE, number=14, message="ObjectTrackingAnnotation", ) - logo_recognition_annotations = proto.RepeatedField( proto.MESSAGE, number=19, message="LogoRecognitionAnnotation", ) - person_detection_annotations = proto.RepeatedField( proto.MESSAGE, number=20, message="PersonDetectionAnnotation", ) - - error = proto.Field(proto.MESSAGE, number=9, message=status.Status,) + error = proto.Field(proto.MESSAGE, number=9, message=status_pb2.Status,) class AnnotateVideoResponse(proto.Message): @@ -895,7 +806,6 @@ class AnnotateVideoResponse(proto.Message): class VideoAnnotationProgress(proto.Message): r"""Annotation progress for a single video. - Attributes: input_uri (str): Video file location in `Cloud @@ -915,16 +825,11 @@ class VideoAnnotationProgress(proto.Message): the request contains more than one segment. """ - input_uri = proto.Field(proto.STRING, number=1) - - progress_percent = proto.Field(proto.INT32, number=2) - - start_time = proto.Field(proto.MESSAGE, number=3, message=timestamp.Timestamp,) - - update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp.Timestamp,) - + input_uri = proto.Field(proto.STRING, number=1,) + progress_percent = proto.Field(proto.INT32, number=2,) + start_time = proto.Field(proto.MESSAGE, number=3, message=timestamp_pb2.Timestamp,) + update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp_pb2.Timestamp,) feature = proto.Field(proto.ENUM, number=5, enum="Feature",) - segment = proto.Field(proto.MESSAGE, number=6, message="VideoSegment",) @@ -946,7 +851,6 @@ class AnnotateVideoProgress(proto.Message): class SpeechTranscriptionConfig(proto.Message): r"""Config for SPEECH_TRANSCRIPTION. - Attributes: language_code (str): Required. *Required* The language of the supplied audio as a @@ -1006,25 +910,17 @@ class SpeechTranscriptionConfig(proto.Message): is ``false``. """ - language_code = proto.Field(proto.STRING, number=1) - - max_alternatives = proto.Field(proto.INT32, number=2) - - filter_profanity = proto.Field(proto.BOOL, number=3) - + language_code = proto.Field(proto.STRING, number=1,) + max_alternatives = proto.Field(proto.INT32, number=2,) + filter_profanity = proto.Field(proto.BOOL, number=3,) speech_contexts = proto.RepeatedField( proto.MESSAGE, number=4, message="SpeechContext", ) - - enable_automatic_punctuation = proto.Field(proto.BOOL, number=5) - - audio_tracks = proto.RepeatedField(proto.INT32, number=6) - - enable_speaker_diarization = proto.Field(proto.BOOL, number=7) - - diarization_speaker_count = proto.Field(proto.INT32, number=8) - - enable_word_confidence = proto.Field(proto.BOOL, number=9) + enable_automatic_punctuation = proto.Field(proto.BOOL, number=5,) + audio_tracks = proto.RepeatedField(proto.INT32, number=6,) + enable_speaker_diarization = proto.Field(proto.BOOL, number=7,) + diarization_speaker_count = proto.Field(proto.INT32, number=8,) + enable_word_confidence = proto.Field(proto.BOOL, number=9,) class SpeechContext(proto.Message): @@ -1043,7 +939,7 @@ class SpeechContext(proto.Message): limits `__. """ - phrases = proto.RepeatedField(proto.STRING, number=1) + phrases = proto.RepeatedField(proto.STRING, number=1,) class SpeechTranscription(proto.Message): @@ -1068,13 +964,11 @@ class SpeechTranscription(proto.Message): alternatives = proto.RepeatedField( proto.MESSAGE, number=1, message="SpeechRecognitionAlternative", ) - - language_code = proto.Field(proto.STRING, number=2) + language_code = proto.Field(proto.STRING, number=2,) class SpeechRecognitionAlternative(proto.Message): r"""Alternative hypotheses (a.k.a. n-best list). - Attributes: transcript (str): Transcript text representing the words that @@ -1094,10 +988,8 @@ class SpeechRecognitionAlternative(proto.Message): beginning of the audio. """ - transcript = proto.Field(proto.STRING, number=1) - - confidence = proto.Field(proto.FLOAT, number=2) - + transcript = proto.Field(proto.STRING, number=1,) + confidence = proto.Field(proto.FLOAT, number=2,) words = proto.RepeatedField(proto.MESSAGE, number=3, message="WordInfo",) @@ -1138,15 +1030,11 @@ class WordInfo(proto.Message): set if speaker diarization is enabled. """ - start_time = proto.Field(proto.MESSAGE, number=1, message=duration.Duration,) - - end_time = proto.Field(proto.MESSAGE, number=2, message=duration.Duration,) - - word = proto.Field(proto.STRING, number=3) - - confidence = proto.Field(proto.FLOAT, number=4) - - speaker_tag = proto.Field(proto.INT32, number=5) + start_time = proto.Field(proto.MESSAGE, number=1, message=duration_pb2.Duration,) + end_time = proto.Field(proto.MESSAGE, number=2, message=duration_pb2.Duration,) + word = proto.Field(proto.STRING, number=3,) + confidence = proto.Field(proto.FLOAT, number=4,) + speaker_tag = proto.Field(proto.INT32, number=5,) class NormalizedVertex(proto.Message): @@ -1161,9 +1049,8 @@ class NormalizedVertex(proto.Message): Y coordinate. """ - x = proto.Field(proto.FLOAT, number=1) - - y = proto.Field(proto.FLOAT, number=2) + x = proto.Field(proto.FLOAT, number=1,) + y = proto.Field(proto.FLOAT, number=2,) class NormalizedBoundingPoly(proto.Message): @@ -1190,7 +1077,6 @@ class NormalizedBoundingPoly(proto.Message): class TextSegment(proto.Message): r"""Video segment level annotation results for text detection. - Attributes: segment (google.cloud.videointelligence_v1.types.VideoSegment): Video segment where a text snippet was @@ -1205,9 +1091,7 @@ class TextSegment(proto.Message): """ segment = proto.Field(proto.MESSAGE, number=1, message="VideoSegment",) - - confidence = proto.Field(proto.FLOAT, number=2) - + confidence = proto.Field(proto.FLOAT, number=2,) frames = proto.RepeatedField(proto.MESSAGE, number=3, message="TextFrame",) @@ -1227,8 +1111,7 @@ class TextFrame(proto.Message): rotated_bounding_box = proto.Field( proto.MESSAGE, number=1, message="NormalizedBoundingPoly", ) - - time_offset = proto.Field(proto.MESSAGE, number=2, message=duration.Duration,) + time_offset = proto.Field(proto.MESSAGE, number=2, message=duration_pb2.Duration,) class TextAnnotation(proto.Message): @@ -1246,11 +1129,9 @@ class TextAnnotation(proto.Message): Feature version. """ - text = proto.Field(proto.STRING, number=1) - + text = proto.Field(proto.STRING, number=1,) segments = proto.RepeatedField(proto.MESSAGE, number=2, message="TextSegment",) - - version = proto.Field(proto.STRING, number=3) + version = proto.Field(proto.STRING, number=3,) class ObjectTrackingFrame(proto.Message): @@ -1269,13 +1150,11 @@ class ObjectTrackingFrame(proto.Message): normalized_bounding_box = proto.Field( proto.MESSAGE, number=1, message="NormalizedBoundingBox", ) - - time_offset = proto.Field(proto.MESSAGE, number=2, message=duration.Duration,) + time_offset = proto.Field(proto.MESSAGE, number=2, message=duration_pb2.Duration,) class ObjectTrackingAnnotation(proto.Message): r"""Annotations corresponding to one tracked object. - Attributes: segment (google.cloud.videointelligence_v1.types.VideoSegment): Non-streaming batch mode ONLY. @@ -1308,18 +1187,13 @@ class ObjectTrackingAnnotation(proto.Message): segment = proto.Field( proto.MESSAGE, number=3, oneof="track_info", message="VideoSegment", ) - - track_id = proto.Field(proto.INT64, number=5, oneof="track_info") - + track_id = proto.Field(proto.INT64, number=5, oneof="track_info",) entity = proto.Field(proto.MESSAGE, number=1, message="Entity",) - - confidence = proto.Field(proto.FLOAT, number=4) - + confidence = proto.Field(proto.FLOAT, number=4,) frames = proto.RepeatedField( proto.MESSAGE, number=2, message="ObjectTrackingFrame", ) - - version = proto.Field(proto.STRING, number=6) + version = proto.Field(proto.STRING, number=6,) class LogoRecognitionAnnotation(proto.Message): @@ -1343,9 +1217,7 @@ class LogoRecognitionAnnotation(proto.Message): """ entity = proto.Field(proto.MESSAGE, number=1, message="Entity",) - tracks = proto.RepeatedField(proto.MESSAGE, number=2, message="Track",) - segments = proto.RepeatedField(proto.MESSAGE, number=3, message="VideoSegment",) diff --git a/google/cloud/videointelligence_v1beta2/__init__.py b/google/cloud/videointelligence_v1beta2/__init__.py index af876851..e31bf9ef 100644 --- a/google/cloud/videointelligence_v1beta2/__init__.py +++ b/google/cloud/videointelligence_v1beta2/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,6 +15,8 @@ # from .services.video_intelligence_service import VideoIntelligenceServiceClient +from .services.video_intelligence_service import VideoIntelligenceServiceAsyncClient + from .types.video_intelligence import AnnotateVideoProgress from .types.video_intelligence import AnnotateVideoRequest from .types.video_intelligence import AnnotateVideoResponse @@ -27,22 +28,22 @@ from .types.video_intelligence import FaceDetectionConfig from .types.video_intelligence import FaceFrame from .types.video_intelligence import FaceSegment -from .types.video_intelligence import Feature from .types.video_intelligence import LabelAnnotation from .types.video_intelligence import LabelDetectionConfig -from .types.video_intelligence import LabelDetectionMode from .types.video_intelligence import LabelFrame from .types.video_intelligence import LabelSegment -from .types.video_intelligence import Likelihood from .types.video_intelligence import NormalizedBoundingBox from .types.video_intelligence import ShotChangeDetectionConfig from .types.video_intelligence import VideoAnnotationProgress from .types.video_intelligence import VideoAnnotationResults from .types.video_intelligence import VideoContext from .types.video_intelligence import VideoSegment - +from .types.video_intelligence import Feature +from .types.video_intelligence import LabelDetectionMode +from .types.video_intelligence import Likelihood __all__ = ( + "VideoIntelligenceServiceAsyncClient", "AnnotateVideoProgress", "AnnotateVideoRequest", "AnnotateVideoResponse", @@ -66,6 +67,6 @@ "VideoAnnotationProgress", "VideoAnnotationResults", "VideoContext", - "VideoSegment", "VideoIntelligenceServiceClient", + "VideoSegment", ) diff --git a/google/cloud/videointelligence_v1beta2/gapic_metadata.json b/google/cloud/videointelligence_v1beta2/gapic_metadata.json new file mode 100644 index 00000000..478a3473 --- /dev/null +++ b/google/cloud/videointelligence_v1beta2/gapic_metadata.json @@ -0,0 +1,33 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.cloud.videointelligence_v1beta2", + "protoPackage": "google.cloud.videointelligence.v1beta2", + "schema": "1.0", + "services": { + "VideoIntelligenceService": { + "clients": { + "grpc": { + "libraryClient": "VideoIntelligenceServiceClient", + "rpcs": { + "AnnotateVideo": { + "methods": [ + "annotate_video" + ] + } + } + }, + "grpc-async": { + "libraryClient": "VideoIntelligenceServiceAsyncClient", + "rpcs": { + "AnnotateVideo": { + "methods": [ + "annotate_video" + ] + } + } + } + } + } + } +} diff --git a/google/cloud/videointelligence_v1beta2/services/__init__.py b/google/cloud/videointelligence_v1beta2/services/__init__.py index 42ffdf2b..4de65971 100644 --- a/google/cloud/videointelligence_v1beta2/services/__init__.py +++ b/google/cloud/videointelligence_v1beta2/services/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/__init__.py b/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/__init__.py index 55932028..02e942f8 100644 --- a/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/__init__.py +++ b/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .client import VideoIntelligenceServiceClient from .async_client import VideoIntelligenceServiceAsyncClient diff --git a/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/async_client.py b/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/async_client.py index 1f2e51e0..dafe7b7c 100644 --- a/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/async_client.py +++ b/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/async_client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict import functools import re @@ -22,16 +20,15 @@ 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 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 # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore from google.cloud.videointelligence_v1beta2.types import video_intelligence - from .transports.base import VideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO from .transports.grpc_asyncio import VideoIntelligenceServiceGrpcAsyncIOTransport from .client import VideoIntelligenceServiceClient @@ -51,26 +48,22 @@ class VideoIntelligenceServiceAsyncClient: parse_common_billing_account_path = staticmethod( VideoIntelligenceServiceClient.parse_common_billing_account_path ) - common_folder_path = staticmethod(VideoIntelligenceServiceClient.common_folder_path) parse_common_folder_path = staticmethod( VideoIntelligenceServiceClient.parse_common_folder_path ) - common_organization_path = staticmethod( VideoIntelligenceServiceClient.common_organization_path ) parse_common_organization_path = staticmethod( VideoIntelligenceServiceClient.parse_common_organization_path ) - common_project_path = staticmethod( VideoIntelligenceServiceClient.common_project_path ) parse_common_project_path = staticmethod( VideoIntelligenceServiceClient.parse_common_project_path ) - common_location_path = staticmethod( VideoIntelligenceServiceClient.common_location_path ) @@ -80,7 +73,8 @@ class VideoIntelligenceServiceAsyncClient: @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -95,7 +89,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -112,7 +106,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> VideoIntelligenceServiceTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: VideoIntelligenceServiceTransport: The transport used by the client instance. @@ -127,12 +121,12 @@ def transport(self) -> VideoIntelligenceServiceTransport: def __init__( self, *, - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, transport: Union[str, VideoIntelligenceServiceTransport] = "grpc_asyncio", client_options: ClientOptions = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the video intelligence service client. + """Instantiates the video intelligence service client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -164,7 +158,6 @@ def __init__( google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport creation failed for any reason. """ - self._client = VideoIntelligenceServiceClient( credentials=credentials, transport=transport, @@ -217,7 +210,6 @@ async def annotate_video( This corresponds to the ``features`` 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. @@ -247,10 +239,8 @@ async def annotate_video( # If we have keyword arguments corresponding to fields on the # request, apply these. - if input_uri is not None: request.input_uri = input_uri - if features: request.features.extend(features) @@ -263,7 +253,8 @@ async def annotate_video( maximum=120.0, multiplier=2.5, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=600.0, ), diff --git a/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/client.py b/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/client.py index 39bf203e..a071b42e 100644 --- a/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/client.py +++ b/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from distutils import util import os @@ -23,10 +21,10 @@ 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 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 # type: ignore +from google.auth import credentials as ga_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 @@ -35,7 +33,6 @@ from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore from google.cloud.videointelligence_v1beta2.types import video_intelligence - from .transports.base import VideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO from .transports.grpc import VideoIntelligenceServiceGrpcTransport from .transports.grpc_asyncio import VideoIntelligenceServiceGrpcAsyncIOTransport @@ -58,7 +55,7 @@ class VideoIntelligenceServiceClientMeta(type): def get_transport_class( cls, label: str = None, ) -> Type[VideoIntelligenceServiceTransport]: - """Return an appropriate transport class. + """Returns an appropriate transport class. Args: label: The name of the desired transport. If none is @@ -81,7 +78,8 @@ class VideoIntelligenceServiceClient(metaclass=VideoIntelligenceServiceClientMet @staticmethod def _get_default_mtls_endpoint(api_endpoint): - """Convert api endpoint to mTLS endpoint. + """Converts api endpoint to mTLS endpoint. + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. Args: @@ -115,7 +113,8 @@ def _get_default_mtls_endpoint(api_endpoint): @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -132,7 +131,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -151,16 +150,17 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> VideoIntelligenceServiceTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: - VideoIntelligenceServiceTransport: The transport used by the client instance. + VideoIntelligenceServiceTransport: The transport used by the client + instance. """ return self._transport @staticmethod def common_billing_account_path(billing_account: str,) -> str: - """Return a fully-qualified billing_account string.""" + """Returns a fully-qualified billing_account string.""" return "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -173,7 +173,7 @@ def parse_common_billing_account_path(path: str) -> Dict[str, str]: @staticmethod def common_folder_path(folder: str,) -> str: - """Return a fully-qualified folder string.""" + """Returns a fully-qualified folder string.""" return "folders/{folder}".format(folder=folder,) @staticmethod @@ -184,7 +184,7 @@ def parse_common_folder_path(path: str) -> Dict[str, str]: @staticmethod def common_organization_path(organization: str,) -> str: - """Return a fully-qualified organization string.""" + """Returns a fully-qualified organization string.""" return "organizations/{organization}".format(organization=organization,) @staticmethod @@ -195,7 +195,7 @@ def parse_common_organization_path(path: str) -> Dict[str, str]: @staticmethod def common_project_path(project: str,) -> str: - """Return a fully-qualified project string.""" + """Returns a fully-qualified project string.""" return "projects/{project}".format(project=project,) @staticmethod @@ -206,7 +206,7 @@ def parse_common_project_path(path: str) -> Dict[str, str]: @staticmethod def common_location_path(project: str, location: str,) -> str: - """Return a fully-qualified location string.""" + """Returns a fully-qualified location string.""" return "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -220,12 +220,12 @@ def parse_common_location_path(path: str) -> Dict[str, str]: def __init__( self, *, - credentials: Optional[credentials.Credentials] = None, + credentials: Optional[ga_credentials.Credentials] = None, transport: Union[str, VideoIntelligenceServiceTransport, None] = None, client_options: Optional[client_options_lib.ClientOptions] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the video intelligence service client. + """Instantiates the video intelligence service client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -280,9 +280,10 @@ def __init__( 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 - ) + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None # Figure out which api endpoint to use. if client_options.api_endpoint is not None: @@ -294,12 +295,14 @@ def __init__( 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 - ) + if is_mtls: + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = self.DEFAULT_ENDPOINT else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" ) # Save or instantiate the transport. @@ -314,8 +317,8 @@ def __init__( ) if client_options.scopes: raise ValueError( - "When providing a transport instance, " - "provide its scopes directly." + "When providing a transport instance, provide its scopes " + "directly." ) self._transport = transport else: @@ -375,7 +378,6 @@ def annotate_video( This corresponds to the ``features`` 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. @@ -407,10 +409,8 @@ def annotate_video( # there are no flattened fields. if not isinstance(request, video_intelligence.AnnotateVideoRequest): request = video_intelligence.AnnotateVideoRequest(request) - # If we have keyword arguments corresponding to fields on the # request, apply these. - if input_uri is not None: request.input_uri = input_uri if features is not None: diff --git a/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/__init__.py b/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/__init__.py index fef86838..8ae3c6cb 100644 --- a/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/__init__.py +++ b/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from typing import Dict, Type diff --git a/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/base.py b/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/base.py index f62c9607..0e37d2e4 100644 --- a/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/base.py +++ b/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/base.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,21 +13,21 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import abc -import typing +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union +import packaging.version import pkg_resources -from google import auth # type: ignore -from google.api_core import exceptions # type: ignore +import google.auth # type: ignore +import google.api_core # 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.api_core import operations_v1 # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.cloud.videointelligence_v1beta2.types import video_intelligence -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( @@ -39,27 +38,41 @@ 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 + +_API_CORE_VERSION = google.api_core.__version__ + class VideoIntelligenceServiceTransport(abc.ABC): """Abstract transport class for VideoIntelligenceService.""" AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + DEFAULT_HOST: str = "videointelligence.googleapis.com" + def __init__( self, *, - host: str = "videointelligence.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, + host: str = DEFAULT_HOST, + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: 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. + 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 @@ -68,7 +81,7 @@ def __init__( 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. + scopes (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): @@ -82,29 +95,76 @@ def __init__( host += ":443" self._host = host + scopes_kwargs = self._get_scopes_kwargs(self._host, scopes) + # Save the scopes. self._scopes = scopes or self.AUTH_SCOPES # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: - raise exceptions.DuplicateCredentialArgs( + raise core_exceptions.DuplicateCredentialArgs( "'credentials_file' and 'credentials' are mutually exclusive" ) if credentials_file is not None: - credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, **scopes_kwargs, quota_project_id=quota_project_id ) elif credentials is None: - credentials, _ = auth.default( - scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials + # TODO(busunkim): These two class methods are in the base transport + # to avoid duplicating code across the transport classes. These functions + # should be deleted once the minimum required versions of google-api-core + # and google-auth are 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 + + # TODO: Remove this function once google-api-core >= 1.26.0 is required + @classmethod + def _get_self_signed_jwt_kwargs( + cls, host: str, scopes: Optional[Sequence[str]] + ) -> Dict[str, Union[Optional[Sequence[str]], str]]: + """Returns kwargs to pass to grpc_helpers.create_channel depending on the google-api-core version""" + + self_signed_jwt_kwargs: Dict[str, Union[Optional[Sequence[str]], str]] = {} + + if _API_CORE_VERSION and ( + packaging.version.parse(_API_CORE_VERSION) + >= packaging.version.parse("1.26.0") + ): + self_signed_jwt_kwargs["default_scopes"] = cls.AUTH_SCOPES + self_signed_jwt_kwargs["scopes"] = scopes + self_signed_jwt_kwargs["default_host"] = cls.DEFAULT_HOST + else: + self_signed_jwt_kwargs["scopes"] = scopes or cls.AUTH_SCOPES + + return self_signed_jwt_kwargs + def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { @@ -115,7 +175,8 @@ def _prep_wrapped_messages(self, client_info): maximum=120.0, multiplier=2.5, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=600.0, ), @@ -132,9 +193,9 @@ def operations_client(self) -> operations_v1.OperationsClient: @property def annotate_video( self, - ) -> typing.Callable[ + ) -> Callable[ [video_intelligence.AnnotateVideoRequest], - typing.Union[operations.Operation, typing.Awaitable[operations.Operation]], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], ]: raise NotImplementedError() diff --git a/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/grpc.py b/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/grpc.py index 5a96ff22..2bda9afc 100644 --- a/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/grpc.py +++ b/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/grpc.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,22 +13,20 @@ # 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 typing import Callable, Dict, Optional, Sequence, Tuple, Union from google.api_core import grpc_helpers # type: ignore from google.api_core import operations_v1 # type: ignore from google.api_core import gapic_v1 # type: ignore -from google import auth # type: ignore -from google.auth import credentials # type: ignore +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore import grpc # type: ignore from google.cloud.videointelligence_v1beta2.types import video_intelligence -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore from .base import VideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO @@ -52,7 +49,7 @@ def __init__( self, *, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Sequence[str] = None, channel: grpc.Channel = None, @@ -66,7 +63,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + 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 @@ -177,7 +175,7 @@ def __init__( def create_channel( cls, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -208,13 +206,15 @@ def create_channel( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) @@ -241,7 +241,7 @@ def operations_client(self) -> operations_v1.OperationsClient: @property def annotate_video( self, - ) -> Callable[[video_intelligence.AnnotateVideoRequest], operations.Operation]: + ) -> Callable[[video_intelligence.AnnotateVideoRequest], operations_pb2.Operation]: r"""Return a callable for the annotate video method over gRPC. Performs asynchronous video annotation. Progress and results can @@ -264,7 +264,7 @@ def annotate_video( self._stubs["annotate_video"] = self.grpc_channel.unary_unary( "/google.cloud.videointelligence.v1beta2.VideoIntelligenceService/AnnotateVideo", request_serializer=video_intelligence.AnnotateVideoRequest.serialize, - response_deserializer=operations.Operation.FromString, + response_deserializer=operations_pb2.Operation.FromString, ) return self._stubs["annotate_video"] diff --git a/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/grpc_asyncio.py b/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/grpc_asyncio.py index 955e7852..44ecfe92 100644 --- a/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/grpc_asyncio.py +++ b/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/grpc_asyncio.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,23 +13,21 @@ # 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 typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore -from google import auth # type: ignore -from google.auth import credentials # 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 from google.cloud.videointelligence_v1beta2.types import video_intelligence -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore from .base import VideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO from .grpc import VideoIntelligenceServiceGrpcTransport @@ -55,7 +52,7 @@ class VideoIntelligenceServiceGrpcAsyncIOTransport(VideoIntelligenceServiceTrans def create_channel( cls, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -82,13 +79,15 @@ def create_channel( Returns: aio.Channel: A gRPC AsyncIO channel object. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers_async.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) @@ -96,7 +95,7 @@ def __init__( self, *, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, channel: aio.Channel = None, @@ -110,7 +109,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + 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 @@ -169,7 +169,6 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - else: if api_mtls_endpoint: host = api_mtls_endpoint @@ -248,7 +247,7 @@ def operations_client(self) -> operations_v1.OperationsAsyncClient: def annotate_video( self, ) -> Callable[ - [video_intelligence.AnnotateVideoRequest], Awaitable[operations.Operation] + [video_intelligence.AnnotateVideoRequest], Awaitable[operations_pb2.Operation] ]: r"""Return a callable for the annotate video method over gRPC. @@ -272,7 +271,7 @@ def annotate_video( self._stubs["annotate_video"] = self.grpc_channel.unary_unary( "/google.cloud.videointelligence.v1beta2.VideoIntelligenceService/AnnotateVideo", request_serializer=video_intelligence.AnnotateVideoRequest.serialize, - response_deserializer=operations.Operation.FromString, + response_deserializer=operations_pb2.Operation.FromString, ) return self._stubs["annotate_video"] diff --git a/google/cloud/videointelligence_v1beta2/types/__init__.py b/google/cloud/videointelligence_v1beta2/types/__init__.py index 72f210f3..a5858e61 100644 --- a/google/cloud/videointelligence_v1beta2/types/__init__.py +++ b/google/cloud/videointelligence_v1beta2/types/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .video_intelligence import ( AnnotateVideoProgress, AnnotateVideoRequest, diff --git a/google/cloud/videointelligence_v1beta2/types/video_intelligence.py b/google/cloud/videointelligence_v1beta2/types/video_intelligence.py index 1872665a..fb2d38e8 100644 --- a/google/cloud/videointelligence_v1beta2/types/video_intelligence.py +++ b/google/cloud/videointelligence_v1beta2/types/video_intelligence.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,13 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore - -from google.protobuf import duration_pb2 as duration # type: ignore -from google.protobuf import timestamp_pb2 as timestamp # type: ignore -from google.rpc import status_pb2 as status # type: ignore +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( @@ -83,7 +80,6 @@ class Likelihood(proto.Enum): class AnnotateVideoRequest(proto.Message): r"""Video annotation request. - Attributes: input_uri (str): Input video location. Currently, only `Google Cloud @@ -125,22 +121,16 @@ class AnnotateVideoRequest(proto.Message): a region will be determined based on video file location. """ - input_uri = proto.Field(proto.STRING, number=1) - - input_content = proto.Field(proto.BYTES, number=6) - + input_uri = proto.Field(proto.STRING, number=1,) + input_content = proto.Field(proto.BYTES, number=6,) features = proto.RepeatedField(proto.ENUM, number=2, enum="Feature",) - video_context = proto.Field(proto.MESSAGE, number=3, message="VideoContext",) - - output_uri = proto.Field(proto.STRING, number=4) - - location_id = proto.Field(proto.STRING, number=5) + output_uri = proto.Field(proto.STRING, number=4,) + location_id = proto.Field(proto.STRING, number=5,) class VideoContext(proto.Message): r"""Video context and/or feature-specific parameters. - Attributes: segments (Sequence[google.cloud.videointelligence_v1beta2.types.VideoSegment]): Video segments to annotate. The segments may @@ -158,19 +148,15 @@ class VideoContext(proto.Message): """ segments = proto.RepeatedField(proto.MESSAGE, number=1, message="VideoSegment",) - label_detection_config = proto.Field( proto.MESSAGE, number=2, message="LabelDetectionConfig", ) - shot_change_detection_config = proto.Field( proto.MESSAGE, number=3, message="ShotChangeDetectionConfig", ) - explicit_content_detection_config = proto.Field( proto.MESSAGE, number=4, message="ExplicitContentDetectionConfig", ) - face_detection_config = proto.Field( proto.MESSAGE, number=5, message="FaceDetectionConfig", ) @@ -178,7 +164,6 @@ class VideoContext(proto.Message): class LabelDetectionConfig(proto.Message): r"""Config for LABEL_DETECTION. - Attributes: label_detection_mode (google.cloud.videointelligence_v1beta2.types.LabelDetectionMode): What labels should be detected with LABEL_DETECTION, in @@ -196,15 +181,12 @@ class LabelDetectionConfig(proto.Message): """ label_detection_mode = proto.Field(proto.ENUM, number=1, enum="LabelDetectionMode",) - - stationary_camera = proto.Field(proto.BOOL, number=2) - - model = proto.Field(proto.STRING, number=3) + stationary_camera = proto.Field(proto.BOOL, number=2,) + model = proto.Field(proto.STRING, number=3,) class ShotChangeDetectionConfig(proto.Message): r"""Config for SHOT_CHANGE_DETECTION. - Attributes: model (str): Model to use for shot change detection. @@ -212,12 +194,11 @@ class ShotChangeDetectionConfig(proto.Message): if unset) and "builtin/latest". """ - model = proto.Field(proto.STRING, number=1) + model = proto.Field(proto.STRING, number=1,) class ExplicitContentDetectionConfig(proto.Message): r"""Config for EXPLICIT_CONTENT_DETECTION. - Attributes: model (str): Model to use for explicit content detection. @@ -225,12 +206,11 @@ class ExplicitContentDetectionConfig(proto.Message): if unset) and "builtin/latest". """ - model = proto.Field(proto.STRING, number=1) + model = proto.Field(proto.STRING, number=1,) class FaceDetectionConfig(proto.Message): r"""Config for FACE_DETECTION. - Attributes: model (str): Model to use for face detection. @@ -241,14 +221,12 @@ class FaceDetectionConfig(proto.Message): face annotation output. """ - model = proto.Field(proto.STRING, number=1) - - include_bounding_boxes = proto.Field(proto.BOOL, number=2) + model = proto.Field(proto.STRING, number=1,) + include_bounding_boxes = proto.Field(proto.BOOL, number=2,) class VideoSegment(proto.Message): r"""Video segment. - Attributes: start_time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the @@ -260,14 +238,16 @@ class VideoSegment(proto.Message): (inclusive). """ - start_time_offset = proto.Field(proto.MESSAGE, number=1, message=duration.Duration,) - - end_time_offset = proto.Field(proto.MESSAGE, number=2, message=duration.Duration,) + start_time_offset = proto.Field( + proto.MESSAGE, number=1, message=duration_pb2.Duration, + ) + end_time_offset = proto.Field( + proto.MESSAGE, number=2, message=duration_pb2.Duration, + ) class LabelSegment(proto.Message): r"""Video segment level annotation results for label detection. - Attributes: segment (google.cloud.videointelligence_v1beta2.types.VideoSegment): Video segment where a label was detected. @@ -276,13 +256,11 @@ class LabelSegment(proto.Message): """ segment = proto.Field(proto.MESSAGE, number=1, message="VideoSegment",) - - confidence = proto.Field(proto.FLOAT, number=2) + confidence = proto.Field(proto.FLOAT, number=2,) class LabelFrame(proto.Message): r"""Video frame level annotation results for label detection. - Attributes: time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the @@ -292,14 +270,12 @@ class LabelFrame(proto.Message): Confidence that the label is accurate. Range: [0, 1]. """ - time_offset = proto.Field(proto.MESSAGE, number=1, message=duration.Duration,) - - confidence = proto.Field(proto.FLOAT, number=2) + time_offset = proto.Field(proto.MESSAGE, number=1, message=duration_pb2.Duration,) + confidence = proto.Field(proto.FLOAT, number=2,) class Entity(proto.Message): r"""Detected entity from video analysis. - Attributes: entity_id (str): Opaque entity ID. Some IDs may be available in `Google @@ -311,16 +287,13 @@ class Entity(proto.Message): Language code for ``description`` in BCP-47 format. """ - entity_id = proto.Field(proto.STRING, number=1) - - description = proto.Field(proto.STRING, number=2) - - language_code = proto.Field(proto.STRING, number=3) + entity_id = proto.Field(proto.STRING, number=1,) + description = proto.Field(proto.STRING, number=2,) + language_code = proto.Field(proto.STRING, number=3,) class LabelAnnotation(proto.Message): r"""Label annotation. - Attributes: entity (google.cloud.videointelligence_v1beta2.types.Entity): Detected entity. @@ -337,17 +310,13 @@ class LabelAnnotation(proto.Message): """ entity = proto.Field(proto.MESSAGE, number=1, message="Entity",) - category_entities = proto.RepeatedField(proto.MESSAGE, number=2, message="Entity",) - segments = proto.RepeatedField(proto.MESSAGE, number=3, message="LabelSegment",) - frames = proto.RepeatedField(proto.MESSAGE, number=4, message="LabelFrame",) class ExplicitContentFrame(proto.Message): r"""Video frame level annotation results for explicit content. - Attributes: time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the @@ -357,8 +326,7 @@ class ExplicitContentFrame(proto.Message): Likelihood of the pornography content.. """ - time_offset = proto.Field(proto.MESSAGE, number=1, message=duration.Duration,) - + time_offset = proto.Field(proto.MESSAGE, number=1, message=duration_pb2.Duration,) pornography_likelihood = proto.Field(proto.ENUM, number=2, enum="Likelihood",) @@ -393,18 +361,14 @@ class NormalizedBoundingBox(proto.Message): Bottom Y coordinate. """ - left = proto.Field(proto.FLOAT, number=1) - - top = proto.Field(proto.FLOAT, number=2) - - right = proto.Field(proto.FLOAT, number=3) - - bottom = proto.Field(proto.FLOAT, number=4) + left = proto.Field(proto.FLOAT, number=1,) + top = proto.Field(proto.FLOAT, number=2,) + right = proto.Field(proto.FLOAT, number=3,) + bottom = proto.Field(proto.FLOAT, number=4,) class FaceSegment(proto.Message): r"""Video segment level annotation results for face detection. - Attributes: segment (google.cloud.videointelligence_v1beta2.types.VideoSegment): Video segment where a face was detected. @@ -415,7 +379,6 @@ class FaceSegment(proto.Message): class FaceFrame(proto.Message): r"""Video frame level annotation results for face detection. - Attributes: normalized_bounding_boxes (Sequence[google.cloud.videointelligence_v1beta2.types.NormalizedBoundingBox]): Normalized Bounding boxes in a frame. @@ -431,13 +394,11 @@ class FaceFrame(proto.Message): normalized_bounding_boxes = proto.RepeatedField( proto.MESSAGE, number=1, message="NormalizedBoundingBox", ) - - time_offset = proto.Field(proto.MESSAGE, number=2, message=duration.Duration,) + time_offset = proto.Field(proto.MESSAGE, number=2, message=duration_pb2.Duration,) class FaceAnnotation(proto.Message): r"""Face annotation. - Attributes: thumbnail (bytes): Thumbnail of a representative face view (in @@ -448,16 +409,13 @@ class FaceAnnotation(proto.Message): All video frames where a face was detected. """ - thumbnail = proto.Field(proto.BYTES, number=1) - + thumbnail = proto.Field(proto.BYTES, number=1,) segments = proto.RepeatedField(proto.MESSAGE, number=2, message="FaceSegment",) - frames = proto.RepeatedField(proto.MESSAGE, number=3, message="FaceFrame",) class VideoAnnotationResults(proto.Message): r"""Annotation results for a single video. - Attributes: input_uri (str): Video file location in `Google Cloud @@ -488,33 +446,26 @@ class VideoAnnotationResults(proto.Message): may fail. """ - input_uri = proto.Field(proto.STRING, number=1) - + input_uri = proto.Field(proto.STRING, number=1,) segment_label_annotations = proto.RepeatedField( proto.MESSAGE, number=2, message="LabelAnnotation", ) - shot_label_annotations = proto.RepeatedField( proto.MESSAGE, number=3, message="LabelAnnotation", ) - frame_label_annotations = proto.RepeatedField( proto.MESSAGE, number=4, message="LabelAnnotation", ) - face_annotations = proto.RepeatedField( proto.MESSAGE, number=5, message="FaceAnnotation", ) - shot_annotations = proto.RepeatedField( proto.MESSAGE, number=6, message="VideoSegment", ) - explicit_annotation = proto.Field( proto.MESSAGE, number=7, message="ExplicitContentAnnotation", ) - - error = proto.Field(proto.MESSAGE, number=9, message=status.Status,) + error = proto.Field(proto.MESSAGE, number=9, message=status_pb2.Status,) class AnnotateVideoResponse(proto.Message): @@ -535,7 +486,6 @@ class AnnotateVideoResponse(proto.Message): class VideoAnnotationProgress(proto.Message): r"""Annotation progress for a single video. - Attributes: input_uri (str): Video file location in `Google Cloud @@ -549,13 +499,10 @@ class VideoAnnotationProgress(proto.Message): Time of the most recent update. """ - input_uri = proto.Field(proto.STRING, number=1) - - progress_percent = proto.Field(proto.INT32, number=2) - - start_time = proto.Field(proto.MESSAGE, number=3, message=timestamp.Timestamp,) - - update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp.Timestamp,) + input_uri = proto.Field(proto.STRING, number=1,) + progress_percent = proto.Field(proto.INT32, number=2,) + start_time = proto.Field(proto.MESSAGE, number=3, message=timestamp_pb2.Timestamp,) + update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp_pb2.Timestamp,) class AnnotateVideoProgress(proto.Message): diff --git a/google/cloud/videointelligence_v1p1beta1/__init__.py b/google/cloud/videointelligence_v1p1beta1/__init__.py index b3f78d15..d0620b52 100644 --- a/google/cloud/videointelligence_v1p1beta1/__init__.py +++ b/google/cloud/videointelligence_v1p1beta1/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,6 +15,8 @@ # from .services.video_intelligence_service import VideoIntelligenceServiceClient +from .services.video_intelligence_service import VideoIntelligenceServiceAsyncClient + from .types.video_intelligence import AnnotateVideoProgress from .types.video_intelligence import AnnotateVideoRequest from .types.video_intelligence import AnnotateVideoResponse @@ -23,13 +24,10 @@ from .types.video_intelligence import ExplicitContentAnnotation from .types.video_intelligence import ExplicitContentDetectionConfig from .types.video_intelligence import ExplicitContentFrame -from .types.video_intelligence import Feature from .types.video_intelligence import LabelAnnotation from .types.video_intelligence import LabelDetectionConfig -from .types.video_intelligence import LabelDetectionMode from .types.video_intelligence import LabelFrame from .types.video_intelligence import LabelSegment -from .types.video_intelligence import Likelihood from .types.video_intelligence import ShotChangeDetectionConfig from .types.video_intelligence import SpeechContext from .types.video_intelligence import SpeechRecognitionAlternative @@ -40,9 +38,12 @@ from .types.video_intelligence import VideoContext from .types.video_intelligence import VideoSegment from .types.video_intelligence import WordInfo - +from .types.video_intelligence import Feature +from .types.video_intelligence import LabelDetectionMode +from .types.video_intelligence import Likelihood __all__ = ( + "VideoIntelligenceServiceAsyncClient", "AnnotateVideoProgress", "AnnotateVideoRequest", "AnnotateVideoResponse", @@ -65,7 +66,7 @@ "VideoAnnotationProgress", "VideoAnnotationResults", "VideoContext", + "VideoIntelligenceServiceClient", "VideoSegment", "WordInfo", - "VideoIntelligenceServiceClient", ) diff --git a/google/cloud/videointelligence_v1p1beta1/gapic_metadata.json b/google/cloud/videointelligence_v1p1beta1/gapic_metadata.json new file mode 100644 index 00000000..6af0aca3 --- /dev/null +++ b/google/cloud/videointelligence_v1p1beta1/gapic_metadata.json @@ -0,0 +1,33 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.cloud.videointelligence_v1p1beta1", + "protoPackage": "google.cloud.videointelligence.v1p1beta1", + "schema": "1.0", + "services": { + "VideoIntelligenceService": { + "clients": { + "grpc": { + "libraryClient": "VideoIntelligenceServiceClient", + "rpcs": { + "AnnotateVideo": { + "methods": [ + "annotate_video" + ] + } + } + }, + "grpc-async": { + "libraryClient": "VideoIntelligenceServiceAsyncClient", + "rpcs": { + "AnnotateVideo": { + "methods": [ + "annotate_video" + ] + } + } + } + } + } + } +} diff --git a/google/cloud/videointelligence_v1p1beta1/services/__init__.py b/google/cloud/videointelligence_v1p1beta1/services/__init__.py index 42ffdf2b..4de65971 100644 --- a/google/cloud/videointelligence_v1p1beta1/services/__init__.py +++ b/google/cloud/videointelligence_v1p1beta1/services/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/__init__.py b/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/__init__.py index 55932028..02e942f8 100644 --- a/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/__init__.py +++ b/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .client import VideoIntelligenceServiceClient from .async_client import VideoIntelligenceServiceAsyncClient diff --git a/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/async_client.py b/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/async_client.py index 37e87175..5f3d922e 100644 --- a/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/async_client.py +++ b/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/async_client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict import functools import re @@ -22,16 +20,15 @@ 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 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 # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore from google.cloud.videointelligence_v1p1beta1.types import video_intelligence - from .transports.base import VideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO from .transports.grpc_asyncio import VideoIntelligenceServiceGrpcAsyncIOTransport from .client import VideoIntelligenceServiceClient @@ -51,26 +48,22 @@ class VideoIntelligenceServiceAsyncClient: parse_common_billing_account_path = staticmethod( VideoIntelligenceServiceClient.parse_common_billing_account_path ) - common_folder_path = staticmethod(VideoIntelligenceServiceClient.common_folder_path) parse_common_folder_path = staticmethod( VideoIntelligenceServiceClient.parse_common_folder_path ) - common_organization_path = staticmethod( VideoIntelligenceServiceClient.common_organization_path ) parse_common_organization_path = staticmethod( VideoIntelligenceServiceClient.parse_common_organization_path ) - common_project_path = staticmethod( VideoIntelligenceServiceClient.common_project_path ) parse_common_project_path = staticmethod( VideoIntelligenceServiceClient.parse_common_project_path ) - common_location_path = staticmethod( VideoIntelligenceServiceClient.common_location_path ) @@ -80,7 +73,8 @@ class VideoIntelligenceServiceAsyncClient: @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -95,7 +89,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -112,7 +106,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> VideoIntelligenceServiceTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: VideoIntelligenceServiceTransport: The transport used by the client instance. @@ -127,12 +121,12 @@ def transport(self) -> VideoIntelligenceServiceTransport: def __init__( self, *, - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, transport: Union[str, VideoIntelligenceServiceTransport] = "grpc_asyncio", client_options: ClientOptions = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the video intelligence service client. + """Instantiates the video intelligence service client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -164,7 +158,6 @@ def __init__( google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport creation failed for any reason. """ - self._client = VideoIntelligenceServiceClient( credentials=credentials, transport=transport, @@ -217,7 +210,6 @@ async def annotate_video( This corresponds to the ``features`` 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. @@ -247,10 +239,8 @@ async def annotate_video( # If we have keyword arguments corresponding to fields on the # request, apply these. - if input_uri is not None: request.input_uri = input_uri - if features: request.features.extend(features) @@ -263,7 +253,8 @@ async def annotate_video( maximum=120.0, multiplier=2.5, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=600.0, ), diff --git a/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/client.py b/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/client.py index aa7ee68f..ccbedfe1 100644 --- a/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/client.py +++ b/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from distutils import util import os @@ -23,10 +21,10 @@ 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 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 # type: ignore +from google.auth import credentials as ga_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 @@ -35,7 +33,6 @@ from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore from google.cloud.videointelligence_v1p1beta1.types import video_intelligence - from .transports.base import VideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO from .transports.grpc import VideoIntelligenceServiceGrpcTransport from .transports.grpc_asyncio import VideoIntelligenceServiceGrpcAsyncIOTransport @@ -58,7 +55,7 @@ class VideoIntelligenceServiceClientMeta(type): def get_transport_class( cls, label: str = None, ) -> Type[VideoIntelligenceServiceTransport]: - """Return an appropriate transport class. + """Returns an appropriate transport class. Args: label: The name of the desired transport. If none is @@ -81,7 +78,8 @@ class VideoIntelligenceServiceClient(metaclass=VideoIntelligenceServiceClientMet @staticmethod def _get_default_mtls_endpoint(api_endpoint): - """Convert api endpoint to mTLS endpoint. + """Converts api endpoint to mTLS endpoint. + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. Args: @@ -115,7 +113,8 @@ def _get_default_mtls_endpoint(api_endpoint): @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -132,7 +131,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -151,16 +150,17 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> VideoIntelligenceServiceTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: - VideoIntelligenceServiceTransport: The transport used by the client instance. + VideoIntelligenceServiceTransport: The transport used by the client + instance. """ return self._transport @staticmethod def common_billing_account_path(billing_account: str,) -> str: - """Return a fully-qualified billing_account string.""" + """Returns a fully-qualified billing_account string.""" return "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -173,7 +173,7 @@ def parse_common_billing_account_path(path: str) -> Dict[str, str]: @staticmethod def common_folder_path(folder: str,) -> str: - """Return a fully-qualified folder string.""" + """Returns a fully-qualified folder string.""" return "folders/{folder}".format(folder=folder,) @staticmethod @@ -184,7 +184,7 @@ def parse_common_folder_path(path: str) -> Dict[str, str]: @staticmethod def common_organization_path(organization: str,) -> str: - """Return a fully-qualified organization string.""" + """Returns a fully-qualified organization string.""" return "organizations/{organization}".format(organization=organization,) @staticmethod @@ -195,7 +195,7 @@ def parse_common_organization_path(path: str) -> Dict[str, str]: @staticmethod def common_project_path(project: str,) -> str: - """Return a fully-qualified project string.""" + """Returns a fully-qualified project string.""" return "projects/{project}".format(project=project,) @staticmethod @@ -206,7 +206,7 @@ def parse_common_project_path(path: str) -> Dict[str, str]: @staticmethod def common_location_path(project: str, location: str,) -> str: - """Return a fully-qualified location string.""" + """Returns a fully-qualified location string.""" return "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -220,12 +220,12 @@ def parse_common_location_path(path: str) -> Dict[str, str]: def __init__( self, *, - credentials: Optional[credentials.Credentials] = None, + credentials: Optional[ga_credentials.Credentials] = None, transport: Union[str, VideoIntelligenceServiceTransport, None] = None, client_options: Optional[client_options_lib.ClientOptions] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the video intelligence service client. + """Instantiates the video intelligence service client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -280,9 +280,10 @@ def __init__( 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 - ) + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None # Figure out which api endpoint to use. if client_options.api_endpoint is not None: @@ -294,12 +295,14 @@ def __init__( 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 - ) + if is_mtls: + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = self.DEFAULT_ENDPOINT else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" ) # Save or instantiate the transport. @@ -314,8 +317,8 @@ def __init__( ) if client_options.scopes: raise ValueError( - "When providing a transport instance, " - "provide its scopes directly." + "When providing a transport instance, provide its scopes " + "directly." ) self._transport = transport else: @@ -375,7 +378,6 @@ def annotate_video( This corresponds to the ``features`` 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. @@ -407,10 +409,8 @@ def annotate_video( # there are no flattened fields. if not isinstance(request, video_intelligence.AnnotateVideoRequest): request = video_intelligence.AnnotateVideoRequest(request) - # If we have keyword arguments corresponding to fields on the # request, apply these. - if input_uri is not None: request.input_uri = input_uri if features is not None: diff --git a/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/__init__.py b/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/__init__.py index fef86838..8ae3c6cb 100644 --- a/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/__init__.py +++ b/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from typing import Dict, Type diff --git a/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/base.py b/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/base.py index 95339b8e..a1f07f64 100644 --- a/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/base.py +++ b/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/base.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,21 +13,21 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import abc -import typing +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union +import packaging.version import pkg_resources -from google import auth # type: ignore -from google.api_core import exceptions # type: ignore +import google.auth # type: ignore +import google.api_core # 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.api_core import operations_v1 # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.cloud.videointelligence_v1p1beta1.types import video_intelligence -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( @@ -39,27 +38,41 @@ 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 + +_API_CORE_VERSION = google.api_core.__version__ + class VideoIntelligenceServiceTransport(abc.ABC): """Abstract transport class for VideoIntelligenceService.""" AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + DEFAULT_HOST: str = "videointelligence.googleapis.com" + def __init__( self, *, - host: str = "videointelligence.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, + host: str = DEFAULT_HOST, + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: 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. + 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 @@ -68,7 +81,7 @@ def __init__( 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. + scopes (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): @@ -82,29 +95,76 @@ def __init__( host += ":443" self._host = host + scopes_kwargs = self._get_scopes_kwargs(self._host, scopes) + # Save the scopes. self._scopes = scopes or self.AUTH_SCOPES # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: - raise exceptions.DuplicateCredentialArgs( + raise core_exceptions.DuplicateCredentialArgs( "'credentials_file' and 'credentials' are mutually exclusive" ) if credentials_file is not None: - credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, **scopes_kwargs, quota_project_id=quota_project_id ) elif credentials is None: - credentials, _ = auth.default( - scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials + # TODO(busunkim): These two class methods are in the base transport + # to avoid duplicating code across the transport classes. These functions + # should be deleted once the minimum required versions of google-api-core + # and google-auth are 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 + + # TODO: Remove this function once google-api-core >= 1.26.0 is required + @classmethod + def _get_self_signed_jwt_kwargs( + cls, host: str, scopes: Optional[Sequence[str]] + ) -> Dict[str, Union[Optional[Sequence[str]], str]]: + """Returns kwargs to pass to grpc_helpers.create_channel depending on the google-api-core version""" + + self_signed_jwt_kwargs: Dict[str, Union[Optional[Sequence[str]], str]] = {} + + if _API_CORE_VERSION and ( + packaging.version.parse(_API_CORE_VERSION) + >= packaging.version.parse("1.26.0") + ): + self_signed_jwt_kwargs["default_scopes"] = cls.AUTH_SCOPES + self_signed_jwt_kwargs["scopes"] = scopes + self_signed_jwt_kwargs["default_host"] = cls.DEFAULT_HOST + else: + self_signed_jwt_kwargs["scopes"] = scopes or cls.AUTH_SCOPES + + return self_signed_jwt_kwargs + def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { @@ -115,7 +175,8 @@ def _prep_wrapped_messages(self, client_info): maximum=120.0, multiplier=2.5, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=600.0, ), @@ -132,9 +193,9 @@ def operations_client(self) -> operations_v1.OperationsClient: @property def annotate_video( self, - ) -> typing.Callable[ + ) -> Callable[ [video_intelligence.AnnotateVideoRequest], - typing.Union[operations.Operation, typing.Awaitable[operations.Operation]], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], ]: raise NotImplementedError() diff --git a/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/grpc.py b/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/grpc.py index 3a036a9c..45e2e7c8 100644 --- a/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/grpc.py +++ b/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/grpc.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,22 +13,20 @@ # 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 typing import Callable, Dict, Optional, Sequence, Tuple, Union from google.api_core import grpc_helpers # type: ignore from google.api_core import operations_v1 # type: ignore from google.api_core import gapic_v1 # type: ignore -from google import auth # type: ignore -from google.auth import credentials # type: ignore +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore import grpc # type: ignore from google.cloud.videointelligence_v1p1beta1.types import video_intelligence -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore from .base import VideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO @@ -52,7 +49,7 @@ def __init__( self, *, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Sequence[str] = None, channel: grpc.Channel = None, @@ -66,7 +63,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + 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 @@ -177,7 +175,7 @@ def __init__( def create_channel( cls, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -208,13 +206,15 @@ def create_channel( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) @@ -241,7 +241,7 @@ def operations_client(self) -> operations_v1.OperationsClient: @property def annotate_video( self, - ) -> Callable[[video_intelligence.AnnotateVideoRequest], operations.Operation]: + ) -> Callable[[video_intelligence.AnnotateVideoRequest], operations_pb2.Operation]: r"""Return a callable for the annotate video method over gRPC. Performs asynchronous video annotation. Progress and results can @@ -264,7 +264,7 @@ def annotate_video( self._stubs["annotate_video"] = self.grpc_channel.unary_unary( "/google.cloud.videointelligence.v1p1beta1.VideoIntelligenceService/AnnotateVideo", request_serializer=video_intelligence.AnnotateVideoRequest.serialize, - response_deserializer=operations.Operation.FromString, + response_deserializer=operations_pb2.Operation.FromString, ) return self._stubs["annotate_video"] diff --git a/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/grpc_asyncio.py b/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/grpc_asyncio.py index ef3631aa..5c0416d9 100644 --- a/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/grpc_asyncio.py +++ b/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/grpc_asyncio.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,23 +13,21 @@ # 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 typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore -from google import auth # type: ignore -from google.auth import credentials # 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 from google.cloud.videointelligence_v1p1beta1.types import video_intelligence -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore from .base import VideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO from .grpc import VideoIntelligenceServiceGrpcTransport @@ -55,7 +52,7 @@ class VideoIntelligenceServiceGrpcAsyncIOTransport(VideoIntelligenceServiceTrans def create_channel( cls, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -82,13 +79,15 @@ def create_channel( Returns: aio.Channel: A gRPC AsyncIO channel object. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers_async.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) @@ -96,7 +95,7 @@ def __init__( self, *, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, channel: aio.Channel = None, @@ -110,7 +109,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + 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 @@ -169,7 +169,6 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - else: if api_mtls_endpoint: host = api_mtls_endpoint @@ -248,7 +247,7 @@ def operations_client(self) -> operations_v1.OperationsAsyncClient: def annotate_video( self, ) -> Callable[ - [video_intelligence.AnnotateVideoRequest], Awaitable[operations.Operation] + [video_intelligence.AnnotateVideoRequest], Awaitable[operations_pb2.Operation] ]: r"""Return a callable for the annotate video method over gRPC. @@ -272,7 +271,7 @@ def annotate_video( self._stubs["annotate_video"] = self.grpc_channel.unary_unary( "/google.cloud.videointelligence.v1p1beta1.VideoIntelligenceService/AnnotateVideo", request_serializer=video_intelligence.AnnotateVideoRequest.serialize, - response_deserializer=operations.Operation.FromString, + response_deserializer=operations_pb2.Operation.FromString, ) return self._stubs["annotate_video"] diff --git a/google/cloud/videointelligence_v1p1beta1/types/__init__.py b/google/cloud/videointelligence_v1p1beta1/types/__init__.py index 8e9d34af..8e8b0e53 100644 --- a/google/cloud/videointelligence_v1p1beta1/types/__init__.py +++ b/google/cloud/videointelligence_v1p1beta1/types/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .video_intelligence import ( AnnotateVideoProgress, AnnotateVideoRequest, diff --git a/google/cloud/videointelligence_v1p1beta1/types/video_intelligence.py b/google/cloud/videointelligence_v1p1beta1/types/video_intelligence.py index 4f7cf766..7c529fdf 100644 --- a/google/cloud/videointelligence_v1p1beta1/types/video_intelligence.py +++ b/google/cloud/videointelligence_v1p1beta1/types/video_intelligence.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,13 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore - -from google.protobuf import duration_pb2 as duration # type: ignore -from google.protobuf import timestamp_pb2 as timestamp # type: ignore -from google.rpc import status_pb2 as status # type: ignore +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( @@ -83,7 +80,6 @@ class Likelihood(proto.Enum): class AnnotateVideoRequest(proto.Message): r"""Video annotation request. - Attributes: input_uri (str): Input video location. Currently, only `Google Cloud @@ -125,22 +121,16 @@ class AnnotateVideoRequest(proto.Message): a region will be determined based on video file location. """ - input_uri = proto.Field(proto.STRING, number=1) - - input_content = proto.Field(proto.BYTES, number=6) - + input_uri = proto.Field(proto.STRING, number=1,) + input_content = proto.Field(proto.BYTES, number=6,) features = proto.RepeatedField(proto.ENUM, number=2, enum="Feature",) - video_context = proto.Field(proto.MESSAGE, number=3, message="VideoContext",) - - output_uri = proto.Field(proto.STRING, number=4) - - location_id = proto.Field(proto.STRING, number=5) + output_uri = proto.Field(proto.STRING, number=4,) + location_id = proto.Field(proto.STRING, number=5,) class VideoContext(proto.Message): r"""Video context and/or feature-specific parameters. - Attributes: segments (Sequence[google.cloud.videointelligence_v1p1beta1.types.VideoSegment]): Video segments to annotate. The segments may @@ -158,19 +148,15 @@ class VideoContext(proto.Message): """ segments = proto.RepeatedField(proto.MESSAGE, number=1, message="VideoSegment",) - label_detection_config = proto.Field( proto.MESSAGE, number=2, message="LabelDetectionConfig", ) - shot_change_detection_config = proto.Field( proto.MESSAGE, number=3, message="ShotChangeDetectionConfig", ) - explicit_content_detection_config = proto.Field( proto.MESSAGE, number=4, message="ExplicitContentDetectionConfig", ) - speech_transcription_config = proto.Field( proto.MESSAGE, number=6, message="SpeechTranscriptionConfig", ) @@ -178,7 +164,6 @@ class VideoContext(proto.Message): class LabelDetectionConfig(proto.Message): r"""Config for LABEL_DETECTION. - Attributes: label_detection_mode (google.cloud.videointelligence_v1p1beta1.types.LabelDetectionMode): What labels should be detected with LABEL_DETECTION, in @@ -196,15 +181,12 @@ class LabelDetectionConfig(proto.Message): """ label_detection_mode = proto.Field(proto.ENUM, number=1, enum="LabelDetectionMode",) - - stationary_camera = proto.Field(proto.BOOL, number=2) - - model = proto.Field(proto.STRING, number=3) + stationary_camera = proto.Field(proto.BOOL, number=2,) + model = proto.Field(proto.STRING, number=3,) class ShotChangeDetectionConfig(proto.Message): r"""Config for SHOT_CHANGE_DETECTION. - Attributes: model (str): Model to use for shot change detection. @@ -212,12 +194,11 @@ class ShotChangeDetectionConfig(proto.Message): if unset) and "builtin/latest". """ - model = proto.Field(proto.STRING, number=1) + model = proto.Field(proto.STRING, number=1,) class ExplicitContentDetectionConfig(proto.Message): r"""Config for EXPLICIT_CONTENT_DETECTION. - Attributes: model (str): Model to use for explicit content detection. @@ -225,12 +206,11 @@ class ExplicitContentDetectionConfig(proto.Message): if unset) and "builtin/latest". """ - model = proto.Field(proto.STRING, number=1) + model = proto.Field(proto.STRING, number=1,) class VideoSegment(proto.Message): r"""Video segment. - Attributes: start_time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the @@ -242,14 +222,16 @@ class VideoSegment(proto.Message): (inclusive). """ - start_time_offset = proto.Field(proto.MESSAGE, number=1, message=duration.Duration,) - - end_time_offset = proto.Field(proto.MESSAGE, number=2, message=duration.Duration,) + start_time_offset = proto.Field( + proto.MESSAGE, number=1, message=duration_pb2.Duration, + ) + end_time_offset = proto.Field( + proto.MESSAGE, number=2, message=duration_pb2.Duration, + ) class LabelSegment(proto.Message): r"""Video segment level annotation results for label detection. - Attributes: segment (google.cloud.videointelligence_v1p1beta1.types.VideoSegment): Video segment where a label was detected. @@ -258,13 +240,11 @@ class LabelSegment(proto.Message): """ segment = proto.Field(proto.MESSAGE, number=1, message="VideoSegment",) - - confidence = proto.Field(proto.FLOAT, number=2) + confidence = proto.Field(proto.FLOAT, number=2,) class LabelFrame(proto.Message): r"""Video frame level annotation results for label detection. - Attributes: time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the @@ -274,14 +254,12 @@ class LabelFrame(proto.Message): Confidence that the label is accurate. Range: [0, 1]. """ - time_offset = proto.Field(proto.MESSAGE, number=1, message=duration.Duration,) - - confidence = proto.Field(proto.FLOAT, number=2) + time_offset = proto.Field(proto.MESSAGE, number=1, message=duration_pb2.Duration,) + confidence = proto.Field(proto.FLOAT, number=2,) class Entity(proto.Message): r"""Detected entity from video analysis. - Attributes: entity_id (str): Opaque entity ID. Some IDs may be available in `Google @@ -293,16 +271,13 @@ class Entity(proto.Message): Language code for ``description`` in BCP-47 format. """ - entity_id = proto.Field(proto.STRING, number=1) - - description = proto.Field(proto.STRING, number=2) - - language_code = proto.Field(proto.STRING, number=3) + entity_id = proto.Field(proto.STRING, number=1,) + description = proto.Field(proto.STRING, number=2,) + language_code = proto.Field(proto.STRING, number=3,) class LabelAnnotation(proto.Message): r"""Label annotation. - Attributes: entity (google.cloud.videointelligence_v1p1beta1.types.Entity): Detected entity. @@ -319,17 +294,13 @@ class LabelAnnotation(proto.Message): """ entity = proto.Field(proto.MESSAGE, number=1, message="Entity",) - category_entities = proto.RepeatedField(proto.MESSAGE, number=2, message="Entity",) - segments = proto.RepeatedField(proto.MESSAGE, number=3, message="LabelSegment",) - frames = proto.RepeatedField(proto.MESSAGE, number=4, message="LabelFrame",) class ExplicitContentFrame(proto.Message): r"""Video frame level annotation results for explicit content. - Attributes: time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the @@ -339,8 +310,7 @@ class ExplicitContentFrame(proto.Message): Likelihood of the pornography content.. """ - time_offset = proto.Field(proto.MESSAGE, number=1, message=duration.Duration,) - + time_offset = proto.Field(proto.MESSAGE, number=1, message=duration_pb2.Duration,) pornography_likelihood = proto.Field(proto.ENUM, number=2, enum="Likelihood",) @@ -362,7 +332,6 @@ class ExplicitContentAnnotation(proto.Message): class VideoAnnotationResults(proto.Message): r"""Annotation results for a single video. - Attributes: input_uri (str): Output only. Video file location in `Google Cloud @@ -392,33 +361,26 @@ class VideoAnnotationResults(proto.Message): some may fail. """ - input_uri = proto.Field(proto.STRING, number=1) - + input_uri = proto.Field(proto.STRING, number=1,) segment_label_annotations = proto.RepeatedField( proto.MESSAGE, number=2, message="LabelAnnotation", ) - shot_label_annotations = proto.RepeatedField( proto.MESSAGE, number=3, message="LabelAnnotation", ) - frame_label_annotations = proto.RepeatedField( proto.MESSAGE, number=4, message="LabelAnnotation", ) - shot_annotations = proto.RepeatedField( proto.MESSAGE, number=6, message="VideoSegment", ) - explicit_annotation = proto.Field( proto.MESSAGE, number=7, message="ExplicitContentAnnotation", ) - speech_transcriptions = proto.RepeatedField( proto.MESSAGE, number=11, message="SpeechTranscription", ) - - error = proto.Field(proto.MESSAGE, number=9, message=status.Status,) + error = proto.Field(proto.MESSAGE, number=9, message=status_pb2.Status,) class AnnotateVideoResponse(proto.Message): @@ -439,7 +401,6 @@ class AnnotateVideoResponse(proto.Message): class VideoAnnotationProgress(proto.Message): r"""Annotation progress for a single video. - Attributes: input_uri (str): Output only. Video file location in `Google Cloud @@ -455,13 +416,10 @@ class VideoAnnotationProgress(proto.Message): Output only. Time of the most recent update. """ - input_uri = proto.Field(proto.STRING, number=1) - - progress_percent = proto.Field(proto.INT32, number=2) - - start_time = proto.Field(proto.MESSAGE, number=3, message=timestamp.Timestamp,) - - update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp.Timestamp,) + input_uri = proto.Field(proto.STRING, number=1,) + progress_percent = proto.Field(proto.INT32, number=2,) + start_time = proto.Field(proto.MESSAGE, number=3, message=timestamp_pb2.Timestamp,) + update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp_pb2.Timestamp,) class AnnotateVideoProgress(proto.Message): @@ -482,7 +440,6 @@ class AnnotateVideoProgress(proto.Message): class SpeechTranscriptionConfig(proto.Message): r"""Config for SPEECH_TRANSCRIPTION. - Attributes: language_code (str): Required. *Required* The language of the supplied audio as a @@ -524,19 +481,14 @@ class SpeechTranscriptionConfig(proto.Message): up to two tracks. Default: track 0. """ - language_code = proto.Field(proto.STRING, number=1) - - max_alternatives = proto.Field(proto.INT32, number=2) - - filter_profanity = proto.Field(proto.BOOL, number=3) - + language_code = proto.Field(proto.STRING, number=1,) + max_alternatives = proto.Field(proto.INT32, number=2,) + filter_profanity = proto.Field(proto.BOOL, number=3,) speech_contexts = proto.RepeatedField( proto.MESSAGE, number=4, message="SpeechContext", ) - - enable_automatic_punctuation = proto.Field(proto.BOOL, number=5) - - audio_tracks = proto.RepeatedField(proto.INT32, number=6) + enable_automatic_punctuation = proto.Field(proto.BOOL, number=5,) + audio_tracks = proto.RepeatedField(proto.INT32, number=6,) class SpeechContext(proto.Message): @@ -555,7 +507,7 @@ class SpeechContext(proto.Message): limits `__. """ - phrases = proto.RepeatedField(proto.STRING, number=1) + phrases = proto.RepeatedField(proto.STRING, number=1,) class SpeechTranscription(proto.Message): @@ -578,7 +530,6 @@ class SpeechTranscription(proto.Message): class SpeechRecognitionAlternative(proto.Message): r"""Alternative hypotheses (a.k.a. n-best list). - Attributes: transcript (str): Output only. Transcript text representing the @@ -596,10 +547,8 @@ class SpeechRecognitionAlternative(proto.Message): information for each recognized word. """ - transcript = proto.Field(proto.STRING, number=1) - - confidence = proto.Field(proto.FLOAT, number=2) - + transcript = proto.Field(proto.STRING, number=1,) + confidence = proto.Field(proto.FLOAT, number=2,) words = proto.RepeatedField(proto.MESSAGE, number=3, message="WordInfo",) @@ -626,11 +575,9 @@ class WordInfo(proto.Message): set of information. """ - start_time = proto.Field(proto.MESSAGE, number=1, message=duration.Duration,) - - end_time = proto.Field(proto.MESSAGE, number=2, message=duration.Duration,) - - word = proto.Field(proto.STRING, number=3) + start_time = proto.Field(proto.MESSAGE, number=1, message=duration_pb2.Duration,) + end_time = proto.Field(proto.MESSAGE, number=2, message=duration_pb2.Duration,) + word = proto.Field(proto.STRING, number=3,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/videointelligence_v1p2beta1/__init__.py b/google/cloud/videointelligence_v1p2beta1/__init__.py index 8b821c7d..9b11a710 100644 --- a/google/cloud/videointelligence_v1p2beta1/__init__.py +++ b/google/cloud/videointelligence_v1p2beta1/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,6 +15,8 @@ # from .services.video_intelligence_service import VideoIntelligenceServiceClient +from .services.video_intelligence_service import VideoIntelligenceServiceAsyncClient + from .types.video_intelligence import AnnotateVideoProgress from .types.video_intelligence import AnnotateVideoRequest from .types.video_intelligence import AnnotateVideoResponse @@ -23,13 +24,10 @@ from .types.video_intelligence import ExplicitContentAnnotation from .types.video_intelligence import ExplicitContentDetectionConfig from .types.video_intelligence import ExplicitContentFrame -from .types.video_intelligence import Feature from .types.video_intelligence import LabelAnnotation from .types.video_intelligence import LabelDetectionConfig -from .types.video_intelligence import LabelDetectionMode from .types.video_intelligence import LabelFrame from .types.video_intelligence import LabelSegment -from .types.video_intelligence import Likelihood from .types.video_intelligence import NormalizedBoundingBox from .types.video_intelligence import NormalizedBoundingPoly from .types.video_intelligence import NormalizedVertex @@ -44,9 +42,12 @@ from .types.video_intelligence import VideoAnnotationResults from .types.video_intelligence import VideoContext from .types.video_intelligence import VideoSegment - +from .types.video_intelligence import Feature +from .types.video_intelligence import LabelDetectionMode +from .types.video_intelligence import Likelihood __all__ = ( + "VideoIntelligenceServiceAsyncClient", "AnnotateVideoProgress", "AnnotateVideoRequest", "AnnotateVideoResponse", @@ -74,6 +75,6 @@ "VideoAnnotationProgress", "VideoAnnotationResults", "VideoContext", - "VideoSegment", "VideoIntelligenceServiceClient", + "VideoSegment", ) diff --git a/google/cloud/videointelligence_v1p2beta1/gapic_metadata.json b/google/cloud/videointelligence_v1p2beta1/gapic_metadata.json new file mode 100644 index 00000000..3f52f8b4 --- /dev/null +++ b/google/cloud/videointelligence_v1p2beta1/gapic_metadata.json @@ -0,0 +1,33 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.cloud.videointelligence_v1p2beta1", + "protoPackage": "google.cloud.videointelligence.v1p2beta1", + "schema": "1.0", + "services": { + "VideoIntelligenceService": { + "clients": { + "grpc": { + "libraryClient": "VideoIntelligenceServiceClient", + "rpcs": { + "AnnotateVideo": { + "methods": [ + "annotate_video" + ] + } + } + }, + "grpc-async": { + "libraryClient": "VideoIntelligenceServiceAsyncClient", + "rpcs": { + "AnnotateVideo": { + "methods": [ + "annotate_video" + ] + } + } + } + } + } + } +} diff --git a/google/cloud/videointelligence_v1p2beta1/services/__init__.py b/google/cloud/videointelligence_v1p2beta1/services/__init__.py index 42ffdf2b..4de65971 100644 --- a/google/cloud/videointelligence_v1p2beta1/services/__init__.py +++ b/google/cloud/videointelligence_v1p2beta1/services/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/__init__.py b/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/__init__.py index 55932028..02e942f8 100644 --- a/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/__init__.py +++ b/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .client import VideoIntelligenceServiceClient from .async_client import VideoIntelligenceServiceAsyncClient diff --git a/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/async_client.py b/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/async_client.py index ac3f4fda..f3af55da 100644 --- a/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/async_client.py +++ b/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/async_client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict import functools import re @@ -22,16 +20,15 @@ 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 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 # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore from google.cloud.videointelligence_v1p2beta1.types import video_intelligence - from .transports.base import VideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO from .transports.grpc_asyncio import VideoIntelligenceServiceGrpcAsyncIOTransport from .client import VideoIntelligenceServiceClient @@ -51,26 +48,22 @@ class VideoIntelligenceServiceAsyncClient: parse_common_billing_account_path = staticmethod( VideoIntelligenceServiceClient.parse_common_billing_account_path ) - common_folder_path = staticmethod(VideoIntelligenceServiceClient.common_folder_path) parse_common_folder_path = staticmethod( VideoIntelligenceServiceClient.parse_common_folder_path ) - common_organization_path = staticmethod( VideoIntelligenceServiceClient.common_organization_path ) parse_common_organization_path = staticmethod( VideoIntelligenceServiceClient.parse_common_organization_path ) - common_project_path = staticmethod( VideoIntelligenceServiceClient.common_project_path ) parse_common_project_path = staticmethod( VideoIntelligenceServiceClient.parse_common_project_path ) - common_location_path = staticmethod( VideoIntelligenceServiceClient.common_location_path ) @@ -80,7 +73,8 @@ class VideoIntelligenceServiceAsyncClient: @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -95,7 +89,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -112,7 +106,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> VideoIntelligenceServiceTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: VideoIntelligenceServiceTransport: The transport used by the client instance. @@ -127,12 +121,12 @@ def transport(self) -> VideoIntelligenceServiceTransport: def __init__( self, *, - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, transport: Union[str, VideoIntelligenceServiceTransport] = "grpc_asyncio", client_options: ClientOptions = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the video intelligence service client. + """Instantiates the video intelligence service client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -164,7 +158,6 @@ def __init__( google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport creation failed for any reason. """ - self._client = VideoIntelligenceServiceClient( credentials=credentials, transport=transport, @@ -217,7 +210,6 @@ async def annotate_video( This corresponds to the ``features`` 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. @@ -247,10 +239,8 @@ async def annotate_video( # If we have keyword arguments corresponding to fields on the # request, apply these. - if input_uri is not None: request.input_uri = input_uri - if features: request.features.extend(features) @@ -263,7 +253,8 @@ async def annotate_video( maximum=120.0, multiplier=2.5, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=600.0, ), diff --git a/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/client.py b/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/client.py index 1e1b9dd9..b83a92a9 100644 --- a/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/client.py +++ b/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from distutils import util import os @@ -23,10 +21,10 @@ 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 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 # type: ignore +from google.auth import credentials as ga_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 @@ -35,7 +33,6 @@ from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore from google.cloud.videointelligence_v1p2beta1.types import video_intelligence - from .transports.base import VideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO from .transports.grpc import VideoIntelligenceServiceGrpcTransport from .transports.grpc_asyncio import VideoIntelligenceServiceGrpcAsyncIOTransport @@ -58,7 +55,7 @@ class VideoIntelligenceServiceClientMeta(type): def get_transport_class( cls, label: str = None, ) -> Type[VideoIntelligenceServiceTransport]: - """Return an appropriate transport class. + """Returns an appropriate transport class. Args: label: The name of the desired transport. If none is @@ -81,7 +78,8 @@ class VideoIntelligenceServiceClient(metaclass=VideoIntelligenceServiceClientMet @staticmethod def _get_default_mtls_endpoint(api_endpoint): - """Convert api endpoint to mTLS endpoint. + """Converts api endpoint to mTLS endpoint. + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. Args: @@ -115,7 +113,8 @@ def _get_default_mtls_endpoint(api_endpoint): @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -132,7 +131,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -151,16 +150,17 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> VideoIntelligenceServiceTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: - VideoIntelligenceServiceTransport: The transport used by the client instance. + VideoIntelligenceServiceTransport: The transport used by the client + instance. """ return self._transport @staticmethod def common_billing_account_path(billing_account: str,) -> str: - """Return a fully-qualified billing_account string.""" + """Returns a fully-qualified billing_account string.""" return "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -173,7 +173,7 @@ def parse_common_billing_account_path(path: str) -> Dict[str, str]: @staticmethod def common_folder_path(folder: str,) -> str: - """Return a fully-qualified folder string.""" + """Returns a fully-qualified folder string.""" return "folders/{folder}".format(folder=folder,) @staticmethod @@ -184,7 +184,7 @@ def parse_common_folder_path(path: str) -> Dict[str, str]: @staticmethod def common_organization_path(organization: str,) -> str: - """Return a fully-qualified organization string.""" + """Returns a fully-qualified organization string.""" return "organizations/{organization}".format(organization=organization,) @staticmethod @@ -195,7 +195,7 @@ def parse_common_organization_path(path: str) -> Dict[str, str]: @staticmethod def common_project_path(project: str,) -> str: - """Return a fully-qualified project string.""" + """Returns a fully-qualified project string.""" return "projects/{project}".format(project=project,) @staticmethod @@ -206,7 +206,7 @@ def parse_common_project_path(path: str) -> Dict[str, str]: @staticmethod def common_location_path(project: str, location: str,) -> str: - """Return a fully-qualified location string.""" + """Returns a fully-qualified location string.""" return "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -220,12 +220,12 @@ def parse_common_location_path(path: str) -> Dict[str, str]: def __init__( self, *, - credentials: Optional[credentials.Credentials] = None, + credentials: Optional[ga_credentials.Credentials] = None, transport: Union[str, VideoIntelligenceServiceTransport, None] = None, client_options: Optional[client_options_lib.ClientOptions] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the video intelligence service client. + """Instantiates the video intelligence service client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -280,9 +280,10 @@ def __init__( 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 - ) + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None # Figure out which api endpoint to use. if client_options.api_endpoint is not None: @@ -294,12 +295,14 @@ def __init__( 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 - ) + if is_mtls: + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = self.DEFAULT_ENDPOINT else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" ) # Save or instantiate the transport. @@ -314,8 +317,8 @@ def __init__( ) if client_options.scopes: raise ValueError( - "When providing a transport instance, " - "provide its scopes directly." + "When providing a transport instance, provide its scopes " + "directly." ) self._transport = transport else: @@ -375,7 +378,6 @@ def annotate_video( This corresponds to the ``features`` 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. @@ -407,10 +409,8 @@ def annotate_video( # there are no flattened fields. if not isinstance(request, video_intelligence.AnnotateVideoRequest): request = video_intelligence.AnnotateVideoRequest(request) - # If we have keyword arguments corresponding to fields on the # request, apply these. - if input_uri is not None: request.input_uri = input_uri if features is not None: diff --git a/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/__init__.py b/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/__init__.py index fef86838..8ae3c6cb 100644 --- a/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/__init__.py +++ b/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from typing import Dict, Type diff --git a/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/base.py b/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/base.py index dc1d2ddc..081d82c6 100644 --- a/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/base.py +++ b/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/base.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,21 +13,21 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import abc -import typing +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union +import packaging.version import pkg_resources -from google import auth # type: ignore -from google.api_core import exceptions # type: ignore +import google.auth # type: ignore +import google.api_core # 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.api_core import operations_v1 # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.cloud.videointelligence_v1p2beta1.types import video_intelligence -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( @@ -39,27 +38,41 @@ 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 + +_API_CORE_VERSION = google.api_core.__version__ + class VideoIntelligenceServiceTransport(abc.ABC): """Abstract transport class for VideoIntelligenceService.""" AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + DEFAULT_HOST: str = "videointelligence.googleapis.com" + def __init__( self, *, - host: str = "videointelligence.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, + host: str = DEFAULT_HOST, + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: 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. + 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 @@ -68,7 +81,7 @@ def __init__( 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. + scopes (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): @@ -82,29 +95,76 @@ def __init__( host += ":443" self._host = host + scopes_kwargs = self._get_scopes_kwargs(self._host, scopes) + # Save the scopes. self._scopes = scopes or self.AUTH_SCOPES # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: - raise exceptions.DuplicateCredentialArgs( + raise core_exceptions.DuplicateCredentialArgs( "'credentials_file' and 'credentials' are mutually exclusive" ) if credentials_file is not None: - credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, **scopes_kwargs, quota_project_id=quota_project_id ) elif credentials is None: - credentials, _ = auth.default( - scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials + # TODO(busunkim): These two class methods are in the base transport + # to avoid duplicating code across the transport classes. These functions + # should be deleted once the minimum required versions of google-api-core + # and google-auth are 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 + + # TODO: Remove this function once google-api-core >= 1.26.0 is required + @classmethod + def _get_self_signed_jwt_kwargs( + cls, host: str, scopes: Optional[Sequence[str]] + ) -> Dict[str, Union[Optional[Sequence[str]], str]]: + """Returns kwargs to pass to grpc_helpers.create_channel depending on the google-api-core version""" + + self_signed_jwt_kwargs: Dict[str, Union[Optional[Sequence[str]], str]] = {} + + if _API_CORE_VERSION and ( + packaging.version.parse(_API_CORE_VERSION) + >= packaging.version.parse("1.26.0") + ): + self_signed_jwt_kwargs["default_scopes"] = cls.AUTH_SCOPES + self_signed_jwt_kwargs["scopes"] = scopes + self_signed_jwt_kwargs["default_host"] = cls.DEFAULT_HOST + else: + self_signed_jwt_kwargs["scopes"] = scopes or cls.AUTH_SCOPES + + return self_signed_jwt_kwargs + def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { @@ -115,7 +175,8 @@ def _prep_wrapped_messages(self, client_info): maximum=120.0, multiplier=2.5, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=600.0, ), @@ -132,9 +193,9 @@ def operations_client(self) -> operations_v1.OperationsClient: @property def annotate_video( self, - ) -> typing.Callable[ + ) -> Callable[ [video_intelligence.AnnotateVideoRequest], - typing.Union[operations.Operation, typing.Awaitable[operations.Operation]], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], ]: raise NotImplementedError() diff --git a/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/grpc.py b/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/grpc.py index a41cccee..cc257d79 100644 --- a/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/grpc.py +++ b/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/grpc.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,22 +13,20 @@ # 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 typing import Callable, Dict, Optional, Sequence, Tuple, Union from google.api_core import grpc_helpers # type: ignore from google.api_core import operations_v1 # type: ignore from google.api_core import gapic_v1 # type: ignore -from google import auth # type: ignore -from google.auth import credentials # type: ignore +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore import grpc # type: ignore from google.cloud.videointelligence_v1p2beta1.types import video_intelligence -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore from .base import VideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO @@ -52,7 +49,7 @@ def __init__( self, *, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Sequence[str] = None, channel: grpc.Channel = None, @@ -66,7 +63,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + 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 @@ -177,7 +175,7 @@ def __init__( def create_channel( cls, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -208,13 +206,15 @@ def create_channel( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) @@ -241,7 +241,7 @@ def operations_client(self) -> operations_v1.OperationsClient: @property def annotate_video( self, - ) -> Callable[[video_intelligence.AnnotateVideoRequest], operations.Operation]: + ) -> Callable[[video_intelligence.AnnotateVideoRequest], operations_pb2.Operation]: r"""Return a callable for the annotate video method over gRPC. Performs asynchronous video annotation. Progress and results can @@ -264,7 +264,7 @@ def annotate_video( self._stubs["annotate_video"] = self.grpc_channel.unary_unary( "/google.cloud.videointelligence.v1p2beta1.VideoIntelligenceService/AnnotateVideo", request_serializer=video_intelligence.AnnotateVideoRequest.serialize, - response_deserializer=operations.Operation.FromString, + response_deserializer=operations_pb2.Operation.FromString, ) return self._stubs["annotate_video"] diff --git a/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/grpc_asyncio.py b/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/grpc_asyncio.py index 4daff5ec..09ab4705 100644 --- a/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/grpc_asyncio.py +++ b/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/grpc_asyncio.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,23 +13,21 @@ # 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 typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore -from google import auth # type: ignore -from google.auth import credentials # 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 from google.cloud.videointelligence_v1p2beta1.types import video_intelligence -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore from .base import VideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO from .grpc import VideoIntelligenceServiceGrpcTransport @@ -55,7 +52,7 @@ class VideoIntelligenceServiceGrpcAsyncIOTransport(VideoIntelligenceServiceTrans def create_channel( cls, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -82,13 +79,15 @@ def create_channel( Returns: aio.Channel: A gRPC AsyncIO channel object. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers_async.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) @@ -96,7 +95,7 @@ def __init__( self, *, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, channel: aio.Channel = None, @@ -110,7 +109,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + 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 @@ -169,7 +169,6 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - else: if api_mtls_endpoint: host = api_mtls_endpoint @@ -248,7 +247,7 @@ def operations_client(self) -> operations_v1.OperationsAsyncClient: def annotate_video( self, ) -> Callable[ - [video_intelligence.AnnotateVideoRequest], Awaitable[operations.Operation] + [video_intelligence.AnnotateVideoRequest], Awaitable[operations_pb2.Operation] ]: r"""Return a callable for the annotate video method over gRPC. @@ -272,7 +271,7 @@ def annotate_video( self._stubs["annotate_video"] = self.grpc_channel.unary_unary( "/google.cloud.videointelligence.v1p2beta1.VideoIntelligenceService/AnnotateVideo", request_serializer=video_intelligence.AnnotateVideoRequest.serialize, - response_deserializer=operations.Operation.FromString, + response_deserializer=operations_pb2.Operation.FromString, ) return self._stubs["annotate_video"] diff --git a/google/cloud/videointelligence_v1p2beta1/types/__init__.py b/google/cloud/videointelligence_v1p2beta1/types/__init__.py index fc0e4966..cb157c58 100644 --- a/google/cloud/videointelligence_v1p2beta1/types/__init__.py +++ b/google/cloud/videointelligence_v1p2beta1/types/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .video_intelligence import ( AnnotateVideoProgress, AnnotateVideoRequest, diff --git a/google/cloud/videointelligence_v1p2beta1/types/video_intelligence.py b/google/cloud/videointelligence_v1p2beta1/types/video_intelligence.py index 62df5db7..754ad23a 100644 --- a/google/cloud/videointelligence_v1p2beta1/types/video_intelligence.py +++ b/google/cloud/videointelligence_v1p2beta1/types/video_intelligence.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,13 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore - -from google.protobuf import duration_pb2 as duration # type: ignore -from google.protobuf import timestamp_pb2 as timestamp # type: ignore -from google.rpc import status_pb2 as status # type: ignore +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( @@ -88,7 +85,6 @@ class Likelihood(proto.Enum): class AnnotateVideoRequest(proto.Message): r"""Video annotation request. - Attributes: input_uri (str): Input video location. Currently, only `Google Cloud @@ -130,22 +126,16 @@ class AnnotateVideoRequest(proto.Message): a region will be determined based on video file location. """ - input_uri = proto.Field(proto.STRING, number=1) - - input_content = proto.Field(proto.BYTES, number=6) - + input_uri = proto.Field(proto.STRING, number=1,) + input_content = proto.Field(proto.BYTES, number=6,) features = proto.RepeatedField(proto.ENUM, number=2, enum="Feature",) - video_context = proto.Field(proto.MESSAGE, number=3, message="VideoContext",) - - output_uri = proto.Field(proto.STRING, number=4) - - location_id = proto.Field(proto.STRING, number=5) + output_uri = proto.Field(proto.STRING, number=4,) + location_id = proto.Field(proto.STRING, number=5,) class VideoContext(proto.Message): r"""Video context and/or feature-specific parameters. - Attributes: segments (Sequence[google.cloud.videointelligence_v1p2beta1.types.VideoSegment]): Video segments to annotate. The segments may @@ -163,19 +153,15 @@ class VideoContext(proto.Message): """ segments = proto.RepeatedField(proto.MESSAGE, number=1, message="VideoSegment",) - label_detection_config = proto.Field( proto.MESSAGE, number=2, message="LabelDetectionConfig", ) - shot_change_detection_config = proto.Field( proto.MESSAGE, number=3, message="ShotChangeDetectionConfig", ) - explicit_content_detection_config = proto.Field( proto.MESSAGE, number=4, message="ExplicitContentDetectionConfig", ) - text_detection_config = proto.Field( proto.MESSAGE, number=8, message="TextDetectionConfig", ) @@ -183,7 +169,6 @@ class VideoContext(proto.Message): class LabelDetectionConfig(proto.Message): r"""Config for LABEL_DETECTION. - Attributes: label_detection_mode (google.cloud.videointelligence_v1p2beta1.types.LabelDetectionMode): What labels should be detected with LABEL_DETECTION, in @@ -201,15 +186,12 @@ class LabelDetectionConfig(proto.Message): """ label_detection_mode = proto.Field(proto.ENUM, number=1, enum="LabelDetectionMode",) - - stationary_camera = proto.Field(proto.BOOL, number=2) - - model = proto.Field(proto.STRING, number=3) + stationary_camera = proto.Field(proto.BOOL, number=2,) + model = proto.Field(proto.STRING, number=3,) class ShotChangeDetectionConfig(proto.Message): r"""Config for SHOT_CHANGE_DETECTION. - Attributes: model (str): Model to use for shot change detection. @@ -217,12 +199,11 @@ class ShotChangeDetectionConfig(proto.Message): if unset) and "builtin/latest". """ - model = proto.Field(proto.STRING, number=1) + model = proto.Field(proto.STRING, number=1,) class ExplicitContentDetectionConfig(proto.Message): r"""Config for EXPLICIT_CONTENT_DETECTION. - Attributes: model (str): Model to use for explicit content detection. @@ -230,12 +211,11 @@ class ExplicitContentDetectionConfig(proto.Message): if unset) and "builtin/latest". """ - model = proto.Field(proto.STRING, number=1) + model = proto.Field(proto.STRING, number=1,) class TextDetectionConfig(proto.Message): r"""Config for TEXT_DETECTION. - Attributes: language_hints (Sequence[str]): Language hint can be specified if the @@ -248,12 +228,11 @@ class TextDetectionConfig(proto.Message): hint is provided. """ - language_hints = proto.RepeatedField(proto.STRING, number=1) + language_hints = proto.RepeatedField(proto.STRING, number=1,) class VideoSegment(proto.Message): r"""Video segment. - Attributes: start_time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the @@ -265,14 +244,16 @@ class VideoSegment(proto.Message): (inclusive). """ - start_time_offset = proto.Field(proto.MESSAGE, number=1, message=duration.Duration,) - - end_time_offset = proto.Field(proto.MESSAGE, number=2, message=duration.Duration,) + start_time_offset = proto.Field( + proto.MESSAGE, number=1, message=duration_pb2.Duration, + ) + end_time_offset = proto.Field( + proto.MESSAGE, number=2, message=duration_pb2.Duration, + ) class LabelSegment(proto.Message): r"""Video segment level annotation results for label detection. - Attributes: segment (google.cloud.videointelligence_v1p2beta1.types.VideoSegment): Video segment where a label was detected. @@ -281,13 +262,11 @@ class LabelSegment(proto.Message): """ segment = proto.Field(proto.MESSAGE, number=1, message="VideoSegment",) - - confidence = proto.Field(proto.FLOAT, number=2) + confidence = proto.Field(proto.FLOAT, number=2,) class LabelFrame(proto.Message): r"""Video frame level annotation results for label detection. - Attributes: time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the @@ -297,14 +276,12 @@ class LabelFrame(proto.Message): Confidence that the label is accurate. Range: [0, 1]. """ - time_offset = proto.Field(proto.MESSAGE, number=1, message=duration.Duration,) - - confidence = proto.Field(proto.FLOAT, number=2) + time_offset = proto.Field(proto.MESSAGE, number=1, message=duration_pb2.Duration,) + confidence = proto.Field(proto.FLOAT, number=2,) class Entity(proto.Message): r"""Detected entity from video analysis. - Attributes: entity_id (str): Opaque entity ID. Some IDs may be available in `Google @@ -316,16 +293,13 @@ class Entity(proto.Message): Language code for ``description`` in BCP-47 format. """ - entity_id = proto.Field(proto.STRING, number=1) - - description = proto.Field(proto.STRING, number=2) - - language_code = proto.Field(proto.STRING, number=3) + entity_id = proto.Field(proto.STRING, number=1,) + description = proto.Field(proto.STRING, number=2,) + language_code = proto.Field(proto.STRING, number=3,) class LabelAnnotation(proto.Message): r"""Label annotation. - Attributes: entity (google.cloud.videointelligence_v1p2beta1.types.Entity): Detected entity. @@ -342,17 +316,13 @@ class LabelAnnotation(proto.Message): """ entity = proto.Field(proto.MESSAGE, number=1, message="Entity",) - category_entities = proto.RepeatedField(proto.MESSAGE, number=2, message="Entity",) - segments = proto.RepeatedField(proto.MESSAGE, number=3, message="LabelSegment",) - frames = proto.RepeatedField(proto.MESSAGE, number=4, message="LabelFrame",) class ExplicitContentFrame(proto.Message): r"""Video frame level annotation results for explicit content. - Attributes: time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the @@ -362,8 +332,7 @@ class ExplicitContentFrame(proto.Message): Likelihood of the pornography content.. """ - time_offset = proto.Field(proto.MESSAGE, number=1, message=duration.Duration,) - + time_offset = proto.Field(proto.MESSAGE, number=1, message=duration_pb2.Duration,) pornography_likelihood = proto.Field(proto.ENUM, number=2, enum="Likelihood",) @@ -398,18 +367,14 @@ class NormalizedBoundingBox(proto.Message): Bottom Y coordinate. """ - left = proto.Field(proto.FLOAT, number=1) - - top = proto.Field(proto.FLOAT, number=2) - - right = proto.Field(proto.FLOAT, number=3) - - bottom = proto.Field(proto.FLOAT, number=4) + left = proto.Field(proto.FLOAT, number=1,) + top = proto.Field(proto.FLOAT, number=2,) + right = proto.Field(proto.FLOAT, number=3,) + bottom = proto.Field(proto.FLOAT, number=4,) class VideoAnnotationResults(proto.Message): r"""Annotation results for a single video. - Attributes: input_uri (str): Video file location in `Google Cloud @@ -445,37 +410,29 @@ class VideoAnnotationResults(proto.Message): may fail. """ - input_uri = proto.Field(proto.STRING, number=1) - + input_uri = proto.Field(proto.STRING, number=1,) segment_label_annotations = proto.RepeatedField( proto.MESSAGE, number=2, message="LabelAnnotation", ) - shot_label_annotations = proto.RepeatedField( proto.MESSAGE, number=3, message="LabelAnnotation", ) - frame_label_annotations = proto.RepeatedField( proto.MESSAGE, number=4, message="LabelAnnotation", ) - shot_annotations = proto.RepeatedField( proto.MESSAGE, number=6, message="VideoSegment", ) - explicit_annotation = proto.Field( proto.MESSAGE, number=7, message="ExplicitContentAnnotation", ) - text_annotations = proto.RepeatedField( proto.MESSAGE, number=12, message="TextAnnotation", ) - object_annotations = proto.RepeatedField( proto.MESSAGE, number=14, message="ObjectTrackingAnnotation", ) - - error = proto.Field(proto.MESSAGE, number=9, message=status.Status,) + error = proto.Field(proto.MESSAGE, number=9, message=status_pb2.Status,) class AnnotateVideoResponse(proto.Message): @@ -496,7 +453,6 @@ class AnnotateVideoResponse(proto.Message): class VideoAnnotationProgress(proto.Message): r"""Annotation progress for a single video. - Attributes: input_uri (str): Video file location in `Google Cloud @@ -510,13 +466,10 @@ class VideoAnnotationProgress(proto.Message): Time of the most recent update. """ - input_uri = proto.Field(proto.STRING, number=1) - - progress_percent = proto.Field(proto.INT32, number=2) - - start_time = proto.Field(proto.MESSAGE, number=3, message=timestamp.Timestamp,) - - update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp.Timestamp,) + input_uri = proto.Field(proto.STRING, number=1,) + progress_percent = proto.Field(proto.INT32, number=2,) + start_time = proto.Field(proto.MESSAGE, number=3, message=timestamp_pb2.Timestamp,) + update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp_pb2.Timestamp,) class AnnotateVideoProgress(proto.Message): @@ -547,9 +500,8 @@ class NormalizedVertex(proto.Message): Y coordinate. """ - x = proto.Field(proto.FLOAT, number=1) - - y = proto.Field(proto.FLOAT, number=2) + x = proto.Field(proto.FLOAT, number=1,) + y = proto.Field(proto.FLOAT, number=2,) class NormalizedBoundingPoly(proto.Message): @@ -576,7 +528,6 @@ class NormalizedBoundingPoly(proto.Message): class TextSegment(proto.Message): r"""Video segment level annotation results for text detection. - Attributes: segment (google.cloud.videointelligence_v1p2beta1.types.VideoSegment): Video segment where a text snippet was @@ -591,9 +542,7 @@ class TextSegment(proto.Message): """ segment = proto.Field(proto.MESSAGE, number=1, message="VideoSegment",) - - confidence = proto.Field(proto.FLOAT, number=2) - + confidence = proto.Field(proto.FLOAT, number=2,) frames = proto.RepeatedField(proto.MESSAGE, number=3, message="TextFrame",) @@ -613,8 +562,7 @@ class TextFrame(proto.Message): rotated_bounding_box = proto.Field( proto.MESSAGE, number=1, message="NormalizedBoundingPoly", ) - - time_offset = proto.Field(proto.MESSAGE, number=2, message=duration.Duration,) + time_offset = proto.Field(proto.MESSAGE, number=2, message=duration_pb2.Duration,) class TextAnnotation(proto.Message): @@ -630,8 +578,7 @@ class TextAnnotation(proto.Message): appears. """ - text = proto.Field(proto.STRING, number=1) - + text = proto.Field(proto.STRING, number=1,) segments = proto.RepeatedField(proto.MESSAGE, number=2, message="TextSegment",) @@ -651,13 +598,11 @@ class ObjectTrackingFrame(proto.Message): normalized_bounding_box = proto.Field( proto.MESSAGE, number=1, message="NormalizedBoundingBox", ) - - time_offset = proto.Field(proto.MESSAGE, number=2, message=duration.Duration,) + time_offset = proto.Field(proto.MESSAGE, number=2, message=duration_pb2.Duration,) class ObjectTrackingAnnotation(proto.Message): r"""Annotations corresponding to one tracked object. - Attributes: entity (google.cloud.videointelligence_v1p2beta1.types.Entity): Entity to specify the object category that @@ -674,13 +619,10 @@ class ObjectTrackingAnnotation(proto.Message): """ entity = proto.Field(proto.MESSAGE, number=1, message="Entity",) - - confidence = proto.Field(proto.FLOAT, number=4) - + confidence = proto.Field(proto.FLOAT, number=4,) frames = proto.RepeatedField( proto.MESSAGE, number=2, message="ObjectTrackingFrame", ) - segment = proto.Field(proto.MESSAGE, number=3, message="VideoSegment",) diff --git a/google/cloud/videointelligence_v1p3beta1/__init__.py b/google/cloud/videointelligence_v1p3beta1/__init__.py index 8ae655cd..0e8e6271 100644 --- a/google/cloud/videointelligence_v1p3beta1/__init__.py +++ b/google/cloud/videointelligence_v1p3beta1/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,7 +17,12 @@ from .services.streaming_video_intelligence_service import ( StreamingVideoIntelligenceServiceClient, ) +from .services.streaming_video_intelligence_service import ( + StreamingVideoIntelligenceServiceAsyncClient, +) from .services.video_intelligence_service import VideoIntelligenceServiceClient +from .services.video_intelligence_service import VideoIntelligenceServiceAsyncClient + from .types.video_intelligence import AnnotateVideoProgress from .types.video_intelligence import AnnotateVideoRequest from .types.video_intelligence import AnnotateVideoResponse @@ -33,13 +37,10 @@ from .types.video_intelligence import ExplicitContentFrame from .types.video_intelligence import FaceDetectionAnnotation from .types.video_intelligence import FaceDetectionConfig -from .types.video_intelligence import Feature from .types.video_intelligence import LabelAnnotation from .types.video_intelligence import LabelDetectionConfig -from .types.video_intelligence import LabelDetectionMode from .types.video_intelligence import LabelFrame from .types.video_intelligence import LabelSegment -from .types.video_intelligence import Likelihood from .types.video_intelligence import LogoRecognitionAnnotation from .types.video_intelligence import NormalizedBoundingBox from .types.video_intelligence import NormalizedBoundingPoly @@ -60,7 +61,6 @@ from .types.video_intelligence import StreamingAutomlClassificationConfig from .types.video_intelligence import StreamingAutomlObjectTrackingConfig from .types.video_intelligence import StreamingExplicitContentDetectionConfig -from .types.video_intelligence import StreamingFeature from .types.video_intelligence import StreamingLabelDetectionConfig from .types.video_intelligence import StreamingObjectTrackingConfig from .types.video_intelligence import StreamingShotChangeDetectionConfig @@ -78,9 +78,14 @@ from .types.video_intelligence import VideoContext from .types.video_intelligence import VideoSegment from .types.video_intelligence import WordInfo - +from .types.video_intelligence import Feature +from .types.video_intelligence import LabelDetectionMode +from .types.video_intelligence import Likelihood +from .types.video_intelligence import StreamingFeature __all__ = ( + "StreamingVideoIntelligenceServiceAsyncClient", + "VideoIntelligenceServiceAsyncClient", "AnnotateVideoProgress", "AnnotateVideoRequest", "AnnotateVideoResponse", @@ -139,7 +144,7 @@ "VideoAnnotationProgress", "VideoAnnotationResults", "VideoContext", + "VideoIntelligenceServiceClient", "VideoSegment", "WordInfo", - "VideoIntelligenceServiceClient", ) diff --git a/google/cloud/videointelligence_v1p3beta1/gapic_metadata.json b/google/cloud/videointelligence_v1p3beta1/gapic_metadata.json new file mode 100644 index 00000000..040a74a1 --- /dev/null +++ b/google/cloud/videointelligence_v1p3beta1/gapic_metadata.json @@ -0,0 +1,57 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.cloud.videointelligence_v1p3beta1", + "protoPackage": "google.cloud.videointelligence.v1p3beta1", + "schema": "1.0", + "services": { + "StreamingVideoIntelligenceService": { + "clients": { + "grpc": { + "libraryClient": "StreamingVideoIntelligenceServiceClient", + "rpcs": { + "StreamingAnnotateVideo": { + "methods": [ + "streaming_annotate_video" + ] + } + } + }, + "grpc-async": { + "libraryClient": "StreamingVideoIntelligenceServiceAsyncClient", + "rpcs": { + "StreamingAnnotateVideo": { + "methods": [ + "streaming_annotate_video" + ] + } + } + } + } + }, + "VideoIntelligenceService": { + "clients": { + "grpc": { + "libraryClient": "VideoIntelligenceServiceClient", + "rpcs": { + "AnnotateVideo": { + "methods": [ + "annotate_video" + ] + } + } + }, + "grpc-async": { + "libraryClient": "VideoIntelligenceServiceAsyncClient", + "rpcs": { + "AnnotateVideo": { + "methods": [ + "annotate_video" + ] + } + } + } + } + } + } +} diff --git a/google/cloud/videointelligence_v1p3beta1/services/__init__.py b/google/cloud/videointelligence_v1p3beta1/services/__init__.py index 42ffdf2b..4de65971 100644 --- a/google/cloud/videointelligence_v1p3beta1/services/__init__.py +++ b/google/cloud/videointelligence_v1p3beta1/services/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/__init__.py b/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/__init__.py index 6cba0cfb..d48a840b 100644 --- a/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/__init__.py +++ b/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .client import StreamingVideoIntelligenceServiceClient from .async_client import StreamingVideoIntelligenceServiceAsyncClient diff --git a/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/async_client.py b/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/async_client.py index dd530073..5b86c803 100644 --- a/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/async_client.py +++ b/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/async_client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict import functools import re @@ -31,15 +29,14 @@ 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 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 # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore from google.cloud.videointelligence_v1p3beta1.types import video_intelligence -from google.rpc import status_pb2 as status # type: ignore - +from google.rpc import status_pb2 # type: ignore from .transports.base import ( StreamingVideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO, @@ -66,28 +63,24 @@ class StreamingVideoIntelligenceServiceAsyncClient: parse_common_billing_account_path = staticmethod( StreamingVideoIntelligenceServiceClient.parse_common_billing_account_path ) - common_folder_path = staticmethod( StreamingVideoIntelligenceServiceClient.common_folder_path ) parse_common_folder_path = staticmethod( StreamingVideoIntelligenceServiceClient.parse_common_folder_path ) - common_organization_path = staticmethod( StreamingVideoIntelligenceServiceClient.common_organization_path ) parse_common_organization_path = staticmethod( StreamingVideoIntelligenceServiceClient.parse_common_organization_path ) - common_project_path = staticmethod( StreamingVideoIntelligenceServiceClient.common_project_path ) parse_common_project_path = staticmethod( StreamingVideoIntelligenceServiceClient.parse_common_project_path ) - common_location_path = staticmethod( StreamingVideoIntelligenceServiceClient.common_location_path ) @@ -97,7 +90,8 @@ class StreamingVideoIntelligenceServiceAsyncClient: @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -112,7 +106,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -129,7 +123,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> StreamingVideoIntelligenceServiceTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: StreamingVideoIntelligenceServiceTransport: The transport used by the client instance. @@ -144,14 +138,14 @@ def transport(self) -> StreamingVideoIntelligenceServiceTransport: def __init__( self, *, - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, transport: Union[ str, StreamingVideoIntelligenceServiceTransport ] = "grpc_asyncio", client_options: ClientOptions = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the streaming video intelligence service client. + """Instantiates the streaming video intelligence service client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -183,7 +177,6 @@ def __init__( google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport creation failed for any reason. """ - self._client = StreamingVideoIntelligenceServiceClient( credentials=credentials, transport=transport, @@ -238,7 +231,8 @@ def streaming_annotate_video( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=10800.0, ), diff --git a/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/client.py b/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/client.py index 9780eaf9..7ca902cd 100644 --- a/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/client.py +++ b/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from distutils import util import os @@ -33,18 +31,17 @@ 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 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 # type: ignore +from google.auth import credentials as ga_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.videointelligence_v1p3beta1.types import video_intelligence -from google.rpc import status_pb2 as status # type: ignore - +from google.rpc import status_pb2 # type: ignore from .transports.base import ( StreamingVideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO, @@ -74,7 +71,7 @@ class StreamingVideoIntelligenceServiceClientMeta(type): def get_transport_class( cls, label: str = None, ) -> Type[StreamingVideoIntelligenceServiceTransport]: - """Return an appropriate transport class. + """Returns an appropriate transport class. Args: label: The name of the desired transport. If none is @@ -99,7 +96,8 @@ class StreamingVideoIntelligenceServiceClient( @staticmethod def _get_default_mtls_endpoint(api_endpoint): - """Convert api endpoint to mTLS endpoint. + """Converts api endpoint to mTLS endpoint. + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. Args: @@ -133,7 +131,8 @@ def _get_default_mtls_endpoint(api_endpoint): @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -150,7 +149,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -169,16 +168,17 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> StreamingVideoIntelligenceServiceTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: - StreamingVideoIntelligenceServiceTransport: The transport used by the client instance. + StreamingVideoIntelligenceServiceTransport: The transport used by the client + instance. """ return self._transport @staticmethod def common_billing_account_path(billing_account: str,) -> str: - """Return a fully-qualified billing_account string.""" + """Returns a fully-qualified billing_account string.""" return "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -191,7 +191,7 @@ def parse_common_billing_account_path(path: str) -> Dict[str, str]: @staticmethod def common_folder_path(folder: str,) -> str: - """Return a fully-qualified folder string.""" + """Returns a fully-qualified folder string.""" return "folders/{folder}".format(folder=folder,) @staticmethod @@ -202,7 +202,7 @@ def parse_common_folder_path(path: str) -> Dict[str, str]: @staticmethod def common_organization_path(organization: str,) -> str: - """Return a fully-qualified organization string.""" + """Returns a fully-qualified organization string.""" return "organizations/{organization}".format(organization=organization,) @staticmethod @@ -213,7 +213,7 @@ def parse_common_organization_path(path: str) -> Dict[str, str]: @staticmethod def common_project_path(project: str,) -> str: - """Return a fully-qualified project string.""" + """Returns a fully-qualified project string.""" return "projects/{project}".format(project=project,) @staticmethod @@ -224,7 +224,7 @@ def parse_common_project_path(path: str) -> Dict[str, str]: @staticmethod def common_location_path(project: str, location: str,) -> str: - """Return a fully-qualified location string.""" + """Returns a fully-qualified location string.""" return "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -238,12 +238,12 @@ def parse_common_location_path(path: str) -> Dict[str, str]: def __init__( self, *, - credentials: Optional[credentials.Credentials] = None, + credentials: Optional[ga_credentials.Credentials] = None, transport: Union[str, StreamingVideoIntelligenceServiceTransport, None] = None, client_options: Optional[client_options_lib.ClientOptions] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the streaming video intelligence service client. + """Instantiates the streaming video intelligence service client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -298,9 +298,10 @@ def __init__( 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 - ) + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None # Figure out which api endpoint to use. if client_options.api_endpoint is not None: @@ -312,12 +313,14 @@ def __init__( 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 - ) + if is_mtls: + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = self.DEFAULT_ENDPOINT else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" ) # Save or instantiate the transport. @@ -332,8 +335,8 @@ def __init__( ) if client_options.scopes: raise ValueError( - "When providing a transport instance, " - "provide its scopes directly." + "When providing a transport instance, provide its scopes " + "directly." ) self._transport = transport else: diff --git a/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/__init__.py b/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/__init__.py index 76a8e8e4..293273a8 100644 --- a/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/__init__.py +++ b/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from typing import Dict, Type diff --git a/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/base.py b/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/base.py index c0089a2e..6c553018 100644 --- a/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/base.py +++ b/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/base.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,20 +13,20 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import abc -import typing +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union +import packaging.version import pkg_resources -from google import auth # type: ignore -from google.api_core import exceptions # type: ignore +import google.auth # type: ignore +import google.api_core # 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 # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.cloud.videointelligence_v1p3beta1.types import video_intelligence - try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=pkg_resources.get_distribution( @@ -37,27 +36,41 @@ 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 + +_API_CORE_VERSION = google.api_core.__version__ + class StreamingVideoIntelligenceServiceTransport(abc.ABC): """Abstract transport class for StreamingVideoIntelligenceService.""" AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + DEFAULT_HOST: str = "videointelligence.googleapis.com" + def __init__( self, *, - host: str = "videointelligence.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, + host: str = DEFAULT_HOST, + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: 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. + 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 @@ -66,7 +79,7 @@ def __init__( 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. + scopes (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): @@ -80,29 +93,76 @@ def __init__( host += ":443" self._host = host + scopes_kwargs = self._get_scopes_kwargs(self._host, scopes) + # Save the scopes. self._scopes = scopes or self.AUTH_SCOPES # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: - raise exceptions.DuplicateCredentialArgs( + raise core_exceptions.DuplicateCredentialArgs( "'credentials_file' and 'credentials' are mutually exclusive" ) if credentials_file is not None: - credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, **scopes_kwargs, quota_project_id=quota_project_id ) elif credentials is None: - credentials, _ = auth.default( - scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials + # TODO(busunkim): These two class methods are in the base transport + # to avoid duplicating code across the transport classes. These functions + # should be deleted once the minimum required versions of google-api-core + # and google-auth are 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 + + # TODO: Remove this function once google-api-core >= 1.26.0 is required + @classmethod + def _get_self_signed_jwt_kwargs( + cls, host: str, scopes: Optional[Sequence[str]] + ) -> Dict[str, Union[Optional[Sequence[str]], str]]: + """Returns kwargs to pass to grpc_helpers.create_channel depending on the google-api-core version""" + + self_signed_jwt_kwargs: Dict[str, Union[Optional[Sequence[str]], str]] = {} + + if _API_CORE_VERSION and ( + packaging.version.parse(_API_CORE_VERSION) + >= packaging.version.parse("1.26.0") + ): + self_signed_jwt_kwargs["default_scopes"] = cls.AUTH_SCOPES + self_signed_jwt_kwargs["scopes"] = scopes + self_signed_jwt_kwargs["default_host"] = cls.DEFAULT_HOST + else: + self_signed_jwt_kwargs["scopes"] = scopes or cls.AUTH_SCOPES + + return self_signed_jwt_kwargs + def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { @@ -113,7 +173,8 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=10800.0, ), @@ -125,11 +186,11 @@ def _prep_wrapped_messages(self, client_info): @property def streaming_annotate_video( self, - ) -> typing.Callable[ + ) -> Callable[ [video_intelligence.StreamingAnnotateVideoRequest], - typing.Union[ + Union[ video_intelligence.StreamingAnnotateVideoResponse, - typing.Awaitable[video_intelligence.StreamingAnnotateVideoResponse], + Awaitable[video_intelligence.StreamingAnnotateVideoResponse], ], ]: raise NotImplementedError() diff --git a/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/grpc.py b/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/grpc.py index 7ba3e999..4383118d 100644 --- a/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/grpc.py +++ b/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/grpc.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,20 +13,18 @@ # 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 typing import Callable, Dict, Optional, Sequence, Tuple, Union 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 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore import grpc # type: ignore from google.cloud.videointelligence_v1p3beta1.types import video_intelligence - from .base import StreamingVideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO @@ -52,7 +49,7 @@ def __init__( self, *, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Sequence[str] = None, channel: grpc.Channel = None, @@ -66,7 +63,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + 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 @@ -176,7 +174,7 @@ def __init__( def create_channel( cls, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -207,13 +205,15 @@ def create_channel( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) diff --git a/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/grpc_asyncio.py b/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/grpc_asyncio.py index e7a7cb54..9df05fbf 100644 --- a/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/grpc_asyncio.py +++ b/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/grpc_asyncio.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,21 +13,19 @@ # 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 typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union 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 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 from google.cloud.videointelligence_v1p3beta1.types import video_intelligence - from .base import StreamingVideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO from .grpc import StreamingVideoIntelligenceServiceGrpcTransport @@ -55,7 +52,7 @@ class StreamingVideoIntelligenceServiceGrpcAsyncIOTransport( def create_channel( cls, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -82,13 +79,15 @@ def create_channel( Returns: aio.Channel: A gRPC AsyncIO channel object. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers_async.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) @@ -96,7 +95,7 @@ def __init__( self, *, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, channel: aio.Channel = None, @@ -110,7 +109,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + 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 @@ -168,7 +168,6 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - else: if api_mtls_endpoint: host = api_mtls_endpoint diff --git a/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/__init__.py b/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/__init__.py index 55932028..02e942f8 100644 --- a/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/__init__.py +++ b/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .client import VideoIntelligenceServiceClient from .async_client import VideoIntelligenceServiceAsyncClient diff --git a/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/async_client.py b/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/async_client.py index 0c2d80d5..b9481b55 100644 --- a/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/async_client.py +++ b/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/async_client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict import functools import re @@ -22,16 +20,15 @@ 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 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 # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore from google.cloud.videointelligence_v1p3beta1.types import video_intelligence - from .transports.base import VideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO from .transports.grpc_asyncio import VideoIntelligenceServiceGrpcAsyncIOTransport from .client import VideoIntelligenceServiceClient @@ -51,26 +48,22 @@ class VideoIntelligenceServiceAsyncClient: parse_common_billing_account_path = staticmethod( VideoIntelligenceServiceClient.parse_common_billing_account_path ) - common_folder_path = staticmethod(VideoIntelligenceServiceClient.common_folder_path) parse_common_folder_path = staticmethod( VideoIntelligenceServiceClient.parse_common_folder_path ) - common_organization_path = staticmethod( VideoIntelligenceServiceClient.common_organization_path ) parse_common_organization_path = staticmethod( VideoIntelligenceServiceClient.parse_common_organization_path ) - common_project_path = staticmethod( VideoIntelligenceServiceClient.common_project_path ) parse_common_project_path = staticmethod( VideoIntelligenceServiceClient.parse_common_project_path ) - common_location_path = staticmethod( VideoIntelligenceServiceClient.common_location_path ) @@ -80,7 +73,8 @@ class VideoIntelligenceServiceAsyncClient: @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -95,7 +89,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -112,7 +106,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> VideoIntelligenceServiceTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: VideoIntelligenceServiceTransport: The transport used by the client instance. @@ -127,12 +121,12 @@ def transport(self) -> VideoIntelligenceServiceTransport: def __init__( self, *, - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, transport: Union[str, VideoIntelligenceServiceTransport] = "grpc_asyncio", client_options: ClientOptions = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the video intelligence service client. + """Instantiates the video intelligence service client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -164,7 +158,6 @@ def __init__( google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport creation failed for any reason. """ - self._client = VideoIntelligenceServiceClient( credentials=credentials, transport=transport, @@ -217,7 +210,6 @@ async def annotate_video( This corresponds to the ``features`` 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. @@ -247,10 +239,8 @@ async def annotate_video( # If we have keyword arguments corresponding to fields on the # request, apply these. - if input_uri is not None: request.input_uri = input_uri - if features: request.features.extend(features) @@ -263,7 +253,8 @@ async def annotate_video( maximum=120.0, multiplier=2.5, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=600.0, ), diff --git a/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/client.py b/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/client.py index 80b61de8..d8ed5cac 100644 --- a/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/client.py +++ b/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from distutils import util import os @@ -23,10 +21,10 @@ 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 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 # type: ignore +from google.auth import credentials as ga_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 @@ -35,7 +33,6 @@ from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore from google.cloud.videointelligence_v1p3beta1.types import video_intelligence - from .transports.base import VideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO from .transports.grpc import VideoIntelligenceServiceGrpcTransport from .transports.grpc_asyncio import VideoIntelligenceServiceGrpcAsyncIOTransport @@ -58,7 +55,7 @@ class VideoIntelligenceServiceClientMeta(type): def get_transport_class( cls, label: str = None, ) -> Type[VideoIntelligenceServiceTransport]: - """Return an appropriate transport class. + """Returns an appropriate transport class. Args: label: The name of the desired transport. If none is @@ -81,7 +78,8 @@ class VideoIntelligenceServiceClient(metaclass=VideoIntelligenceServiceClientMet @staticmethod def _get_default_mtls_endpoint(api_endpoint): - """Convert api endpoint to mTLS endpoint. + """Converts api endpoint to mTLS endpoint. + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. Args: @@ -115,7 +113,8 @@ def _get_default_mtls_endpoint(api_endpoint): @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -132,7 +131,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -151,16 +150,17 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> VideoIntelligenceServiceTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: - VideoIntelligenceServiceTransport: The transport used by the client instance. + VideoIntelligenceServiceTransport: The transport used by the client + instance. """ return self._transport @staticmethod def common_billing_account_path(billing_account: str,) -> str: - """Return a fully-qualified billing_account string.""" + """Returns a fully-qualified billing_account string.""" return "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -173,7 +173,7 @@ def parse_common_billing_account_path(path: str) -> Dict[str, str]: @staticmethod def common_folder_path(folder: str,) -> str: - """Return a fully-qualified folder string.""" + """Returns a fully-qualified folder string.""" return "folders/{folder}".format(folder=folder,) @staticmethod @@ -184,7 +184,7 @@ def parse_common_folder_path(path: str) -> Dict[str, str]: @staticmethod def common_organization_path(organization: str,) -> str: - """Return a fully-qualified organization string.""" + """Returns a fully-qualified organization string.""" return "organizations/{organization}".format(organization=organization,) @staticmethod @@ -195,7 +195,7 @@ def parse_common_organization_path(path: str) -> Dict[str, str]: @staticmethod def common_project_path(project: str,) -> str: - """Return a fully-qualified project string.""" + """Returns a fully-qualified project string.""" return "projects/{project}".format(project=project,) @staticmethod @@ -206,7 +206,7 @@ def parse_common_project_path(path: str) -> Dict[str, str]: @staticmethod def common_location_path(project: str, location: str,) -> str: - """Return a fully-qualified location string.""" + """Returns a fully-qualified location string.""" return "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -220,12 +220,12 @@ def parse_common_location_path(path: str) -> Dict[str, str]: def __init__( self, *, - credentials: Optional[credentials.Credentials] = None, + credentials: Optional[ga_credentials.Credentials] = None, transport: Union[str, VideoIntelligenceServiceTransport, None] = None, client_options: Optional[client_options_lib.ClientOptions] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the video intelligence service client. + """Instantiates the video intelligence service client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -280,9 +280,10 @@ def __init__( 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 - ) + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None # Figure out which api endpoint to use. if client_options.api_endpoint is not None: @@ -294,12 +295,14 @@ def __init__( 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 - ) + if is_mtls: + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = self.DEFAULT_ENDPOINT else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" ) # Save or instantiate the transport. @@ -314,8 +317,8 @@ def __init__( ) if client_options.scopes: raise ValueError( - "When providing a transport instance, " - "provide its scopes directly." + "When providing a transport instance, provide its scopes " + "directly." ) self._transport = transport else: @@ -375,7 +378,6 @@ def annotate_video( This corresponds to the ``features`` 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. @@ -407,10 +409,8 @@ def annotate_video( # there are no flattened fields. if not isinstance(request, video_intelligence.AnnotateVideoRequest): request = video_intelligence.AnnotateVideoRequest(request) - # If we have keyword arguments corresponding to fields on the # request, apply these. - if input_uri is not None: request.input_uri = input_uri if features is not None: diff --git a/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/__init__.py b/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/__init__.py index fef86838..8ae3c6cb 100644 --- a/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/__init__.py +++ b/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from typing import Dict, Type diff --git a/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/base.py b/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/base.py index e1f08ea9..05966977 100644 --- a/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/base.py +++ b/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/base.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,21 +13,21 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import abc -import typing +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union +import packaging.version import pkg_resources -from google import auth # type: ignore -from google.api_core import exceptions # type: ignore +import google.auth # type: ignore +import google.api_core # 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.api_core import operations_v1 # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.cloud.videointelligence_v1p3beta1.types import video_intelligence -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( @@ -39,27 +38,41 @@ 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 + +_API_CORE_VERSION = google.api_core.__version__ + class VideoIntelligenceServiceTransport(abc.ABC): """Abstract transport class for VideoIntelligenceService.""" AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + DEFAULT_HOST: str = "videointelligence.googleapis.com" + def __init__( self, *, - host: str = "videointelligence.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, + host: str = DEFAULT_HOST, + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: 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. + 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 @@ -68,7 +81,7 @@ def __init__( 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. + scopes (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): @@ -82,29 +95,76 @@ def __init__( host += ":443" self._host = host + scopes_kwargs = self._get_scopes_kwargs(self._host, scopes) + # Save the scopes. self._scopes = scopes or self.AUTH_SCOPES # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: - raise exceptions.DuplicateCredentialArgs( + raise core_exceptions.DuplicateCredentialArgs( "'credentials_file' and 'credentials' are mutually exclusive" ) if credentials_file is not None: - credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, **scopes_kwargs, quota_project_id=quota_project_id ) elif credentials is None: - credentials, _ = auth.default( - scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials + # TODO(busunkim): These two class methods are in the base transport + # to avoid duplicating code across the transport classes. These functions + # should be deleted once the minimum required versions of google-api-core + # and google-auth are 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 + + # TODO: Remove this function once google-api-core >= 1.26.0 is required + @classmethod + def _get_self_signed_jwt_kwargs( + cls, host: str, scopes: Optional[Sequence[str]] + ) -> Dict[str, Union[Optional[Sequence[str]], str]]: + """Returns kwargs to pass to grpc_helpers.create_channel depending on the google-api-core version""" + + self_signed_jwt_kwargs: Dict[str, Union[Optional[Sequence[str]], str]] = {} + + if _API_CORE_VERSION and ( + packaging.version.parse(_API_CORE_VERSION) + >= packaging.version.parse("1.26.0") + ): + self_signed_jwt_kwargs["default_scopes"] = cls.AUTH_SCOPES + self_signed_jwt_kwargs["scopes"] = scopes + self_signed_jwt_kwargs["default_host"] = cls.DEFAULT_HOST + else: + self_signed_jwt_kwargs["scopes"] = scopes or cls.AUTH_SCOPES + + return self_signed_jwt_kwargs + def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { @@ -115,7 +175,8 @@ def _prep_wrapped_messages(self, client_info): maximum=120.0, multiplier=2.5, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=600.0, ), @@ -132,9 +193,9 @@ def operations_client(self) -> operations_v1.OperationsClient: @property def annotate_video( self, - ) -> typing.Callable[ + ) -> Callable[ [video_intelligence.AnnotateVideoRequest], - typing.Union[operations.Operation, typing.Awaitable[operations.Operation]], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], ]: raise NotImplementedError() diff --git a/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/grpc.py b/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/grpc.py index af34005d..5131e47e 100644 --- a/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/grpc.py +++ b/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/grpc.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,22 +13,20 @@ # 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 typing import Callable, Dict, Optional, Sequence, Tuple, Union from google.api_core import grpc_helpers # type: ignore from google.api_core import operations_v1 # type: ignore from google.api_core import gapic_v1 # type: ignore -from google import auth # type: ignore -from google.auth import credentials # type: ignore +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore import grpc # type: ignore from google.cloud.videointelligence_v1p3beta1.types import video_intelligence -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore from .base import VideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO @@ -52,7 +49,7 @@ def __init__( self, *, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Sequence[str] = None, channel: grpc.Channel = None, @@ -66,7 +63,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + 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 @@ -177,7 +175,7 @@ def __init__( def create_channel( cls, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -208,13 +206,15 @@ def create_channel( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) @@ -241,7 +241,7 @@ def operations_client(self) -> operations_v1.OperationsClient: @property def annotate_video( self, - ) -> Callable[[video_intelligence.AnnotateVideoRequest], operations.Operation]: + ) -> Callable[[video_intelligence.AnnotateVideoRequest], operations_pb2.Operation]: r"""Return a callable for the annotate video method over gRPC. Performs asynchronous video annotation. Progress and results can @@ -264,7 +264,7 @@ def annotate_video( self._stubs["annotate_video"] = self.grpc_channel.unary_unary( "/google.cloud.videointelligence.v1p3beta1.VideoIntelligenceService/AnnotateVideo", request_serializer=video_intelligence.AnnotateVideoRequest.serialize, - response_deserializer=operations.Operation.FromString, + response_deserializer=operations_pb2.Operation.FromString, ) return self._stubs["annotate_video"] diff --git a/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/grpc_asyncio.py b/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/grpc_asyncio.py index 5b844350..7b3dfe3a 100644 --- a/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/grpc_asyncio.py +++ b/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/grpc_asyncio.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,23 +13,21 @@ # 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 typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore -from google import auth # type: ignore -from google.auth import credentials # 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 from google.cloud.videointelligence_v1p3beta1.types import video_intelligence -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore from .base import VideoIntelligenceServiceTransport, DEFAULT_CLIENT_INFO from .grpc import VideoIntelligenceServiceGrpcTransport @@ -55,7 +52,7 @@ class VideoIntelligenceServiceGrpcAsyncIOTransport(VideoIntelligenceServiceTrans def create_channel( cls, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -82,13 +79,15 @@ def create_channel( Returns: aio.Channel: A gRPC AsyncIO channel object. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers_async.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) @@ -96,7 +95,7 @@ def __init__( self, *, host: str = "videointelligence.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, channel: aio.Channel = None, @@ -110,7 +109,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + 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 @@ -169,7 +169,6 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - else: if api_mtls_endpoint: host = api_mtls_endpoint @@ -248,7 +247,7 @@ def operations_client(self) -> operations_v1.OperationsAsyncClient: def annotate_video( self, ) -> Callable[ - [video_intelligence.AnnotateVideoRequest], Awaitable[operations.Operation] + [video_intelligence.AnnotateVideoRequest], Awaitable[operations_pb2.Operation] ]: r"""Return a callable for the annotate video method over gRPC. @@ -272,7 +271,7 @@ def annotate_video( self._stubs["annotate_video"] = self.grpc_channel.unary_unary( "/google.cloud.videointelligence.v1p3beta1.VideoIntelligenceService/AnnotateVideo", request_serializer=video_intelligence.AnnotateVideoRequest.serialize, - response_deserializer=operations.Operation.FromString, + response_deserializer=operations_pb2.Operation.FromString, ) return self._stubs["annotate_video"] diff --git a/google/cloud/videointelligence_v1p3beta1/types/__init__.py b/google/cloud/videointelligence_v1p3beta1/types/__init__.py index 393ab02f..d74910c4 100644 --- a/google/cloud/videointelligence_v1p3beta1/types/__init__.py +++ b/google/cloud/videointelligence_v1p3beta1/types/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .video_intelligence import ( AnnotateVideoProgress, AnnotateVideoRequest, diff --git a/google/cloud/videointelligence_v1p3beta1/types/video_intelligence.py b/google/cloud/videointelligence_v1p3beta1/types/video_intelligence.py index 4cce08e7..fb3374ee 100644 --- a/google/cloud/videointelligence_v1p3beta1/types/video_intelligence.py +++ b/google/cloud/videointelligence_v1p3beta1/types/video_intelligence.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,13 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore - -from google.protobuf import duration_pb2 as duration # type: ignore -from google.protobuf import timestamp_pb2 as timestamp # type: ignore -from google.rpc import status_pb2 as status # type: ignore +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( @@ -136,7 +133,6 @@ class Feature(proto.Enum): class AnnotateVideoRequest(proto.Message): r"""Video annotation request. - Attributes: input_uri (str): Input video location. Currently, only `Cloud @@ -177,22 +173,16 @@ class AnnotateVideoRequest(proto.Message): the region will be determined based on video file location. """ - input_uri = proto.Field(proto.STRING, number=1) - - input_content = proto.Field(proto.BYTES, number=6) - + input_uri = proto.Field(proto.STRING, number=1,) + input_content = proto.Field(proto.BYTES, number=6,) features = proto.RepeatedField(proto.ENUM, number=2, enum="Feature",) - video_context = proto.Field(proto.MESSAGE, number=3, message="VideoContext",) - - output_uri = proto.Field(proto.STRING, number=4) - - location_id = proto.Field(proto.STRING, number=5) + output_uri = proto.Field(proto.STRING, number=4,) + location_id = proto.Field(proto.STRING, number=5,) class VideoContext(proto.Message): r"""Video context and/or feature-specific parameters. - Attributes: segments (Sequence[google.cloud.videointelligence_v1p3beta1.types.VideoSegment]): Video segments to annotate. The segments may @@ -218,35 +208,27 @@ class VideoContext(proto.Message): """ segments = proto.RepeatedField(proto.MESSAGE, number=1, message="VideoSegment",) - label_detection_config = proto.Field( proto.MESSAGE, number=2, message="LabelDetectionConfig", ) - shot_change_detection_config = proto.Field( proto.MESSAGE, number=3, message="ShotChangeDetectionConfig", ) - explicit_content_detection_config = proto.Field( proto.MESSAGE, number=4, message="ExplicitContentDetectionConfig", ) - face_detection_config = proto.Field( proto.MESSAGE, number=5, message="FaceDetectionConfig", ) - speech_transcription_config = proto.Field( proto.MESSAGE, number=6, message="SpeechTranscriptionConfig", ) - text_detection_config = proto.Field( proto.MESSAGE, number=8, message="TextDetectionConfig", ) - person_detection_config = proto.Field( proto.MESSAGE, number=11, message="PersonDetectionConfig", ) - object_tracking_config = proto.Field( proto.MESSAGE, number=13, message="ObjectTrackingConfig", ) @@ -254,7 +236,6 @@ class VideoContext(proto.Message): class LabelDetectionConfig(proto.Message): r"""Config for LABEL_DETECTION. - Attributes: label_detection_mode (google.cloud.videointelligence_v1p3beta1.types.LabelDetectionMode): What labels should be detected with LABEL_DETECTION, in @@ -288,19 +269,14 @@ class LabelDetectionConfig(proto.Message): """ label_detection_mode = proto.Field(proto.ENUM, number=1, enum="LabelDetectionMode",) - - stationary_camera = proto.Field(proto.BOOL, number=2) - - model = proto.Field(proto.STRING, number=3) - - frame_confidence_threshold = proto.Field(proto.FLOAT, number=4) - - video_confidence_threshold = proto.Field(proto.FLOAT, number=5) + stationary_camera = proto.Field(proto.BOOL, number=2,) + model = proto.Field(proto.STRING, number=3,) + frame_confidence_threshold = proto.Field(proto.FLOAT, number=4,) + video_confidence_threshold = proto.Field(proto.FLOAT, number=5,) class ShotChangeDetectionConfig(proto.Message): r"""Config for SHOT_CHANGE_DETECTION. - Attributes: model (str): Model to use for shot change detection. @@ -308,12 +284,11 @@ class ShotChangeDetectionConfig(proto.Message): if unset) and "builtin/latest". """ - model = proto.Field(proto.STRING, number=1) + model = proto.Field(proto.STRING, number=1,) class ObjectTrackingConfig(proto.Message): r"""Config for OBJECT_TRACKING. - Attributes: model (str): Model to use for object tracking. @@ -321,12 +296,11 @@ class ObjectTrackingConfig(proto.Message): if unset) and "builtin/latest". """ - model = proto.Field(proto.STRING, number=1) + model = proto.Field(proto.STRING, number=1,) class ExplicitContentDetectionConfig(proto.Message): r"""Config for EXPLICIT_CONTENT_DETECTION. - Attributes: model (str): Model to use for explicit content detection. @@ -334,12 +308,11 @@ class ExplicitContentDetectionConfig(proto.Message): if unset) and "builtin/latest". """ - model = proto.Field(proto.STRING, number=1) + model = proto.Field(proto.STRING, number=1,) class FaceDetectionConfig(proto.Message): r"""Config for FACE_DETECTION. - Attributes: model (str): Model to use for face detection. @@ -354,16 +327,13 @@ class FaceDetectionConfig(proto.Message): 'include_bounding_boxes' is set to false. """ - model = proto.Field(proto.STRING, number=1) - - include_bounding_boxes = proto.Field(proto.BOOL, number=2) - - include_attributes = proto.Field(proto.BOOL, number=5) + model = proto.Field(proto.STRING, number=1,) + include_bounding_boxes = proto.Field(proto.BOOL, number=2,) + include_attributes = proto.Field(proto.BOOL, number=5,) class PersonDetectionConfig(proto.Message): r"""Config for PERSON_DETECTION. - Attributes: include_bounding_boxes (bool): Whether bounding boxes are included in the @@ -378,16 +348,13 @@ class PersonDetectionConfig(proto.Message): 'include_bounding_boxes' is set to false. """ - include_bounding_boxes = proto.Field(proto.BOOL, number=1) - - include_pose_landmarks = proto.Field(proto.BOOL, number=2) - - include_attributes = proto.Field(proto.BOOL, number=3) + include_bounding_boxes = proto.Field(proto.BOOL, number=1,) + include_pose_landmarks = proto.Field(proto.BOOL, number=2,) + include_attributes = proto.Field(proto.BOOL, number=3,) class TextDetectionConfig(proto.Message): r"""Config for TEXT_DETECTION. - Attributes: language_hints (Sequence[str]): Language hint can be specified if the @@ -404,14 +371,12 @@ class TextDetectionConfig(proto.Message): if unset) and "builtin/latest". """ - language_hints = proto.RepeatedField(proto.STRING, number=1) - - model = proto.Field(proto.STRING, number=2) + language_hints = proto.RepeatedField(proto.STRING, number=1,) + model = proto.Field(proto.STRING, number=2,) class VideoSegment(proto.Message): r"""Video segment. - Attributes: start_time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the @@ -423,14 +388,16 @@ class VideoSegment(proto.Message): (inclusive). """ - start_time_offset = proto.Field(proto.MESSAGE, number=1, message=duration.Duration,) - - end_time_offset = proto.Field(proto.MESSAGE, number=2, message=duration.Duration,) + start_time_offset = proto.Field( + proto.MESSAGE, number=1, message=duration_pb2.Duration, + ) + end_time_offset = proto.Field( + proto.MESSAGE, number=2, message=duration_pb2.Duration, + ) class LabelSegment(proto.Message): r"""Video segment level annotation results for label detection. - Attributes: segment (google.cloud.videointelligence_v1p3beta1.types.VideoSegment): Video segment where a label was detected. @@ -439,13 +406,11 @@ class LabelSegment(proto.Message): """ segment = proto.Field(proto.MESSAGE, number=1, message="VideoSegment",) - - confidence = proto.Field(proto.FLOAT, number=2) + confidence = proto.Field(proto.FLOAT, number=2,) class LabelFrame(proto.Message): r"""Video frame level annotation results for label detection. - Attributes: time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the @@ -455,14 +420,12 @@ class LabelFrame(proto.Message): Confidence that the label is accurate. Range: [0, 1]. """ - time_offset = proto.Field(proto.MESSAGE, number=1, message=duration.Duration,) - - confidence = proto.Field(proto.FLOAT, number=2) + time_offset = proto.Field(proto.MESSAGE, number=1, message=duration_pb2.Duration,) + confidence = proto.Field(proto.FLOAT, number=2,) class Entity(proto.Message): r"""Detected entity from video analysis. - Attributes: entity_id (str): Opaque entity ID. Some IDs may be available in `Google @@ -474,16 +437,13 @@ class Entity(proto.Message): Language code for ``description`` in BCP-47 format. """ - entity_id = proto.Field(proto.STRING, number=1) - - description = proto.Field(proto.STRING, number=2) - - language_code = proto.Field(proto.STRING, number=3) + entity_id = proto.Field(proto.STRING, number=1,) + description = proto.Field(proto.STRING, number=2,) + language_code = proto.Field(proto.STRING, number=3,) class LabelAnnotation(proto.Message): r"""Label annotation. - Attributes: entity (google.cloud.videointelligence_v1p3beta1.types.Entity): Detected entity. @@ -500,17 +460,13 @@ class LabelAnnotation(proto.Message): """ entity = proto.Field(proto.MESSAGE, number=1, message="Entity",) - category_entities = proto.RepeatedField(proto.MESSAGE, number=2, message="Entity",) - segments = proto.RepeatedField(proto.MESSAGE, number=3, message="LabelSegment",) - frames = proto.RepeatedField(proto.MESSAGE, number=4, message="LabelFrame",) class ExplicitContentFrame(proto.Message): r"""Video frame level annotation results for explicit content. - Attributes: time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the @@ -520,8 +476,7 @@ class ExplicitContentFrame(proto.Message): Likelihood of the pornography content.. """ - time_offset = proto.Field(proto.MESSAGE, number=1, message=duration.Duration,) - + time_offset = proto.Field(proto.MESSAGE, number=1, message=duration_pb2.Duration,) pornography_likelihood = proto.Field(proto.ENUM, number=2, enum="Likelihood",) @@ -556,13 +511,10 @@ class NormalizedBoundingBox(proto.Message): Bottom Y coordinate. """ - left = proto.Field(proto.FLOAT, number=1) - - top = proto.Field(proto.FLOAT, number=2) - - right = proto.Field(proto.FLOAT, number=3) - - bottom = proto.Field(proto.FLOAT, number=4) + left = proto.Field(proto.FLOAT, number=1,) + top = proto.Field(proto.FLOAT, number=2,) + right = proto.Field(proto.FLOAT, number=3,) + bottom = proto.Field(proto.FLOAT, number=4,) class TimestampedObject(proto.Message): @@ -587,13 +539,10 @@ class TimestampedObject(proto.Message): normalized_bounding_box = proto.Field( proto.MESSAGE, number=1, message="NormalizedBoundingBox", ) - - time_offset = proto.Field(proto.MESSAGE, number=2, message=duration.Duration,) - + time_offset = proto.Field(proto.MESSAGE, number=2, message=duration_pb2.Duration,) attributes = proto.RepeatedField( proto.MESSAGE, number=3, message="DetectedAttribute", ) - landmarks = proto.RepeatedField( proto.MESSAGE, number=4, message="DetectedLandmark", ) @@ -601,7 +550,6 @@ class TimestampedObject(proto.Message): class Track(proto.Message): r"""A track of an object instance. - Attributes: segment (google.cloud.videointelligence_v1p3beta1.types.VideoSegment): Video segment of a track. @@ -616,16 +564,13 @@ class Track(proto.Message): """ segment = proto.Field(proto.MESSAGE, number=1, message="VideoSegment",) - timestamped_objects = proto.RepeatedField( proto.MESSAGE, number=2, message="TimestampedObject", ) - attributes = proto.RepeatedField( proto.MESSAGE, number=3, message="DetectedAttribute", ) - - confidence = proto.Field(proto.FLOAT, number=4) + confidence = proto.Field(proto.FLOAT, number=4,) class DetectedAttribute(proto.Message): @@ -645,16 +590,13 @@ class DetectedAttribute(proto.Message): "black", "blonde", etc. """ - name = proto.Field(proto.STRING, number=1) - - confidence = proto.Field(proto.FLOAT, number=2) - - value = proto.Field(proto.STRING, number=3) + name = proto.Field(proto.STRING, number=1,) + confidence = proto.Field(proto.FLOAT, number=2,) + value = proto.Field(proto.STRING, number=3,) class Celebrity(proto.Message): r"""Celebrity definition. - Attributes: name (str): The resource name of the celebrity. Have the format @@ -668,11 +610,9 @@ class Celebrity(proto.Message): about the celebrity, if applicable. """ - name = proto.Field(proto.STRING, number=1) - - display_name = proto.Field(proto.STRING, number=2) - - description = proto.Field(proto.STRING, number=3) + name = proto.Field(proto.STRING, number=1,) + display_name = proto.Field(proto.STRING, number=2,) + description = proto.Field(proto.STRING, number=3,) class CelebrityTrack(proto.Message): @@ -690,7 +630,6 @@ class CelebrityTrack(proto.Message): class RecognizedCelebrity(proto.Message): r"""The recognized celebrity with confidence score. - Attributes: celebrity (google.cloud.videointelligence_v1p3beta1.types.Celebrity): The recognized celebrity. @@ -699,19 +638,16 @@ class RecognizedCelebrity(proto.Message): """ celebrity = proto.Field(proto.MESSAGE, number=1, message="Celebrity",) - - confidence = proto.Field(proto.FLOAT, number=2) + confidence = proto.Field(proto.FLOAT, number=2,) celebrities = proto.RepeatedField( proto.MESSAGE, number=1, message=RecognizedCelebrity, ) - face_track = proto.Field(proto.MESSAGE, number=3, message="Track",) class CelebrityRecognitionAnnotation(proto.Message): r"""Celebrity recognition annotation per video. - Attributes: celebrity_tracks (Sequence[google.cloud.videointelligence_v1p3beta1.types.CelebrityTrack]): The tracks detected from the input video, @@ -741,16 +677,13 @@ class DetectedLandmark(proto.Message): The confidence score of the detected landmark. Range [0, 1]. """ - name = proto.Field(proto.STRING, number=1) - + name = proto.Field(proto.STRING, number=1,) point = proto.Field(proto.MESSAGE, number=2, message="NormalizedVertex",) - - confidence = proto.Field(proto.FLOAT, number=3) + confidence = proto.Field(proto.FLOAT, number=3,) class FaceDetectionAnnotation(proto.Message): r"""Face detection annotation. - Attributes: tracks (Sequence[google.cloud.videointelligence_v1p3beta1.types.Track]): The face tracks with attributes. @@ -759,13 +692,11 @@ class FaceDetectionAnnotation(proto.Message): """ tracks = proto.RepeatedField(proto.MESSAGE, number=3, message="Track",) - - thumbnail = proto.Field(proto.BYTES, number=4) + thumbnail = proto.Field(proto.BYTES, number=4,) class PersonDetectionAnnotation(proto.Message): r"""Person detection annotation per video. - Attributes: tracks (Sequence[google.cloud.videointelligence_v1p3beta1.types.Track]): The detected tracks of a person. @@ -776,7 +707,6 @@ class PersonDetectionAnnotation(proto.Message): class VideoAnnotationResults(proto.Message): r"""Annotation results for a single video. - Attributes: input_uri (str): Video file location in `Cloud @@ -842,67 +772,51 @@ class VideoAnnotationResults(proto.Message): may fail. """ - input_uri = proto.Field(proto.STRING, number=1) - + input_uri = proto.Field(proto.STRING, number=1,) segment = proto.Field(proto.MESSAGE, number=10, message="VideoSegment",) - segment_label_annotations = proto.RepeatedField( proto.MESSAGE, number=2, message="LabelAnnotation", ) - segment_presence_label_annotations = proto.RepeatedField( proto.MESSAGE, number=23, message="LabelAnnotation", ) - shot_label_annotations = proto.RepeatedField( proto.MESSAGE, number=3, message="LabelAnnotation", ) - shot_presence_label_annotations = proto.RepeatedField( proto.MESSAGE, number=24, message="LabelAnnotation", ) - frame_label_annotations = proto.RepeatedField( proto.MESSAGE, number=4, message="LabelAnnotation", ) - face_detection_annotations = proto.RepeatedField( proto.MESSAGE, number=13, message="FaceDetectionAnnotation", ) - shot_annotations = proto.RepeatedField( proto.MESSAGE, number=6, message="VideoSegment", ) - explicit_annotation = proto.Field( proto.MESSAGE, number=7, message="ExplicitContentAnnotation", ) - speech_transcriptions = proto.RepeatedField( proto.MESSAGE, number=11, message="SpeechTranscription", ) - text_annotations = proto.RepeatedField( proto.MESSAGE, number=12, message="TextAnnotation", ) - object_annotations = proto.RepeatedField( proto.MESSAGE, number=14, message="ObjectTrackingAnnotation", ) - logo_recognition_annotations = proto.RepeatedField( proto.MESSAGE, number=19, message="LogoRecognitionAnnotation", ) - person_detection_annotations = proto.RepeatedField( proto.MESSAGE, number=20, message="PersonDetectionAnnotation", ) - celebrity_recognition_annotations = proto.Field( proto.MESSAGE, number=21, message="CelebrityRecognitionAnnotation", ) - - error = proto.Field(proto.MESSAGE, number=9, message=status.Status,) + error = proto.Field(proto.MESSAGE, number=9, message=status_pb2.Status,) class AnnotateVideoResponse(proto.Message): @@ -923,7 +837,6 @@ class AnnotateVideoResponse(proto.Message): class VideoAnnotationProgress(proto.Message): r"""Annotation progress for a single video. - Attributes: input_uri (str): Video file location in `Cloud @@ -943,16 +856,11 @@ class VideoAnnotationProgress(proto.Message): the request contains more than one segment. """ - input_uri = proto.Field(proto.STRING, number=1) - - progress_percent = proto.Field(proto.INT32, number=2) - - start_time = proto.Field(proto.MESSAGE, number=3, message=timestamp.Timestamp,) - - update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp.Timestamp,) - + input_uri = proto.Field(proto.STRING, number=1,) + progress_percent = proto.Field(proto.INT32, number=2,) + start_time = proto.Field(proto.MESSAGE, number=3, message=timestamp_pb2.Timestamp,) + update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp_pb2.Timestamp,) feature = proto.Field(proto.ENUM, number=5, enum="Feature",) - segment = proto.Field(proto.MESSAGE, number=6, message="VideoSegment",) @@ -974,7 +882,6 @@ class AnnotateVideoProgress(proto.Message): class SpeechTranscriptionConfig(proto.Message): r"""Config for SPEECH_TRANSCRIPTION. - Attributes: language_code (str): Required. *Required* The language of the supplied audio as a @@ -1034,25 +941,17 @@ class SpeechTranscriptionConfig(proto.Message): is ``false``. """ - language_code = proto.Field(proto.STRING, number=1) - - max_alternatives = proto.Field(proto.INT32, number=2) - - filter_profanity = proto.Field(proto.BOOL, number=3) - + language_code = proto.Field(proto.STRING, number=1,) + max_alternatives = proto.Field(proto.INT32, number=2,) + filter_profanity = proto.Field(proto.BOOL, number=3,) speech_contexts = proto.RepeatedField( proto.MESSAGE, number=4, message="SpeechContext", ) - - enable_automatic_punctuation = proto.Field(proto.BOOL, number=5) - - audio_tracks = proto.RepeatedField(proto.INT32, number=6) - - enable_speaker_diarization = proto.Field(proto.BOOL, number=7) - - diarization_speaker_count = proto.Field(proto.INT32, number=8) - - enable_word_confidence = proto.Field(proto.BOOL, number=9) + enable_automatic_punctuation = proto.Field(proto.BOOL, number=5,) + audio_tracks = proto.RepeatedField(proto.INT32, number=6,) + enable_speaker_diarization = proto.Field(proto.BOOL, number=7,) + diarization_speaker_count = proto.Field(proto.INT32, number=8,) + enable_word_confidence = proto.Field(proto.BOOL, number=9,) class SpeechContext(proto.Message): @@ -1071,7 +970,7 @@ class SpeechContext(proto.Message): limits `__. """ - phrases = proto.RepeatedField(proto.STRING, number=1) + phrases = proto.RepeatedField(proto.STRING, number=1,) class SpeechTranscription(proto.Message): @@ -1096,13 +995,11 @@ class SpeechTranscription(proto.Message): alternatives = proto.RepeatedField( proto.MESSAGE, number=1, message="SpeechRecognitionAlternative", ) - - language_code = proto.Field(proto.STRING, number=2) + language_code = proto.Field(proto.STRING, number=2,) class SpeechRecognitionAlternative(proto.Message): r"""Alternative hypotheses (a.k.a. n-best list). - Attributes: transcript (str): Transcript text representing the words that @@ -1122,10 +1019,8 @@ class SpeechRecognitionAlternative(proto.Message): beginning of the audio. """ - transcript = proto.Field(proto.STRING, number=1) - - confidence = proto.Field(proto.FLOAT, number=2) - + transcript = proto.Field(proto.STRING, number=1,) + confidence = proto.Field(proto.FLOAT, number=2,) words = proto.RepeatedField(proto.MESSAGE, number=3, message="WordInfo",) @@ -1166,15 +1061,11 @@ class WordInfo(proto.Message): set if speaker diarization is enabled. """ - start_time = proto.Field(proto.MESSAGE, number=1, message=duration.Duration,) - - end_time = proto.Field(proto.MESSAGE, number=2, message=duration.Duration,) - - word = proto.Field(proto.STRING, number=3) - - confidence = proto.Field(proto.FLOAT, number=4) - - speaker_tag = proto.Field(proto.INT32, number=5) + start_time = proto.Field(proto.MESSAGE, number=1, message=duration_pb2.Duration,) + end_time = proto.Field(proto.MESSAGE, number=2, message=duration_pb2.Duration,) + word = proto.Field(proto.STRING, number=3,) + confidence = proto.Field(proto.FLOAT, number=4,) + speaker_tag = proto.Field(proto.INT32, number=5,) class NormalizedVertex(proto.Message): @@ -1189,9 +1080,8 @@ class NormalizedVertex(proto.Message): Y coordinate. """ - x = proto.Field(proto.FLOAT, number=1) - - y = proto.Field(proto.FLOAT, number=2) + x = proto.Field(proto.FLOAT, number=1,) + y = proto.Field(proto.FLOAT, number=2,) class NormalizedBoundingPoly(proto.Message): @@ -1218,7 +1108,6 @@ class NormalizedBoundingPoly(proto.Message): class TextSegment(proto.Message): r"""Video segment level annotation results for text detection. - Attributes: segment (google.cloud.videointelligence_v1p3beta1.types.VideoSegment): Video segment where a text snippet was @@ -1233,9 +1122,7 @@ class TextSegment(proto.Message): """ segment = proto.Field(proto.MESSAGE, number=1, message="VideoSegment",) - - confidence = proto.Field(proto.FLOAT, number=2) - + confidence = proto.Field(proto.FLOAT, number=2,) frames = proto.RepeatedField(proto.MESSAGE, number=3, message="TextFrame",) @@ -1255,8 +1142,7 @@ class TextFrame(proto.Message): rotated_bounding_box = proto.Field( proto.MESSAGE, number=1, message="NormalizedBoundingPoly", ) - - time_offset = proto.Field(proto.MESSAGE, number=2, message=duration.Duration,) + time_offset = proto.Field(proto.MESSAGE, number=2, message=duration_pb2.Duration,) class TextAnnotation(proto.Message): @@ -1272,8 +1158,7 @@ class TextAnnotation(proto.Message): appears. """ - text = proto.Field(proto.STRING, number=1) - + text = proto.Field(proto.STRING, number=1,) segments = proto.RepeatedField(proto.MESSAGE, number=2, message="TextSegment",) @@ -1293,13 +1178,11 @@ class ObjectTrackingFrame(proto.Message): normalized_bounding_box = proto.Field( proto.MESSAGE, number=1, message="NormalizedBoundingBox", ) - - time_offset = proto.Field(proto.MESSAGE, number=2, message=duration.Duration,) + time_offset = proto.Field(proto.MESSAGE, number=2, message=duration_pb2.Duration,) class ObjectTrackingAnnotation(proto.Message): r"""Annotations corresponding to one tracked object. - Attributes: segment (google.cloud.videointelligence_v1p3beta1.types.VideoSegment): Non-streaming batch mode ONLY. @@ -1330,13 +1213,9 @@ class ObjectTrackingAnnotation(proto.Message): segment = proto.Field( proto.MESSAGE, number=3, oneof="track_info", message="VideoSegment", ) - - track_id = proto.Field(proto.INT64, number=5, oneof="track_info") - + track_id = proto.Field(proto.INT64, number=5, oneof="track_info",) entity = proto.Field(proto.MESSAGE, number=1, message="Entity",) - - confidence = proto.Field(proto.FLOAT, number=4) - + confidence = proto.Field(proto.FLOAT, number=4,) frames = proto.RepeatedField( proto.MESSAGE, number=2, message="ObjectTrackingFrame", ) @@ -1363,9 +1242,7 @@ class LogoRecognitionAnnotation(proto.Message): """ entity = proto.Field(proto.MESSAGE, number=1, message="Entity",) - tracks = proto.RepeatedField(proto.MESSAGE, number=2, message="Track",) - segments = proto.RepeatedField(proto.MESSAGE, number=3, message="VideoSegment",) @@ -1399,8 +1276,7 @@ class StreamingAnnotateVideoRequest(proto.Message): oneof="streaming_request", message="StreamingVideoConfig", ) - - input_content = proto.Field(proto.BYTES, number=2, oneof="streaming_request") + input_content = proto.Field(proto.BYTES, number=2, oneof="streaming_request",) class StreamingVideoConfig(proto.Message): @@ -1435,51 +1311,43 @@ class StreamingVideoConfig(proto.Message): oneof="streaming_config", message="StreamingShotChangeDetectionConfig", ) - label_detection_config = proto.Field( proto.MESSAGE, number=3, oneof="streaming_config", message="StreamingLabelDetectionConfig", ) - explicit_content_detection_config = proto.Field( proto.MESSAGE, number=4, oneof="streaming_config", message="StreamingExplicitContentDetectionConfig", ) - object_tracking_config = proto.Field( proto.MESSAGE, number=5, oneof="streaming_config", message="StreamingObjectTrackingConfig", ) - automl_action_recognition_config = proto.Field( proto.MESSAGE, number=23, oneof="streaming_config", message="StreamingAutomlActionRecognitionConfig", ) - automl_classification_config = proto.Field( proto.MESSAGE, number=21, oneof="streaming_config", message="StreamingAutomlClassificationConfig", ) - automl_object_tracking_config = proto.Field( proto.MESSAGE, number=22, oneof="streaming_config", message="StreamingAutomlObjectTrackingConfig", ) - feature = proto.Field(proto.ENUM, number=1, enum="StreamingFeature",) - storage_config = proto.Field( proto.MESSAGE, number=30, message="StreamingStorageConfig", ) @@ -1504,13 +1372,11 @@ class StreamingAnnotateVideoResponse(proto.Message): followed by '/cloud_project_number-session_id'. """ - error = proto.Field(proto.MESSAGE, number=1, message=status.Status,) - + error = proto.Field(proto.MESSAGE, number=1, message=status_pb2.Status,) annotation_results = proto.Field( proto.MESSAGE, number=2, message="StreamingVideoAnnotationResults", ) - - annotation_results_uri = proto.Field(proto.STRING, number=3) + annotation_results_uri = proto.Field(proto.STRING, number=3,) class StreamingVideoAnnotationResults(proto.Message): @@ -1532,27 +1398,23 @@ class StreamingVideoAnnotationResults(proto.Message): shot_annotations = proto.RepeatedField( proto.MESSAGE, number=1, message="VideoSegment", ) - label_annotations = proto.RepeatedField( proto.MESSAGE, number=2, message="LabelAnnotation", ) - explicit_annotation = proto.Field( proto.MESSAGE, number=3, message="ExplicitContentAnnotation", ) - object_annotations = proto.RepeatedField( proto.MESSAGE, number=4, message="ObjectTrackingAnnotation", ) class StreamingShotChangeDetectionConfig(proto.Message): - r"""Config for STREAMING_SHOT_CHANGE_DETECTION.""" + r"""Config for STREAMING_SHOT_CHANGE_DETECTION. """ class StreamingLabelDetectionConfig(proto.Message): r"""Config for STREAMING_LABEL_DETECTION. - Attributes: stationary_camera (bool): Whether the video has been captured from a @@ -1561,56 +1423,52 @@ class StreamingLabelDetectionConfig(proto.Message): moving objects. Default: false. """ - stationary_camera = proto.Field(proto.BOOL, number=1) + stationary_camera = proto.Field(proto.BOOL, number=1,) class StreamingExplicitContentDetectionConfig(proto.Message): - r"""Config for STREAMING_EXPLICIT_CONTENT_DETECTION.""" + r"""Config for STREAMING_EXPLICIT_CONTENT_DETECTION. """ class StreamingObjectTrackingConfig(proto.Message): - r"""Config for STREAMING_OBJECT_TRACKING.""" + r"""Config for STREAMING_OBJECT_TRACKING. """ class StreamingAutomlActionRecognitionConfig(proto.Message): r"""Config for STREAMING_AUTOML_ACTION_RECOGNITION. - Attributes: model_name (str): Resource name of AutoML model. Format: ``projects/{project_id}/locations/{location_id}/models/{model_id}`` """ - model_name = proto.Field(proto.STRING, number=1) + model_name = proto.Field(proto.STRING, number=1,) class StreamingAutomlClassificationConfig(proto.Message): r"""Config for STREAMING_AUTOML_CLASSIFICATION. - Attributes: model_name (str): Resource name of AutoML model. Format: ``projects/{project_number}/locations/{location_id}/models/{model_id}`` """ - model_name = proto.Field(proto.STRING, number=1) + model_name = proto.Field(proto.STRING, number=1,) class StreamingAutomlObjectTrackingConfig(proto.Message): r"""Config for STREAMING_AUTOML_OBJECT_TRACKING. - Attributes: model_name (str): Resource name of AutoML model. Format: ``projects/{project_id}/locations/{location_id}/models/{model_id}`` """ - model_name = proto.Field(proto.STRING, number=1) + model_name = proto.Field(proto.STRING, number=1,) class StreamingStorageConfig(proto.Message): r"""Config for streaming storage option. - Attributes: enable_storage_annotation_result (bool): Enable streaming storage. Default: false. @@ -1630,9 +1488,8 @@ class StreamingStorageConfig(proto.Message): Storage write failure. """ - enable_storage_annotation_result = proto.Field(proto.BOOL, number=1) - - annotation_result_storage_directory = proto.Field(proto.STRING, number=3) + enable_storage_annotation_result = proto.Field(proto.BOOL, number=1,) + annotation_result_storage_directory = proto.Field(proto.STRING, number=3,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/scripts/fixup_videointelligence_v1_keywords.py b/scripts/fixup_videointelligence_v1_keywords.py index cda96fc5..1f1ca2dd 100644 --- a/scripts/fixup_videointelligence_v1_keywords.py +++ b/scripts/fixup_videointelligence_v1_keywords.py @@ -1,6 +1,5 @@ #! /usr/bin/env python3 # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,7 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import argparse import os import libcst as cst @@ -41,8 +39,7 @@ def partition( class videointelligenceCallTransformer(cst.CSTTransformer): CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { - 'annotate_video': ('features', 'input_uri', 'input_content', 'video_context', 'output_uri', 'location_id', ), - + 'annotate_video': ('features', 'input_uri', 'input_content', 'video_context', 'output_uri', 'location_id', ), } def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: @@ -73,7 +70,7 @@ def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: value=cst.Dict([ cst.DictElement( cst.SimpleString("'{}'".format(name)), - cst.Element(value=arg.value) +cst.Element(value=arg.value) ) # Note: the args + kwargs looks silly, but keep in mind that # the control parameters had to be stripped out, and that diff --git a/scripts/fixup_videointelligence_v1beta2_keywords.py b/scripts/fixup_videointelligence_v1beta2_keywords.py index cda96fc5..1f1ca2dd 100644 --- a/scripts/fixup_videointelligence_v1beta2_keywords.py +++ b/scripts/fixup_videointelligence_v1beta2_keywords.py @@ -1,6 +1,5 @@ #! /usr/bin/env python3 # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,7 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import argparse import os import libcst as cst @@ -41,8 +39,7 @@ def partition( class videointelligenceCallTransformer(cst.CSTTransformer): CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { - 'annotate_video': ('features', 'input_uri', 'input_content', 'video_context', 'output_uri', 'location_id', ), - + 'annotate_video': ('features', 'input_uri', 'input_content', 'video_context', 'output_uri', 'location_id', ), } def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: @@ -73,7 +70,7 @@ def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: value=cst.Dict([ cst.DictElement( cst.SimpleString("'{}'".format(name)), - cst.Element(value=arg.value) +cst.Element(value=arg.value) ) # Note: the args + kwargs looks silly, but keep in mind that # the control parameters had to be stripped out, and that diff --git a/scripts/fixup_videointelligence_v1p1beta1_keywords.py b/scripts/fixup_videointelligence_v1p1beta1_keywords.py index cda96fc5..1f1ca2dd 100644 --- a/scripts/fixup_videointelligence_v1p1beta1_keywords.py +++ b/scripts/fixup_videointelligence_v1p1beta1_keywords.py @@ -1,6 +1,5 @@ #! /usr/bin/env python3 # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,7 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import argparse import os import libcst as cst @@ -41,8 +39,7 @@ def partition( class videointelligenceCallTransformer(cst.CSTTransformer): CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { - 'annotate_video': ('features', 'input_uri', 'input_content', 'video_context', 'output_uri', 'location_id', ), - + 'annotate_video': ('features', 'input_uri', 'input_content', 'video_context', 'output_uri', 'location_id', ), } def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: @@ -73,7 +70,7 @@ def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: value=cst.Dict([ cst.DictElement( cst.SimpleString("'{}'".format(name)), - cst.Element(value=arg.value) +cst.Element(value=arg.value) ) # Note: the args + kwargs looks silly, but keep in mind that # the control parameters had to be stripped out, and that diff --git a/scripts/fixup_videointelligence_v1p2beta1_keywords.py b/scripts/fixup_videointelligence_v1p2beta1_keywords.py index cda96fc5..1f1ca2dd 100644 --- a/scripts/fixup_videointelligence_v1p2beta1_keywords.py +++ b/scripts/fixup_videointelligence_v1p2beta1_keywords.py @@ -1,6 +1,5 @@ #! /usr/bin/env python3 # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,7 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import argparse import os import libcst as cst @@ -41,8 +39,7 @@ def partition( class videointelligenceCallTransformer(cst.CSTTransformer): CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { - 'annotate_video': ('features', 'input_uri', 'input_content', 'video_context', 'output_uri', 'location_id', ), - + 'annotate_video': ('features', 'input_uri', 'input_content', 'video_context', 'output_uri', 'location_id', ), } def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: @@ -73,7 +70,7 @@ def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: value=cst.Dict([ cst.DictElement( cst.SimpleString("'{}'".format(name)), - cst.Element(value=arg.value) +cst.Element(value=arg.value) ) # Note: the args + kwargs looks silly, but keep in mind that # the control parameters had to be stripped out, and that diff --git a/scripts/fixup_videointelligence_v1p3beta1_keywords.py b/scripts/fixup_videointelligence_v1p3beta1_keywords.py index 9a1b69ba..b8e257f0 100644 --- a/scripts/fixup_videointelligence_v1p3beta1_keywords.py +++ b/scripts/fixup_videointelligence_v1p3beta1_keywords.py @@ -1,6 +1,5 @@ #! /usr/bin/env python3 # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,7 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import argparse import os import libcst as cst @@ -41,9 +39,8 @@ def partition( class videointelligenceCallTransformer(cst.CSTTransformer): CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { - 'annotate_video': ('features', 'input_uri', 'input_content', 'video_context', 'output_uri', 'location_id', ), - 'streaming_annotate_video': ('video_config', 'input_content', ), - + 'annotate_video': ('features', 'input_uri', 'input_content', 'video_context', 'output_uri', 'location_id', ), + 'streaming_annotate_video': ('video_config', 'input_content', ), } def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: @@ -74,7 +71,7 @@ def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: value=cst.Dict([ cst.DictElement( cst.SimpleString("'{}'".format(name)), - cst.Element(value=arg.value) +cst.Element(value=arg.value) ) # Note: the args + kwargs looks silly, but keep in mind that # the control parameters had to be stripped out, and that diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..4de65971 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,15 @@ +# -*- 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/__init__.py b/tests/unit/__init__.py new file mode 100644 index 00000000..4de65971 --- /dev/null +++ b/tests/unit/__init__.py @@ -0,0 +1,15 @@ +# -*- 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/__init__.py b/tests/unit/gapic/__init__.py new file mode 100644 index 00000000..4de65971 --- /dev/null +++ b/tests/unit/gapic/__init__.py @@ -0,0 +1,15 @@ +# -*- 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/videointelligence_v1/__init__.py b/tests/unit/gapic/videointelligence_v1/__init__.py index 42ffdf2b..4de65971 100644 --- a/tests/unit/gapic/videointelligence_v1/__init__.py +++ b/tests/unit/gapic/videointelligence_v1/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/tests/unit/gapic/videointelligence_v1/test_video_intelligence_service.py b/tests/unit/gapic/videointelligence_v1/test_video_intelligence_service.py index 9e973d58..07b08e1e 100644 --- a/tests/unit/gapic/videointelligence_v1/test_video_intelligence_service.py +++ b/tests/unit/gapic/videointelligence_v1/test_video_intelligence_service.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import os import mock +import packaging.version import grpc from grpc.experimental import aio @@ -24,16 +23,16 @@ 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 exceptions as core_exceptions from google.api_core import future from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async from google.api_core import operation_async # type: ignore from google.api_core import operations_v1 -from google.auth import credentials +from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.cloud.videointelligence_v1.services.video_intelligence_service import ( VideoIntelligenceServiceAsyncClient, @@ -44,10 +43,40 @@ from google.cloud.videointelligence_v1.services.video_intelligence_service import ( transports, ) +from google.cloud.videointelligence_v1.services.video_intelligence_service.transports.base import ( + _API_CORE_VERSION, +) +from google.cloud.videointelligence_v1.services.video_intelligence_service.transports.base import ( + _GOOGLE_AUTH_VERSION, +) from google.cloud.videointelligence_v1.types import video_intelligence from google.longrunning import operations_pb2 from google.oauth2 import service_account -from google.protobuf import duration_pb2 as duration # type: ignore +from google.protobuf import duration_pb2 # type: ignore +import google.auth + + +# TODO(busunkim): Once google-api-core >= 1.26.0 is required: +# - Delete all the api-core and 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", +) + +requires_api_core_lt_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) >= packaging.version.parse("1.26.0"), + reason="This test requires google-api-core < 1.26.0", +) + +requires_api_core_gte_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) < packaging.version.parse("1.26.0"), + reason="This test requires google-api-core >= 1.26.0", +) def client_cert_source_callback(): @@ -100,7 +129,7 @@ def test__get_default_mtls_endpoint(): [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient,], ) def test_video_intelligence_service_client_from_service_account_info(client_class): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_info" ) as factory: @@ -118,7 +147,7 @@ def test_video_intelligence_service_client_from_service_account_info(client_clas [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient,], ) def test_video_intelligence_service_client_from_service_account_file(client_class): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_file" ) as factory: @@ -177,7 +206,7 @@ def test_video_intelligence_service_client_client_options( with mock.patch.object( VideoIntelligenceServiceClient, "get_transport_class" ) as gtc: - transport = transport_class(credentials=credentials.AnonymousCredentials()) + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) client = client_class(transport=transport) gtc.assert_not_called() @@ -485,7 +514,7 @@ def test_annotate_video( transport: str = "grpc", request_type=video_intelligence.AnnotateVideoRequest ): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -496,13 +525,11 @@ def test_annotate_video( with mock.patch.object(type(client.transport.annotate_video), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") - response = client.annotate_video(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0] == video_intelligence.AnnotateVideoRequest() # Establish that the response is the type that we expect. @@ -517,7 +544,7 @@ def test_annotate_video_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 = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -525,7 +552,6 @@ def test_annotate_video_empty_call(): client.annotate_video() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == video_intelligence.AnnotateVideoRequest() @@ -535,7 +561,7 @@ async def test_annotate_video_async( request_type=video_intelligence.AnnotateVideoRequest, ): client = VideoIntelligenceServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -548,13 +574,11 @@ async def test_annotate_video_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") ) - response = await client.annotate_video(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == video_intelligence.AnnotateVideoRequest() # Establish that the response is the type that we expect. @@ -568,14 +592,13 @@ async def test_annotate_video_async_from_dict(): def test_annotate_video_flattened(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.annotate_video), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") - # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. client.annotate_video( @@ -587,15 +610,13 @@ def test_annotate_video_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].input_uri == "input_uri_value" - assert args[0].features == [video_intelligence.Feature.LABEL_DETECTION] def test_annotate_video_flattened_error(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -611,7 +632,7 @@ def test_annotate_video_flattened_error(): @pytest.mark.asyncio async def test_annotate_video_flattened_async(): client = VideoIntelligenceServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -633,16 +654,14 @@ async def test_annotate_video_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].input_uri == "input_uri_value" - assert args[0].features == [video_intelligence.Feature.LABEL_DETECTION] @pytest.mark.asyncio async def test_annotate_video_flattened_error_async(): client = VideoIntelligenceServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -658,16 +677,16 @@ async def test_annotate_video_flattened_error_async(): def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # It is an error to provide a credentials file and a transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = VideoIntelligenceServiceClient( @@ -677,7 +696,7 @@ def test_credentials_transport_error(): # It is an error to provide scopes and a transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = VideoIntelligenceServiceClient( @@ -688,7 +707,7 @@ def test_credentials_transport_error(): def test_transport_instance(): # A client may be instantiated with a custom transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) client = VideoIntelligenceServiceClient(transport=transport) assert client.transport is transport @@ -697,13 +716,13 @@ def test_transport_instance(): def test_transport_get_channel(): # A client may be instantiated with a custom transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel transport = transports.VideoIntelligenceServiceGrpcAsyncIOTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel @@ -718,8 +737,8 @@ def test_transport_get_channel(): ) 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) + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport_class() adc.assert_called_once() @@ -727,7 +746,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) assert isinstance( client.transport, transports.VideoIntelligenceServiceGrpcTransport, @@ -736,9 +755,9 @@ def test_transport_grpc_default(): def test_video_intelligence_service_base_transport_error(): # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(exceptions.DuplicateCredentialArgs): + with pytest.raises(core_exceptions.DuplicateCredentialArgs): transport = transports.VideoIntelligenceServiceTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), credentials_file="credentials.json", ) @@ -750,7 +769,7 @@ def test_video_intelligence_service_base_transport(): ) as Transport: Transport.return_value = None transport = transports.VideoIntelligenceServiceTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Every method on the transport should just blindly @@ -766,15 +785,37 @@ def test_video_intelligence_service_base_transport(): transport.operations_client +@requires_google_auth_gte_1_25_0 def test_video_intelligence_service_base_transport_with_credentials_file(): # Instantiate the base transport with a credentials file with mock.patch.object( - auth, "load_credentials_from_file" + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.cloud.videointelligence_v1.services.video_intelligence_service.transports.VideoIntelligenceServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.VideoIntelligenceServiceTransport( + credentials_file="credentials.json", quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +@requires_google_auth_lt_1_25_0 +def test_video_intelligence_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.videointelligence_v1.services.video_intelligence_service.transports.VideoIntelligenceServiceTransport._prep_wrapped_messages" ) as Transport: Transport.return_value = None - load_creds.return_value = (credentials.AnonymousCredentials(), None) + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.VideoIntelligenceServiceTransport( credentials_file="credentials.json", quota_project_id="octopus", ) @@ -787,19 +828,33 @@ def test_video_intelligence_service_base_transport_with_credentials_file(): def test_video_intelligence_service_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( + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( "google.cloud.videointelligence_v1.services.video_intelligence_service.transports.VideoIntelligenceServiceTransport._prep_wrapped_messages" ) as Transport: Transport.return_value = None - adc.return_value = (credentials.AnonymousCredentials(), None) + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.VideoIntelligenceServiceTransport() adc.assert_called_once() +@requires_google_auth_gte_1_25_0 def test_video_intelligence_service_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) + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + VideoIntelligenceServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id=None, + ) + + +@requires_google_auth_lt_1_25_0 +def test_video_intelligence_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) VideoIntelligenceServiceClient() adc.assert_called_once_with( scopes=("https://www.googleapis.com/auth/cloud-platform",), @@ -807,20 +862,158 @@ def test_video_intelligence_service_auth_adc(): ) -def test_video_intelligence_service_transport_auth_adc(): +@pytest.mark.parametrize( + "transport_class", + [ + transports.VideoIntelligenceServiceGrpcTransport, + transports.VideoIntelligenceServiceGrpcAsyncIOTransport, + ], +) +@requires_google_auth_gte_1_25_0 +def test_video_intelligence_service_transport_auth_adc(transport_class): # 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.VideoIntelligenceServiceGrpcTransport( - host="squid.clam.whelk", quota_project_id="octopus" + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.VideoIntelligenceServiceGrpcTransport, + transports.VideoIntelligenceServiceGrpcAsyncIOTransport, + ], +) +@requires_google_auth_lt_1_25_0 +def test_video_intelligence_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-platform",), quota_project_id="octopus", ) +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.VideoIntelligenceServiceGrpcTransport, grpc_helpers), + (transports.VideoIntelligenceServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_gte_1_26_0 +def test_video_intelligence_service_transport_create_channel( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "videointelligence.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=["1", "2"], + default_host="videointelligence.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.VideoIntelligenceServiceGrpcTransport, grpc_helpers), + (transports.VideoIntelligenceServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_lt_1_26_0 +def test_video_intelligence_service_transport_create_channel_old_api_core( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus") + + create_channel.assert_called_with( + "videointelligence.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.VideoIntelligenceServiceGrpcTransport, grpc_helpers), + (transports.VideoIntelligenceServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_lt_1_26_0 +def test_video_intelligence_service_transport_create_channel_user_scopes( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "videointelligence.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=["1", "2"], + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + @pytest.mark.parametrize( "transport_class", [ @@ -831,7 +1024,7 @@ def test_video_intelligence_service_transport_auth_adc(): def test_video_intelligence_service_grpc_transport_client_cert_source_for_mtls( transport_class, ): - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() # Check ssl_channel_credentials is used if provided. with mock.patch.object(transport_class, "create_channel") as mock_create_channel: @@ -870,7 +1063,7 @@ def test_video_intelligence_service_grpc_transport_client_cert_source_for_mtls( def test_video_intelligence_service_host_no_port(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( api_endpoint="videointelligence.googleapis.com" ), @@ -880,7 +1073,7 @@ def test_video_intelligence_service_host_no_port(): def test_video_intelligence_service_host_with_port(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( api_endpoint="videointelligence.googleapis.com:8000" ), @@ -936,9 +1129,9 @@ def test_video_intelligence_service_transport_channel_mtls_with_client_cert_sour mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() with pytest.warns(DeprecationWarning): - with mock.patch.object(auth, "default") as adc: + with mock.patch.object(google.auth, "default") as adc: adc.return_value = (cred, None) transport = transport_class( host="squid.clam.whelk", @@ -1014,7 +1207,7 @@ def test_video_intelligence_service_transport_channel_mtls_with_adc(transport_cl def test_video_intelligence_service_grpc_lro_client(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) transport = client.transport @@ -1027,7 +1220,7 @@ def test_video_intelligence_service_grpc_lro_client(): def test_video_intelligence_service_grpc_lro_async_client(): client = VideoIntelligenceServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", ) transport = client.transport @@ -1040,7 +1233,6 @@ def test_video_intelligence_service_grpc_lro_async_client(): def test_common_billing_account_path(): billing_account = "squid" - expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -1061,7 +1253,6 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): folder = "whelk" - expected = "folders/{folder}".format(folder=folder,) actual = VideoIntelligenceServiceClient.common_folder_path(folder) assert expected == actual @@ -1080,7 +1271,6 @@ def test_parse_common_folder_path(): def test_common_organization_path(): organization = "oyster" - expected = "organizations/{organization}".format(organization=organization,) actual = VideoIntelligenceServiceClient.common_organization_path(organization) assert expected == actual @@ -1099,7 +1289,6 @@ def test_parse_common_organization_path(): def test_common_project_path(): project = "cuttlefish" - expected = "projects/{project}".format(project=project,) actual = VideoIntelligenceServiceClient.common_project_path(project) assert expected == actual @@ -1119,7 +1308,6 @@ def test_parse_common_project_path(): def test_common_location_path(): project = "winkle" location = "nautilus" - expected = "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -1146,7 +1334,7 @@ def test_client_withDEFAULT_CLIENT_INFO(): transports.VideoIntelligenceServiceTransport, "_prep_wrapped_messages" ) as prep: client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -1155,6 +1343,6 @@ def test_client_withDEFAULT_CLIENT_INFO(): ) as prep: transport_class = VideoIntelligenceServiceClient.get_transport_class() transport = transport_class( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) diff --git a/tests/unit/gapic/videointelligence_v1beta2/__init__.py b/tests/unit/gapic/videointelligence_v1beta2/__init__.py index 42ffdf2b..4de65971 100644 --- a/tests/unit/gapic/videointelligence_v1beta2/__init__.py +++ b/tests/unit/gapic/videointelligence_v1beta2/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/tests/unit/gapic/videointelligence_v1beta2/test_video_intelligence_service.py b/tests/unit/gapic/videointelligence_v1beta2/test_video_intelligence_service.py index 684d8d20..3edfceb3 100644 --- a/tests/unit/gapic/videointelligence_v1beta2/test_video_intelligence_service.py +++ b/tests/unit/gapic/videointelligence_v1beta2/test_video_intelligence_service.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import os import mock +import packaging.version import grpc from grpc.experimental import aio @@ -24,16 +23,16 @@ 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 exceptions as core_exceptions from google.api_core import future from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async from google.api_core import operation_async # type: ignore from google.api_core import operations_v1 -from google.auth import credentials +from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.cloud.videointelligence_v1beta2.services.video_intelligence_service import ( VideoIntelligenceServiceAsyncClient, @@ -44,10 +43,40 @@ from google.cloud.videointelligence_v1beta2.services.video_intelligence_service import ( transports, ) +from google.cloud.videointelligence_v1beta2.services.video_intelligence_service.transports.base import ( + _API_CORE_VERSION, +) +from google.cloud.videointelligence_v1beta2.services.video_intelligence_service.transports.base import ( + _GOOGLE_AUTH_VERSION, +) from google.cloud.videointelligence_v1beta2.types import video_intelligence from google.longrunning import operations_pb2 from google.oauth2 import service_account -from google.protobuf import duration_pb2 as duration # type: ignore +from google.protobuf import duration_pb2 # type: ignore +import google.auth + + +# TODO(busunkim): Once google-api-core >= 1.26.0 is required: +# - Delete all the api-core and 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", +) + +requires_api_core_lt_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) >= packaging.version.parse("1.26.0"), + reason="This test requires google-api-core < 1.26.0", +) + +requires_api_core_gte_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) < packaging.version.parse("1.26.0"), + reason="This test requires google-api-core >= 1.26.0", +) def client_cert_source_callback(): @@ -100,7 +129,7 @@ def test__get_default_mtls_endpoint(): [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient,], ) def test_video_intelligence_service_client_from_service_account_info(client_class): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_info" ) as factory: @@ -118,7 +147,7 @@ def test_video_intelligence_service_client_from_service_account_info(client_clas [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient,], ) def test_video_intelligence_service_client_from_service_account_file(client_class): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_file" ) as factory: @@ -177,7 +206,7 @@ def test_video_intelligence_service_client_client_options( with mock.patch.object( VideoIntelligenceServiceClient, "get_transport_class" ) as gtc: - transport = transport_class(credentials=credentials.AnonymousCredentials()) + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) client = client_class(transport=transport) gtc.assert_not_called() @@ -485,7 +514,7 @@ def test_annotate_video( transport: str = "grpc", request_type=video_intelligence.AnnotateVideoRequest ): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -496,13 +525,11 @@ def test_annotate_video( with mock.patch.object(type(client.transport.annotate_video), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") - response = client.annotate_video(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0] == video_intelligence.AnnotateVideoRequest() # Establish that the response is the type that we expect. @@ -517,7 +544,7 @@ def test_annotate_video_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 = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -525,7 +552,6 @@ def test_annotate_video_empty_call(): client.annotate_video() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == video_intelligence.AnnotateVideoRequest() @@ -535,7 +561,7 @@ async def test_annotate_video_async( request_type=video_intelligence.AnnotateVideoRequest, ): client = VideoIntelligenceServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -548,13 +574,11 @@ async def test_annotate_video_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") ) - response = await client.annotate_video(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == video_intelligence.AnnotateVideoRequest() # Establish that the response is the type that we expect. @@ -568,14 +592,13 @@ async def test_annotate_video_async_from_dict(): def test_annotate_video_flattened(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.annotate_video), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") - # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. client.annotate_video( @@ -587,15 +610,13 @@ def test_annotate_video_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].input_uri == "input_uri_value" - assert args[0].features == [video_intelligence.Feature.LABEL_DETECTION] def test_annotate_video_flattened_error(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -611,7 +632,7 @@ def test_annotate_video_flattened_error(): @pytest.mark.asyncio async def test_annotate_video_flattened_async(): client = VideoIntelligenceServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -633,16 +654,14 @@ async def test_annotate_video_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].input_uri == "input_uri_value" - assert args[0].features == [video_intelligence.Feature.LABEL_DETECTION] @pytest.mark.asyncio async def test_annotate_video_flattened_error_async(): client = VideoIntelligenceServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -658,16 +677,16 @@ async def test_annotate_video_flattened_error_async(): def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # It is an error to provide a credentials file and a transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = VideoIntelligenceServiceClient( @@ -677,7 +696,7 @@ def test_credentials_transport_error(): # It is an error to provide scopes and a transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = VideoIntelligenceServiceClient( @@ -688,7 +707,7 @@ def test_credentials_transport_error(): def test_transport_instance(): # A client may be instantiated with a custom transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) client = VideoIntelligenceServiceClient(transport=transport) assert client.transport is transport @@ -697,13 +716,13 @@ def test_transport_instance(): def test_transport_get_channel(): # A client may be instantiated with a custom transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel transport = transports.VideoIntelligenceServiceGrpcAsyncIOTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel @@ -718,8 +737,8 @@ def test_transport_get_channel(): ) 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) + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport_class() adc.assert_called_once() @@ -727,7 +746,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) assert isinstance( client.transport, transports.VideoIntelligenceServiceGrpcTransport, @@ -736,9 +755,9 @@ def test_transport_grpc_default(): def test_video_intelligence_service_base_transport_error(): # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(exceptions.DuplicateCredentialArgs): + with pytest.raises(core_exceptions.DuplicateCredentialArgs): transport = transports.VideoIntelligenceServiceTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), credentials_file="credentials.json", ) @@ -750,7 +769,7 @@ def test_video_intelligence_service_base_transport(): ) as Transport: Transport.return_value = None transport = transports.VideoIntelligenceServiceTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Every method on the transport should just blindly @@ -766,15 +785,37 @@ def test_video_intelligence_service_base_transport(): transport.operations_client +@requires_google_auth_gte_1_25_0 def test_video_intelligence_service_base_transport_with_credentials_file(): # Instantiate the base transport with a credentials file with mock.patch.object( - auth, "load_credentials_from_file" + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.cloud.videointelligence_v1beta2.services.video_intelligence_service.transports.VideoIntelligenceServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.VideoIntelligenceServiceTransport( + credentials_file="credentials.json", quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +@requires_google_auth_lt_1_25_0 +def test_video_intelligence_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.videointelligence_v1beta2.services.video_intelligence_service.transports.VideoIntelligenceServiceTransport._prep_wrapped_messages" ) as Transport: Transport.return_value = None - load_creds.return_value = (credentials.AnonymousCredentials(), None) + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.VideoIntelligenceServiceTransport( credentials_file="credentials.json", quota_project_id="octopus", ) @@ -787,19 +828,33 @@ def test_video_intelligence_service_base_transport_with_credentials_file(): def test_video_intelligence_service_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( + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( "google.cloud.videointelligence_v1beta2.services.video_intelligence_service.transports.VideoIntelligenceServiceTransport._prep_wrapped_messages" ) as Transport: Transport.return_value = None - adc.return_value = (credentials.AnonymousCredentials(), None) + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.VideoIntelligenceServiceTransport() adc.assert_called_once() +@requires_google_auth_gte_1_25_0 def test_video_intelligence_service_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) + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + VideoIntelligenceServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id=None, + ) + + +@requires_google_auth_lt_1_25_0 +def test_video_intelligence_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) VideoIntelligenceServiceClient() adc.assert_called_once_with( scopes=("https://www.googleapis.com/auth/cloud-platform",), @@ -807,20 +862,158 @@ def test_video_intelligence_service_auth_adc(): ) -def test_video_intelligence_service_transport_auth_adc(): +@pytest.mark.parametrize( + "transport_class", + [ + transports.VideoIntelligenceServiceGrpcTransport, + transports.VideoIntelligenceServiceGrpcAsyncIOTransport, + ], +) +@requires_google_auth_gte_1_25_0 +def test_video_intelligence_service_transport_auth_adc(transport_class): # 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.VideoIntelligenceServiceGrpcTransport( - host="squid.clam.whelk", quota_project_id="octopus" + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.VideoIntelligenceServiceGrpcTransport, + transports.VideoIntelligenceServiceGrpcAsyncIOTransport, + ], +) +@requires_google_auth_lt_1_25_0 +def test_video_intelligence_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-platform",), quota_project_id="octopus", ) +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.VideoIntelligenceServiceGrpcTransport, grpc_helpers), + (transports.VideoIntelligenceServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_gte_1_26_0 +def test_video_intelligence_service_transport_create_channel( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "videointelligence.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=["1", "2"], + default_host="videointelligence.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.VideoIntelligenceServiceGrpcTransport, grpc_helpers), + (transports.VideoIntelligenceServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_lt_1_26_0 +def test_video_intelligence_service_transport_create_channel_old_api_core( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus") + + create_channel.assert_called_with( + "videointelligence.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.VideoIntelligenceServiceGrpcTransport, grpc_helpers), + (transports.VideoIntelligenceServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_lt_1_26_0 +def test_video_intelligence_service_transport_create_channel_user_scopes( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "videointelligence.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=["1", "2"], + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + @pytest.mark.parametrize( "transport_class", [ @@ -831,7 +1024,7 @@ def test_video_intelligence_service_transport_auth_adc(): def test_video_intelligence_service_grpc_transport_client_cert_source_for_mtls( transport_class, ): - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() # Check ssl_channel_credentials is used if provided. with mock.patch.object(transport_class, "create_channel") as mock_create_channel: @@ -870,7 +1063,7 @@ def test_video_intelligence_service_grpc_transport_client_cert_source_for_mtls( def test_video_intelligence_service_host_no_port(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( api_endpoint="videointelligence.googleapis.com" ), @@ -880,7 +1073,7 @@ def test_video_intelligence_service_host_no_port(): def test_video_intelligence_service_host_with_port(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( api_endpoint="videointelligence.googleapis.com:8000" ), @@ -936,9 +1129,9 @@ def test_video_intelligence_service_transport_channel_mtls_with_client_cert_sour mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() with pytest.warns(DeprecationWarning): - with mock.patch.object(auth, "default") as adc: + with mock.patch.object(google.auth, "default") as adc: adc.return_value = (cred, None) transport = transport_class( host="squid.clam.whelk", @@ -1014,7 +1207,7 @@ def test_video_intelligence_service_transport_channel_mtls_with_adc(transport_cl def test_video_intelligence_service_grpc_lro_client(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) transport = client.transport @@ -1027,7 +1220,7 @@ def test_video_intelligence_service_grpc_lro_client(): def test_video_intelligence_service_grpc_lro_async_client(): client = VideoIntelligenceServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", ) transport = client.transport @@ -1040,7 +1233,6 @@ def test_video_intelligence_service_grpc_lro_async_client(): def test_common_billing_account_path(): billing_account = "squid" - expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -1061,7 +1253,6 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): folder = "whelk" - expected = "folders/{folder}".format(folder=folder,) actual = VideoIntelligenceServiceClient.common_folder_path(folder) assert expected == actual @@ -1080,7 +1271,6 @@ def test_parse_common_folder_path(): def test_common_organization_path(): organization = "oyster" - expected = "organizations/{organization}".format(organization=organization,) actual = VideoIntelligenceServiceClient.common_organization_path(organization) assert expected == actual @@ -1099,7 +1289,6 @@ def test_parse_common_organization_path(): def test_common_project_path(): project = "cuttlefish" - expected = "projects/{project}".format(project=project,) actual = VideoIntelligenceServiceClient.common_project_path(project) assert expected == actual @@ -1119,7 +1308,6 @@ def test_parse_common_project_path(): def test_common_location_path(): project = "winkle" location = "nautilus" - expected = "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -1146,7 +1334,7 @@ def test_client_withDEFAULT_CLIENT_INFO(): transports.VideoIntelligenceServiceTransport, "_prep_wrapped_messages" ) as prep: client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -1155,6 +1343,6 @@ def test_client_withDEFAULT_CLIENT_INFO(): ) as prep: transport_class = VideoIntelligenceServiceClient.get_transport_class() transport = transport_class( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) diff --git a/tests/unit/gapic/videointelligence_v1p1beta1/__init__.py b/tests/unit/gapic/videointelligence_v1p1beta1/__init__.py index 42ffdf2b..4de65971 100644 --- a/tests/unit/gapic/videointelligence_v1p1beta1/__init__.py +++ b/tests/unit/gapic/videointelligence_v1p1beta1/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/tests/unit/gapic/videointelligence_v1p1beta1/test_video_intelligence_service.py b/tests/unit/gapic/videointelligence_v1p1beta1/test_video_intelligence_service.py index a631e0e7..1a84afa3 100644 --- a/tests/unit/gapic/videointelligence_v1p1beta1/test_video_intelligence_service.py +++ b/tests/unit/gapic/videointelligence_v1p1beta1/test_video_intelligence_service.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import os import mock +import packaging.version import grpc from grpc.experimental import aio @@ -24,16 +23,16 @@ 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 exceptions as core_exceptions from google.api_core import future from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async from google.api_core import operation_async # type: ignore from google.api_core import operations_v1 -from google.auth import credentials +from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.cloud.videointelligence_v1p1beta1.services.video_intelligence_service import ( VideoIntelligenceServiceAsyncClient, @@ -44,10 +43,40 @@ from google.cloud.videointelligence_v1p1beta1.services.video_intelligence_service import ( transports, ) +from google.cloud.videointelligence_v1p1beta1.services.video_intelligence_service.transports.base import ( + _API_CORE_VERSION, +) +from google.cloud.videointelligence_v1p1beta1.services.video_intelligence_service.transports.base import ( + _GOOGLE_AUTH_VERSION, +) from google.cloud.videointelligence_v1p1beta1.types import video_intelligence from google.longrunning import operations_pb2 from google.oauth2 import service_account -from google.protobuf import duration_pb2 as duration # type: ignore +from google.protobuf import duration_pb2 # type: ignore +import google.auth + + +# TODO(busunkim): Once google-api-core >= 1.26.0 is required: +# - Delete all the api-core and 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", +) + +requires_api_core_lt_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) >= packaging.version.parse("1.26.0"), + reason="This test requires google-api-core < 1.26.0", +) + +requires_api_core_gte_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) < packaging.version.parse("1.26.0"), + reason="This test requires google-api-core >= 1.26.0", +) def client_cert_source_callback(): @@ -100,7 +129,7 @@ def test__get_default_mtls_endpoint(): [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient,], ) def test_video_intelligence_service_client_from_service_account_info(client_class): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_info" ) as factory: @@ -118,7 +147,7 @@ def test_video_intelligence_service_client_from_service_account_info(client_clas [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient,], ) def test_video_intelligence_service_client_from_service_account_file(client_class): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_file" ) as factory: @@ -177,7 +206,7 @@ def test_video_intelligence_service_client_client_options( with mock.patch.object( VideoIntelligenceServiceClient, "get_transport_class" ) as gtc: - transport = transport_class(credentials=credentials.AnonymousCredentials()) + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) client = client_class(transport=transport) gtc.assert_not_called() @@ -485,7 +514,7 @@ def test_annotate_video( transport: str = "grpc", request_type=video_intelligence.AnnotateVideoRequest ): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -496,13 +525,11 @@ def test_annotate_video( with mock.patch.object(type(client.transport.annotate_video), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") - response = client.annotate_video(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0] == video_intelligence.AnnotateVideoRequest() # Establish that the response is the type that we expect. @@ -517,7 +544,7 @@ def test_annotate_video_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 = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -525,7 +552,6 @@ def test_annotate_video_empty_call(): client.annotate_video() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == video_intelligence.AnnotateVideoRequest() @@ -535,7 +561,7 @@ async def test_annotate_video_async( request_type=video_intelligence.AnnotateVideoRequest, ): client = VideoIntelligenceServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -548,13 +574,11 @@ async def test_annotate_video_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") ) - response = await client.annotate_video(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == video_intelligence.AnnotateVideoRequest() # Establish that the response is the type that we expect. @@ -568,14 +592,13 @@ async def test_annotate_video_async_from_dict(): def test_annotate_video_flattened(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.annotate_video), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") - # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. client.annotate_video( @@ -587,15 +610,13 @@ def test_annotate_video_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].input_uri == "input_uri_value" - assert args[0].features == [video_intelligence.Feature.LABEL_DETECTION] def test_annotate_video_flattened_error(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -611,7 +632,7 @@ def test_annotate_video_flattened_error(): @pytest.mark.asyncio async def test_annotate_video_flattened_async(): client = VideoIntelligenceServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -633,16 +654,14 @@ async def test_annotate_video_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].input_uri == "input_uri_value" - assert args[0].features == [video_intelligence.Feature.LABEL_DETECTION] @pytest.mark.asyncio async def test_annotate_video_flattened_error_async(): client = VideoIntelligenceServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -658,16 +677,16 @@ async def test_annotate_video_flattened_error_async(): def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # It is an error to provide a credentials file and a transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = VideoIntelligenceServiceClient( @@ -677,7 +696,7 @@ def test_credentials_transport_error(): # It is an error to provide scopes and a transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = VideoIntelligenceServiceClient( @@ -688,7 +707,7 @@ def test_credentials_transport_error(): def test_transport_instance(): # A client may be instantiated with a custom transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) client = VideoIntelligenceServiceClient(transport=transport) assert client.transport is transport @@ -697,13 +716,13 @@ def test_transport_instance(): def test_transport_get_channel(): # A client may be instantiated with a custom transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel transport = transports.VideoIntelligenceServiceGrpcAsyncIOTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel @@ -718,8 +737,8 @@ def test_transport_get_channel(): ) 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) + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport_class() adc.assert_called_once() @@ -727,7 +746,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) assert isinstance( client.transport, transports.VideoIntelligenceServiceGrpcTransport, @@ -736,9 +755,9 @@ def test_transport_grpc_default(): def test_video_intelligence_service_base_transport_error(): # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(exceptions.DuplicateCredentialArgs): + with pytest.raises(core_exceptions.DuplicateCredentialArgs): transport = transports.VideoIntelligenceServiceTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), credentials_file="credentials.json", ) @@ -750,7 +769,7 @@ def test_video_intelligence_service_base_transport(): ) as Transport: Transport.return_value = None transport = transports.VideoIntelligenceServiceTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Every method on the transport should just blindly @@ -766,15 +785,37 @@ def test_video_intelligence_service_base_transport(): transport.operations_client +@requires_google_auth_gte_1_25_0 def test_video_intelligence_service_base_transport_with_credentials_file(): # Instantiate the base transport with a credentials file with mock.patch.object( - auth, "load_credentials_from_file" + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.cloud.videointelligence_v1p1beta1.services.video_intelligence_service.transports.VideoIntelligenceServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.VideoIntelligenceServiceTransport( + credentials_file="credentials.json", quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +@requires_google_auth_lt_1_25_0 +def test_video_intelligence_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.videointelligence_v1p1beta1.services.video_intelligence_service.transports.VideoIntelligenceServiceTransport._prep_wrapped_messages" ) as Transport: Transport.return_value = None - load_creds.return_value = (credentials.AnonymousCredentials(), None) + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.VideoIntelligenceServiceTransport( credentials_file="credentials.json", quota_project_id="octopus", ) @@ -787,19 +828,33 @@ def test_video_intelligence_service_base_transport_with_credentials_file(): def test_video_intelligence_service_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( + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( "google.cloud.videointelligence_v1p1beta1.services.video_intelligence_service.transports.VideoIntelligenceServiceTransport._prep_wrapped_messages" ) as Transport: Transport.return_value = None - adc.return_value = (credentials.AnonymousCredentials(), None) + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.VideoIntelligenceServiceTransport() adc.assert_called_once() +@requires_google_auth_gte_1_25_0 def test_video_intelligence_service_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) + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + VideoIntelligenceServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id=None, + ) + + +@requires_google_auth_lt_1_25_0 +def test_video_intelligence_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) VideoIntelligenceServiceClient() adc.assert_called_once_with( scopes=("https://www.googleapis.com/auth/cloud-platform",), @@ -807,20 +862,158 @@ def test_video_intelligence_service_auth_adc(): ) -def test_video_intelligence_service_transport_auth_adc(): +@pytest.mark.parametrize( + "transport_class", + [ + transports.VideoIntelligenceServiceGrpcTransport, + transports.VideoIntelligenceServiceGrpcAsyncIOTransport, + ], +) +@requires_google_auth_gte_1_25_0 +def test_video_intelligence_service_transport_auth_adc(transport_class): # 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.VideoIntelligenceServiceGrpcTransport( - host="squid.clam.whelk", quota_project_id="octopus" + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.VideoIntelligenceServiceGrpcTransport, + transports.VideoIntelligenceServiceGrpcAsyncIOTransport, + ], +) +@requires_google_auth_lt_1_25_0 +def test_video_intelligence_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-platform",), quota_project_id="octopus", ) +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.VideoIntelligenceServiceGrpcTransport, grpc_helpers), + (transports.VideoIntelligenceServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_gte_1_26_0 +def test_video_intelligence_service_transport_create_channel( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "videointelligence.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=["1", "2"], + default_host="videointelligence.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.VideoIntelligenceServiceGrpcTransport, grpc_helpers), + (transports.VideoIntelligenceServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_lt_1_26_0 +def test_video_intelligence_service_transport_create_channel_old_api_core( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus") + + create_channel.assert_called_with( + "videointelligence.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.VideoIntelligenceServiceGrpcTransport, grpc_helpers), + (transports.VideoIntelligenceServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_lt_1_26_0 +def test_video_intelligence_service_transport_create_channel_user_scopes( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "videointelligence.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=["1", "2"], + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + @pytest.mark.parametrize( "transport_class", [ @@ -831,7 +1024,7 @@ def test_video_intelligence_service_transport_auth_adc(): def test_video_intelligence_service_grpc_transport_client_cert_source_for_mtls( transport_class, ): - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() # Check ssl_channel_credentials is used if provided. with mock.patch.object(transport_class, "create_channel") as mock_create_channel: @@ -870,7 +1063,7 @@ def test_video_intelligence_service_grpc_transport_client_cert_source_for_mtls( def test_video_intelligence_service_host_no_port(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( api_endpoint="videointelligence.googleapis.com" ), @@ -880,7 +1073,7 @@ def test_video_intelligence_service_host_no_port(): def test_video_intelligence_service_host_with_port(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( api_endpoint="videointelligence.googleapis.com:8000" ), @@ -936,9 +1129,9 @@ def test_video_intelligence_service_transport_channel_mtls_with_client_cert_sour mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() with pytest.warns(DeprecationWarning): - with mock.patch.object(auth, "default") as adc: + with mock.patch.object(google.auth, "default") as adc: adc.return_value = (cred, None) transport = transport_class( host="squid.clam.whelk", @@ -1014,7 +1207,7 @@ def test_video_intelligence_service_transport_channel_mtls_with_adc(transport_cl def test_video_intelligence_service_grpc_lro_client(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) transport = client.transport @@ -1027,7 +1220,7 @@ def test_video_intelligence_service_grpc_lro_client(): def test_video_intelligence_service_grpc_lro_async_client(): client = VideoIntelligenceServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", ) transport = client.transport @@ -1040,7 +1233,6 @@ def test_video_intelligence_service_grpc_lro_async_client(): def test_common_billing_account_path(): billing_account = "squid" - expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -1061,7 +1253,6 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): folder = "whelk" - expected = "folders/{folder}".format(folder=folder,) actual = VideoIntelligenceServiceClient.common_folder_path(folder) assert expected == actual @@ -1080,7 +1271,6 @@ def test_parse_common_folder_path(): def test_common_organization_path(): organization = "oyster" - expected = "organizations/{organization}".format(organization=organization,) actual = VideoIntelligenceServiceClient.common_organization_path(organization) assert expected == actual @@ -1099,7 +1289,6 @@ def test_parse_common_organization_path(): def test_common_project_path(): project = "cuttlefish" - expected = "projects/{project}".format(project=project,) actual = VideoIntelligenceServiceClient.common_project_path(project) assert expected == actual @@ -1119,7 +1308,6 @@ def test_parse_common_project_path(): def test_common_location_path(): project = "winkle" location = "nautilus" - expected = "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -1146,7 +1334,7 @@ def test_client_withDEFAULT_CLIENT_INFO(): transports.VideoIntelligenceServiceTransport, "_prep_wrapped_messages" ) as prep: client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -1155,6 +1343,6 @@ def test_client_withDEFAULT_CLIENT_INFO(): ) as prep: transport_class = VideoIntelligenceServiceClient.get_transport_class() transport = transport_class( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) diff --git a/tests/unit/gapic/videointelligence_v1p2beta1/__init__.py b/tests/unit/gapic/videointelligence_v1p2beta1/__init__.py index 42ffdf2b..4de65971 100644 --- a/tests/unit/gapic/videointelligence_v1p2beta1/__init__.py +++ b/tests/unit/gapic/videointelligence_v1p2beta1/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/tests/unit/gapic/videointelligence_v1p2beta1/test_video_intelligence_service.py b/tests/unit/gapic/videointelligence_v1p2beta1/test_video_intelligence_service.py index 62cccf87..f95f30c3 100644 --- a/tests/unit/gapic/videointelligence_v1p2beta1/test_video_intelligence_service.py +++ b/tests/unit/gapic/videointelligence_v1p2beta1/test_video_intelligence_service.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import os import mock +import packaging.version import grpc from grpc.experimental import aio @@ -24,16 +23,16 @@ 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 exceptions as core_exceptions from google.api_core import future from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async from google.api_core import operation_async # type: ignore from google.api_core import operations_v1 -from google.auth import credentials +from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.cloud.videointelligence_v1p2beta1.services.video_intelligence_service import ( VideoIntelligenceServiceAsyncClient, @@ -44,10 +43,40 @@ from google.cloud.videointelligence_v1p2beta1.services.video_intelligence_service import ( transports, ) +from google.cloud.videointelligence_v1p2beta1.services.video_intelligence_service.transports.base import ( + _API_CORE_VERSION, +) +from google.cloud.videointelligence_v1p2beta1.services.video_intelligence_service.transports.base import ( + _GOOGLE_AUTH_VERSION, +) from google.cloud.videointelligence_v1p2beta1.types import video_intelligence from google.longrunning import operations_pb2 from google.oauth2 import service_account -from google.protobuf import duration_pb2 as duration # type: ignore +from google.protobuf import duration_pb2 # type: ignore +import google.auth + + +# TODO(busunkim): Once google-api-core >= 1.26.0 is required: +# - Delete all the api-core and 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", +) + +requires_api_core_lt_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) >= packaging.version.parse("1.26.0"), + reason="This test requires google-api-core < 1.26.0", +) + +requires_api_core_gte_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) < packaging.version.parse("1.26.0"), + reason="This test requires google-api-core >= 1.26.0", +) def client_cert_source_callback(): @@ -100,7 +129,7 @@ def test__get_default_mtls_endpoint(): [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient,], ) def test_video_intelligence_service_client_from_service_account_info(client_class): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_info" ) as factory: @@ -118,7 +147,7 @@ def test_video_intelligence_service_client_from_service_account_info(client_clas [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient,], ) def test_video_intelligence_service_client_from_service_account_file(client_class): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_file" ) as factory: @@ -177,7 +206,7 @@ def test_video_intelligence_service_client_client_options( with mock.patch.object( VideoIntelligenceServiceClient, "get_transport_class" ) as gtc: - transport = transport_class(credentials=credentials.AnonymousCredentials()) + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) client = client_class(transport=transport) gtc.assert_not_called() @@ -485,7 +514,7 @@ def test_annotate_video( transport: str = "grpc", request_type=video_intelligence.AnnotateVideoRequest ): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -496,13 +525,11 @@ def test_annotate_video( with mock.patch.object(type(client.transport.annotate_video), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") - response = client.annotate_video(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0] == video_intelligence.AnnotateVideoRequest() # Establish that the response is the type that we expect. @@ -517,7 +544,7 @@ def test_annotate_video_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 = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -525,7 +552,6 @@ def test_annotate_video_empty_call(): client.annotate_video() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == video_intelligence.AnnotateVideoRequest() @@ -535,7 +561,7 @@ async def test_annotate_video_async( request_type=video_intelligence.AnnotateVideoRequest, ): client = VideoIntelligenceServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -548,13 +574,11 @@ async def test_annotate_video_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") ) - response = await client.annotate_video(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == video_intelligence.AnnotateVideoRequest() # Establish that the response is the type that we expect. @@ -568,14 +592,13 @@ async def test_annotate_video_async_from_dict(): def test_annotate_video_flattened(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.annotate_video), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") - # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. client.annotate_video( @@ -587,15 +610,13 @@ def test_annotate_video_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].input_uri == "input_uri_value" - assert args[0].features == [video_intelligence.Feature.LABEL_DETECTION] def test_annotate_video_flattened_error(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -611,7 +632,7 @@ def test_annotate_video_flattened_error(): @pytest.mark.asyncio async def test_annotate_video_flattened_async(): client = VideoIntelligenceServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -633,16 +654,14 @@ async def test_annotate_video_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].input_uri == "input_uri_value" - assert args[0].features == [video_intelligence.Feature.LABEL_DETECTION] @pytest.mark.asyncio async def test_annotate_video_flattened_error_async(): client = VideoIntelligenceServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -658,16 +677,16 @@ async def test_annotate_video_flattened_error_async(): def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # It is an error to provide a credentials file and a transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = VideoIntelligenceServiceClient( @@ -677,7 +696,7 @@ def test_credentials_transport_error(): # It is an error to provide scopes and a transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = VideoIntelligenceServiceClient( @@ -688,7 +707,7 @@ def test_credentials_transport_error(): def test_transport_instance(): # A client may be instantiated with a custom transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) client = VideoIntelligenceServiceClient(transport=transport) assert client.transport is transport @@ -697,13 +716,13 @@ def test_transport_instance(): def test_transport_get_channel(): # A client may be instantiated with a custom transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel transport = transports.VideoIntelligenceServiceGrpcAsyncIOTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel @@ -718,8 +737,8 @@ def test_transport_get_channel(): ) 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) + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport_class() adc.assert_called_once() @@ -727,7 +746,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) assert isinstance( client.transport, transports.VideoIntelligenceServiceGrpcTransport, @@ -736,9 +755,9 @@ def test_transport_grpc_default(): def test_video_intelligence_service_base_transport_error(): # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(exceptions.DuplicateCredentialArgs): + with pytest.raises(core_exceptions.DuplicateCredentialArgs): transport = transports.VideoIntelligenceServiceTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), credentials_file="credentials.json", ) @@ -750,7 +769,7 @@ def test_video_intelligence_service_base_transport(): ) as Transport: Transport.return_value = None transport = transports.VideoIntelligenceServiceTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Every method on the transport should just blindly @@ -766,15 +785,37 @@ def test_video_intelligence_service_base_transport(): transport.operations_client +@requires_google_auth_gte_1_25_0 def test_video_intelligence_service_base_transport_with_credentials_file(): # Instantiate the base transport with a credentials file with mock.patch.object( - auth, "load_credentials_from_file" + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.cloud.videointelligence_v1p2beta1.services.video_intelligence_service.transports.VideoIntelligenceServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.VideoIntelligenceServiceTransport( + credentials_file="credentials.json", quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +@requires_google_auth_lt_1_25_0 +def test_video_intelligence_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.videointelligence_v1p2beta1.services.video_intelligence_service.transports.VideoIntelligenceServiceTransport._prep_wrapped_messages" ) as Transport: Transport.return_value = None - load_creds.return_value = (credentials.AnonymousCredentials(), None) + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.VideoIntelligenceServiceTransport( credentials_file="credentials.json", quota_project_id="octopus", ) @@ -787,19 +828,33 @@ def test_video_intelligence_service_base_transport_with_credentials_file(): def test_video_intelligence_service_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( + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( "google.cloud.videointelligence_v1p2beta1.services.video_intelligence_service.transports.VideoIntelligenceServiceTransport._prep_wrapped_messages" ) as Transport: Transport.return_value = None - adc.return_value = (credentials.AnonymousCredentials(), None) + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.VideoIntelligenceServiceTransport() adc.assert_called_once() +@requires_google_auth_gte_1_25_0 def test_video_intelligence_service_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) + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + VideoIntelligenceServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id=None, + ) + + +@requires_google_auth_lt_1_25_0 +def test_video_intelligence_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) VideoIntelligenceServiceClient() adc.assert_called_once_with( scopes=("https://www.googleapis.com/auth/cloud-platform",), @@ -807,20 +862,158 @@ def test_video_intelligence_service_auth_adc(): ) -def test_video_intelligence_service_transport_auth_adc(): +@pytest.mark.parametrize( + "transport_class", + [ + transports.VideoIntelligenceServiceGrpcTransport, + transports.VideoIntelligenceServiceGrpcAsyncIOTransport, + ], +) +@requires_google_auth_gte_1_25_0 +def test_video_intelligence_service_transport_auth_adc(transport_class): # 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.VideoIntelligenceServiceGrpcTransport( - host="squid.clam.whelk", quota_project_id="octopus" + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.VideoIntelligenceServiceGrpcTransport, + transports.VideoIntelligenceServiceGrpcAsyncIOTransport, + ], +) +@requires_google_auth_lt_1_25_0 +def test_video_intelligence_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-platform",), quota_project_id="octopus", ) +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.VideoIntelligenceServiceGrpcTransport, grpc_helpers), + (transports.VideoIntelligenceServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_gte_1_26_0 +def test_video_intelligence_service_transport_create_channel( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "videointelligence.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=["1", "2"], + default_host="videointelligence.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.VideoIntelligenceServiceGrpcTransport, grpc_helpers), + (transports.VideoIntelligenceServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_lt_1_26_0 +def test_video_intelligence_service_transport_create_channel_old_api_core( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus") + + create_channel.assert_called_with( + "videointelligence.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.VideoIntelligenceServiceGrpcTransport, grpc_helpers), + (transports.VideoIntelligenceServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_lt_1_26_0 +def test_video_intelligence_service_transport_create_channel_user_scopes( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "videointelligence.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=["1", "2"], + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + @pytest.mark.parametrize( "transport_class", [ @@ -831,7 +1024,7 @@ def test_video_intelligence_service_transport_auth_adc(): def test_video_intelligence_service_grpc_transport_client_cert_source_for_mtls( transport_class, ): - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() # Check ssl_channel_credentials is used if provided. with mock.patch.object(transport_class, "create_channel") as mock_create_channel: @@ -870,7 +1063,7 @@ def test_video_intelligence_service_grpc_transport_client_cert_source_for_mtls( def test_video_intelligence_service_host_no_port(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( api_endpoint="videointelligence.googleapis.com" ), @@ -880,7 +1073,7 @@ def test_video_intelligence_service_host_no_port(): def test_video_intelligence_service_host_with_port(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( api_endpoint="videointelligence.googleapis.com:8000" ), @@ -936,9 +1129,9 @@ def test_video_intelligence_service_transport_channel_mtls_with_client_cert_sour mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() with pytest.warns(DeprecationWarning): - with mock.patch.object(auth, "default") as adc: + with mock.patch.object(google.auth, "default") as adc: adc.return_value = (cred, None) transport = transport_class( host="squid.clam.whelk", @@ -1014,7 +1207,7 @@ def test_video_intelligence_service_transport_channel_mtls_with_adc(transport_cl def test_video_intelligence_service_grpc_lro_client(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) transport = client.transport @@ -1027,7 +1220,7 @@ def test_video_intelligence_service_grpc_lro_client(): def test_video_intelligence_service_grpc_lro_async_client(): client = VideoIntelligenceServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", ) transport = client.transport @@ -1040,7 +1233,6 @@ def test_video_intelligence_service_grpc_lro_async_client(): def test_common_billing_account_path(): billing_account = "squid" - expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -1061,7 +1253,6 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): folder = "whelk" - expected = "folders/{folder}".format(folder=folder,) actual = VideoIntelligenceServiceClient.common_folder_path(folder) assert expected == actual @@ -1080,7 +1271,6 @@ def test_parse_common_folder_path(): def test_common_organization_path(): organization = "oyster" - expected = "organizations/{organization}".format(organization=organization,) actual = VideoIntelligenceServiceClient.common_organization_path(organization) assert expected == actual @@ -1099,7 +1289,6 @@ def test_parse_common_organization_path(): def test_common_project_path(): project = "cuttlefish" - expected = "projects/{project}".format(project=project,) actual = VideoIntelligenceServiceClient.common_project_path(project) assert expected == actual @@ -1119,7 +1308,6 @@ def test_parse_common_project_path(): def test_common_location_path(): project = "winkle" location = "nautilus" - expected = "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -1146,7 +1334,7 @@ def test_client_withDEFAULT_CLIENT_INFO(): transports.VideoIntelligenceServiceTransport, "_prep_wrapped_messages" ) as prep: client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -1155,6 +1343,6 @@ def test_client_withDEFAULT_CLIENT_INFO(): ) as prep: transport_class = VideoIntelligenceServiceClient.get_transport_class() transport = transport_class( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) diff --git a/tests/unit/gapic/videointelligence_v1p3beta1/__init__.py b/tests/unit/gapic/videointelligence_v1p3beta1/__init__.py index 42ffdf2b..4de65971 100644 --- a/tests/unit/gapic/videointelligence_v1p3beta1/__init__.py +++ b/tests/unit/gapic/videointelligence_v1p3beta1/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/tests/unit/gapic/videointelligence_v1p3beta1/test_streaming_video_intelligence_service.py b/tests/unit/gapic/videointelligence_v1p3beta1/test_streaming_video_intelligence_service.py index 1a3a8551..7d583c7e 100644 --- a/tests/unit/gapic/videointelligence_v1p3beta1/test_streaming_video_intelligence_service.py +++ b/tests/unit/gapic/videointelligence_v1p3beta1/test_streaming_video_intelligence_service.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import os import mock +import packaging.version import grpc from grpc.experimental import aio @@ -24,13 +23,13 @@ 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 exceptions as core_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 import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.cloud.videointelligence_v1p3beta1.services.streaming_video_intelligence_service import ( StreamingVideoIntelligenceServiceAsyncClient, @@ -41,9 +40,39 @@ from google.cloud.videointelligence_v1p3beta1.services.streaming_video_intelligence_service import ( transports, ) +from google.cloud.videointelligence_v1p3beta1.services.streaming_video_intelligence_service.transports.base import ( + _API_CORE_VERSION, +) +from google.cloud.videointelligence_v1p3beta1.services.streaming_video_intelligence_service.transports.base import ( + _GOOGLE_AUTH_VERSION, +) from google.cloud.videointelligence_v1p3beta1.types import video_intelligence from google.oauth2 import service_account -from google.rpc import status_pb2 as status # type: ignore +from google.rpc import status_pb2 # type: ignore +import google.auth + + +# TODO(busunkim): Once google-api-core >= 1.26.0 is required: +# - Delete all the api-core and 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", +) + +requires_api_core_lt_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) >= packaging.version.parse("1.26.0"), + reason="This test requires google-api-core < 1.26.0", +) + +requires_api_core_gte_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) < packaging.version.parse("1.26.0"), + reason="This test requires google-api-core >= 1.26.0", +) def client_cert_source_callback(): @@ -111,7 +140,7 @@ def test__get_default_mtls_endpoint(): def test_streaming_video_intelligence_service_client_from_service_account_info( client_class, ): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_info" ) as factory: @@ -134,7 +163,7 @@ def test_streaming_video_intelligence_service_client_from_service_account_info( def test_streaming_video_intelligence_service_client_from_service_account_file( client_class, ): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_file" ) as factory: @@ -193,7 +222,7 @@ def test_streaming_video_intelligence_service_client_client_options( with mock.patch.object( StreamingVideoIntelligenceServiceClient, "get_transport_class" ) as gtc: - transport = transport_class(credentials=credentials.AnonymousCredentials()) + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) client = client_class(transport=transport) gtc.assert_not_called() @@ -502,13 +531,12 @@ def test_streaming_annotate_video( request_type=video_intelligence.StreamingAnnotateVideoRequest, ): client = StreamingVideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_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() - requests = [request] # Mock the actual call within the gRPC stub, and fake the request. @@ -517,13 +545,11 @@ def test_streaming_annotate_video( ) as call: # Designate an appropriate return value for the call. call.return_value = iter([video_intelligence.StreamingAnnotateVideoResponse()]) - response = client.streaming_annotate_video(iter(requests)) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert next(args[0]) == request # Establish that the response is the type that we expect. @@ -541,13 +567,12 @@ async def test_streaming_annotate_video_async( request_type=video_intelligence.StreamingAnnotateVideoRequest, ): client = StreamingVideoIntelligenceServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_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() - requests = [request] # Mock the actual call within the gRPC stub, and fake the request. @@ -559,13 +584,11 @@ async def test_streaming_annotate_video_async( call.return_value.read = mock.AsyncMock( side_effect=[video_intelligence.StreamingAnnotateVideoResponse()] ) - response = await client.streaming_annotate_video(iter(requests)) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert next(args[0]) == request # Establish that the response is the type that we expect. @@ -581,16 +604,16 @@ async def test_streaming_annotate_video_async_from_dict(): def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.StreamingVideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = StreamingVideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # It is an error to provide a credentials file and a transport instance. transport = transports.StreamingVideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = StreamingVideoIntelligenceServiceClient( @@ -600,7 +623,7 @@ def test_credentials_transport_error(): # It is an error to provide scopes and a transport instance. transport = transports.StreamingVideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = StreamingVideoIntelligenceServiceClient( @@ -611,7 +634,7 @@ def test_credentials_transport_error(): def test_transport_instance(): # A client may be instantiated with a custom transport instance. transport = transports.StreamingVideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) client = StreamingVideoIntelligenceServiceClient(transport=transport) assert client.transport is transport @@ -620,13 +643,13 @@ def test_transport_instance(): def test_transport_get_channel(): # A client may be instantiated with a custom transport instance. transport = transports.StreamingVideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel transport = transports.StreamingVideoIntelligenceServiceGrpcAsyncIOTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel @@ -641,8 +664,8 @@ def test_transport_get_channel(): ) 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) + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport_class() adc.assert_called_once() @@ -650,7 +673,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = StreamingVideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) assert isinstance( client.transport, transports.StreamingVideoIntelligenceServiceGrpcTransport, @@ -659,9 +682,9 @@ def test_transport_grpc_default(): def test_streaming_video_intelligence_service_base_transport_error(): # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(exceptions.DuplicateCredentialArgs): + with pytest.raises(core_exceptions.DuplicateCredentialArgs): transport = transports.StreamingVideoIntelligenceServiceTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), credentials_file="credentials.json", ) @@ -673,7 +696,7 @@ def test_streaming_video_intelligence_service_base_transport(): ) as Transport: Transport.return_value = None transport = transports.StreamingVideoIntelligenceServiceTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Every method on the transport should just blindly @@ -684,15 +707,37 @@ def test_streaming_video_intelligence_service_base_transport(): getattr(transport, method)(request=object()) +@requires_google_auth_gte_1_25_0 def test_streaming_video_intelligence_service_base_transport_with_credentials_file(): # Instantiate the base transport with a credentials file with mock.patch.object( - auth, "load_credentials_from_file" + google.auth, "load_credentials_from_file", autospec=True ) as load_creds, mock.patch( "google.cloud.videointelligence_v1p3beta1.services.streaming_video_intelligence_service.transports.StreamingVideoIntelligenceServiceTransport._prep_wrapped_messages" ) as Transport: Transport.return_value = None - load_creds.return_value = (credentials.AnonymousCredentials(), None) + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.StreamingVideoIntelligenceServiceTransport( + credentials_file="credentials.json", quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +@requires_google_auth_lt_1_25_0 +def test_streaming_video_intelligence_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.videointelligence_v1p3beta1.services.streaming_video_intelligence_service.transports.StreamingVideoIntelligenceServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.StreamingVideoIntelligenceServiceTransport( credentials_file="credentials.json", quota_project_id="octopus", ) @@ -705,19 +750,33 @@ def test_streaming_video_intelligence_service_base_transport_with_credentials_fi def test_streaming_video_intelligence_service_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( + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( "google.cloud.videointelligence_v1p3beta1.services.streaming_video_intelligence_service.transports.StreamingVideoIntelligenceServiceTransport._prep_wrapped_messages" ) as Transport: Transport.return_value = None - adc.return_value = (credentials.AnonymousCredentials(), None) + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.StreamingVideoIntelligenceServiceTransport() adc.assert_called_once() +@requires_google_auth_gte_1_25_0 def test_streaming_video_intelligence_service_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) + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + StreamingVideoIntelligenceServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id=None, + ) + + +@requires_google_auth_lt_1_25_0 +def test_streaming_video_intelligence_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) StreamingVideoIntelligenceServiceClient() adc.assert_called_once_with( scopes=("https://www.googleapis.com/auth/cloud-platform",), @@ -725,20 +784,169 @@ def test_streaming_video_intelligence_service_auth_adc(): ) -def test_streaming_video_intelligence_service_transport_auth_adc(): +@pytest.mark.parametrize( + "transport_class", + [ + transports.StreamingVideoIntelligenceServiceGrpcTransport, + transports.StreamingVideoIntelligenceServiceGrpcAsyncIOTransport, + ], +) +@requires_google_auth_gte_1_25_0 +def test_streaming_video_intelligence_service_transport_auth_adc(transport_class): # 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.StreamingVideoIntelligenceServiceGrpcTransport( - host="squid.clam.whelk", quota_project_id="octopus" + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.StreamingVideoIntelligenceServiceGrpcTransport, + transports.StreamingVideoIntelligenceServiceGrpcAsyncIOTransport, + ], +) +@requires_google_auth_lt_1_25_0 +def test_streaming_video_intelligence_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-platform",), quota_project_id="octopus", ) +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.StreamingVideoIntelligenceServiceGrpcTransport, grpc_helpers), + ( + transports.StreamingVideoIntelligenceServiceGrpcAsyncIOTransport, + grpc_helpers_async, + ), + ], +) +@requires_api_core_gte_1_26_0 +def test_streaming_video_intelligence_service_transport_create_channel( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "videointelligence.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=["1", "2"], + default_host="videointelligence.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.StreamingVideoIntelligenceServiceGrpcTransport, grpc_helpers), + ( + transports.StreamingVideoIntelligenceServiceGrpcAsyncIOTransport, + grpc_helpers_async, + ), + ], +) +@requires_api_core_lt_1_26_0 +def test_streaming_video_intelligence_service_transport_create_channel_old_api_core( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus") + + create_channel.assert_called_with( + "videointelligence.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.StreamingVideoIntelligenceServiceGrpcTransport, grpc_helpers), + ( + transports.StreamingVideoIntelligenceServiceGrpcAsyncIOTransport, + grpc_helpers_async, + ), + ], +) +@requires_api_core_lt_1_26_0 +def test_streaming_video_intelligence_service_transport_create_channel_user_scopes( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "videointelligence.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=["1", "2"], + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + @pytest.mark.parametrize( "transport_class", [ @@ -749,7 +957,7 @@ def test_streaming_video_intelligence_service_transport_auth_adc(): def test_streaming_video_intelligence_service_grpc_transport_client_cert_source_for_mtls( transport_class, ): - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() # Check ssl_channel_credentials is used if provided. with mock.patch.object(transport_class, "create_channel") as mock_create_channel: @@ -788,7 +996,7 @@ def test_streaming_video_intelligence_service_grpc_transport_client_cert_source_ def test_streaming_video_intelligence_service_host_no_port(): client = StreamingVideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( api_endpoint="videointelligence.googleapis.com" ), @@ -798,7 +1006,7 @@ def test_streaming_video_intelligence_service_host_no_port(): def test_streaming_video_intelligence_service_host_with_port(): client = StreamingVideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( api_endpoint="videointelligence.googleapis.com:8000" ), @@ -854,9 +1062,9 @@ def test_streaming_video_intelligence_service_transport_channel_mtls_with_client mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() with pytest.warns(DeprecationWarning): - with mock.patch.object(auth, "default") as adc: + with mock.patch.object(google.auth, "default") as adc: adc.return_value = (cred, None) transport = transport_class( host="squid.clam.whelk", @@ -934,7 +1142,6 @@ def test_streaming_video_intelligence_service_transport_channel_mtls_with_adc( def test_common_billing_account_path(): billing_account = "squid" - expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -961,7 +1168,6 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): folder = "whelk" - expected = "folders/{folder}".format(folder=folder,) actual = StreamingVideoIntelligenceServiceClient.common_folder_path(folder) assert expected == actual @@ -980,7 +1186,6 @@ def test_parse_common_folder_path(): def test_common_organization_path(): organization = "oyster" - expected = "organizations/{organization}".format(organization=organization,) actual = StreamingVideoIntelligenceServiceClient.common_organization_path( organization @@ -1003,7 +1208,6 @@ def test_parse_common_organization_path(): def test_common_project_path(): project = "cuttlefish" - expected = "projects/{project}".format(project=project,) actual = StreamingVideoIntelligenceServiceClient.common_project_path(project) assert expected == actual @@ -1023,7 +1227,6 @@ def test_parse_common_project_path(): def test_common_location_path(): project = "winkle" location = "nautilus" - expected = "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -1052,7 +1255,7 @@ def test_client_withDEFAULT_CLIENT_INFO(): transports.StreamingVideoIntelligenceServiceTransport, "_prep_wrapped_messages" ) as prep: client = StreamingVideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -1061,6 +1264,6 @@ def test_client_withDEFAULT_CLIENT_INFO(): ) as prep: transport_class = StreamingVideoIntelligenceServiceClient.get_transport_class() transport = transport_class( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) diff --git a/tests/unit/gapic/videointelligence_v1p3beta1/test_video_intelligence_service.py b/tests/unit/gapic/videointelligence_v1p3beta1/test_video_intelligence_service.py index 45ccb0ae..e6b798f2 100644 --- a/tests/unit/gapic/videointelligence_v1p3beta1/test_video_intelligence_service.py +++ b/tests/unit/gapic/videointelligence_v1p3beta1/test_video_intelligence_service.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import os import mock +import packaging.version import grpc from grpc.experimental import aio @@ -24,16 +23,16 @@ 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 exceptions as core_exceptions from google.api_core import future from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async from google.api_core import operation_async # type: ignore from google.api_core import operations_v1 -from google.auth import credentials +from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.cloud.videointelligence_v1p3beta1.services.video_intelligence_service import ( VideoIntelligenceServiceAsyncClient, @@ -44,10 +43,40 @@ from google.cloud.videointelligence_v1p3beta1.services.video_intelligence_service import ( transports, ) +from google.cloud.videointelligence_v1p3beta1.services.video_intelligence_service.transports.base import ( + _API_CORE_VERSION, +) +from google.cloud.videointelligence_v1p3beta1.services.video_intelligence_service.transports.base import ( + _GOOGLE_AUTH_VERSION, +) from google.cloud.videointelligence_v1p3beta1.types import video_intelligence from google.longrunning import operations_pb2 from google.oauth2 import service_account -from google.protobuf import duration_pb2 as duration # type: ignore +from google.protobuf import duration_pb2 # type: ignore +import google.auth + + +# TODO(busunkim): Once google-api-core >= 1.26.0 is required: +# - Delete all the api-core and 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", +) + +requires_api_core_lt_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) >= packaging.version.parse("1.26.0"), + reason="This test requires google-api-core < 1.26.0", +) + +requires_api_core_gte_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) < packaging.version.parse("1.26.0"), + reason="This test requires google-api-core >= 1.26.0", +) def client_cert_source_callback(): @@ -100,7 +129,7 @@ def test__get_default_mtls_endpoint(): [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient,], ) def test_video_intelligence_service_client_from_service_account_info(client_class): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_info" ) as factory: @@ -118,7 +147,7 @@ def test_video_intelligence_service_client_from_service_account_info(client_clas [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient,], ) def test_video_intelligence_service_client_from_service_account_file(client_class): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_file" ) as factory: @@ -177,7 +206,7 @@ def test_video_intelligence_service_client_client_options( with mock.patch.object( VideoIntelligenceServiceClient, "get_transport_class" ) as gtc: - transport = transport_class(credentials=credentials.AnonymousCredentials()) + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) client = client_class(transport=transport) gtc.assert_not_called() @@ -485,7 +514,7 @@ def test_annotate_video( transport: str = "grpc", request_type=video_intelligence.AnnotateVideoRequest ): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -496,13 +525,11 @@ def test_annotate_video( with mock.patch.object(type(client.transport.annotate_video), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") - response = client.annotate_video(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0] == video_intelligence.AnnotateVideoRequest() # Establish that the response is the type that we expect. @@ -517,7 +544,7 @@ def test_annotate_video_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 = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -525,7 +552,6 @@ def test_annotate_video_empty_call(): client.annotate_video() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == video_intelligence.AnnotateVideoRequest() @@ -535,7 +561,7 @@ async def test_annotate_video_async( request_type=video_intelligence.AnnotateVideoRequest, ): client = VideoIntelligenceServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -548,13 +574,11 @@ async def test_annotate_video_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") ) - response = await client.annotate_video(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == video_intelligence.AnnotateVideoRequest() # Establish that the response is the type that we expect. @@ -568,14 +592,13 @@ async def test_annotate_video_async_from_dict(): def test_annotate_video_flattened(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.annotate_video), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") - # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. client.annotate_video( @@ -587,15 +610,13 @@ def test_annotate_video_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].input_uri == "input_uri_value" - assert args[0].features == [video_intelligence.Feature.LABEL_DETECTION] def test_annotate_video_flattened_error(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -611,7 +632,7 @@ def test_annotate_video_flattened_error(): @pytest.mark.asyncio async def test_annotate_video_flattened_async(): client = VideoIntelligenceServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -633,16 +654,14 @@ async def test_annotate_video_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].input_uri == "input_uri_value" - assert args[0].features == [video_intelligence.Feature.LABEL_DETECTION] @pytest.mark.asyncio async def test_annotate_video_flattened_error_async(): client = VideoIntelligenceServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -658,16 +677,16 @@ async def test_annotate_video_flattened_error_async(): def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # It is an error to provide a credentials file and a transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = VideoIntelligenceServiceClient( @@ -677,7 +696,7 @@ def test_credentials_transport_error(): # It is an error to provide scopes and a transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = VideoIntelligenceServiceClient( @@ -688,7 +707,7 @@ def test_credentials_transport_error(): def test_transport_instance(): # A client may be instantiated with a custom transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) client = VideoIntelligenceServiceClient(transport=transport) assert client.transport is transport @@ -697,13 +716,13 @@ def test_transport_instance(): def test_transport_get_channel(): # A client may be instantiated with a custom transport instance. transport = transports.VideoIntelligenceServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel transport = transports.VideoIntelligenceServiceGrpcAsyncIOTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel @@ -718,8 +737,8 @@ def test_transport_get_channel(): ) 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) + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport_class() adc.assert_called_once() @@ -727,7 +746,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) assert isinstance( client.transport, transports.VideoIntelligenceServiceGrpcTransport, @@ -736,9 +755,9 @@ def test_transport_grpc_default(): def test_video_intelligence_service_base_transport_error(): # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(exceptions.DuplicateCredentialArgs): + with pytest.raises(core_exceptions.DuplicateCredentialArgs): transport = transports.VideoIntelligenceServiceTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), credentials_file="credentials.json", ) @@ -750,7 +769,7 @@ def test_video_intelligence_service_base_transport(): ) as Transport: Transport.return_value = None transport = transports.VideoIntelligenceServiceTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Every method on the transport should just blindly @@ -766,15 +785,37 @@ def test_video_intelligence_service_base_transport(): transport.operations_client +@requires_google_auth_gte_1_25_0 def test_video_intelligence_service_base_transport_with_credentials_file(): # Instantiate the base transport with a credentials file with mock.patch.object( - auth, "load_credentials_from_file" + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.cloud.videointelligence_v1p3beta1.services.video_intelligence_service.transports.VideoIntelligenceServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.VideoIntelligenceServiceTransport( + credentials_file="credentials.json", quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +@requires_google_auth_lt_1_25_0 +def test_video_intelligence_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.videointelligence_v1p3beta1.services.video_intelligence_service.transports.VideoIntelligenceServiceTransport._prep_wrapped_messages" ) as Transport: Transport.return_value = None - load_creds.return_value = (credentials.AnonymousCredentials(), None) + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.VideoIntelligenceServiceTransport( credentials_file="credentials.json", quota_project_id="octopus", ) @@ -787,19 +828,33 @@ def test_video_intelligence_service_base_transport_with_credentials_file(): def test_video_intelligence_service_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( + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( "google.cloud.videointelligence_v1p3beta1.services.video_intelligence_service.transports.VideoIntelligenceServiceTransport._prep_wrapped_messages" ) as Transport: Transport.return_value = None - adc.return_value = (credentials.AnonymousCredentials(), None) + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.VideoIntelligenceServiceTransport() adc.assert_called_once() +@requires_google_auth_gte_1_25_0 def test_video_intelligence_service_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) + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + VideoIntelligenceServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id=None, + ) + + +@requires_google_auth_lt_1_25_0 +def test_video_intelligence_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) VideoIntelligenceServiceClient() adc.assert_called_once_with( scopes=("https://www.googleapis.com/auth/cloud-platform",), @@ -807,20 +862,158 @@ def test_video_intelligence_service_auth_adc(): ) -def test_video_intelligence_service_transport_auth_adc(): +@pytest.mark.parametrize( + "transport_class", + [ + transports.VideoIntelligenceServiceGrpcTransport, + transports.VideoIntelligenceServiceGrpcAsyncIOTransport, + ], +) +@requires_google_auth_gte_1_25_0 +def test_video_intelligence_service_transport_auth_adc(transport_class): # 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.VideoIntelligenceServiceGrpcTransport( - host="squid.clam.whelk", quota_project_id="octopus" + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.VideoIntelligenceServiceGrpcTransport, + transports.VideoIntelligenceServiceGrpcAsyncIOTransport, + ], +) +@requires_google_auth_lt_1_25_0 +def test_video_intelligence_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-platform",), quota_project_id="octopus", ) +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.VideoIntelligenceServiceGrpcTransport, grpc_helpers), + (transports.VideoIntelligenceServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_gte_1_26_0 +def test_video_intelligence_service_transport_create_channel( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "videointelligence.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=["1", "2"], + default_host="videointelligence.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.VideoIntelligenceServiceGrpcTransport, grpc_helpers), + (transports.VideoIntelligenceServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_lt_1_26_0 +def test_video_intelligence_service_transport_create_channel_old_api_core( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus") + + create_channel.assert_called_with( + "videointelligence.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.VideoIntelligenceServiceGrpcTransport, grpc_helpers), + (transports.VideoIntelligenceServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_lt_1_26_0 +def test_video_intelligence_service_transport_create_channel_user_scopes( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "videointelligence.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=["1", "2"], + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + @pytest.mark.parametrize( "transport_class", [ @@ -831,7 +1024,7 @@ def test_video_intelligence_service_transport_auth_adc(): def test_video_intelligence_service_grpc_transport_client_cert_source_for_mtls( transport_class, ): - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() # Check ssl_channel_credentials is used if provided. with mock.patch.object(transport_class, "create_channel") as mock_create_channel: @@ -870,7 +1063,7 @@ def test_video_intelligence_service_grpc_transport_client_cert_source_for_mtls( def test_video_intelligence_service_host_no_port(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( api_endpoint="videointelligence.googleapis.com" ), @@ -880,7 +1073,7 @@ def test_video_intelligence_service_host_no_port(): def test_video_intelligence_service_host_with_port(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( api_endpoint="videointelligence.googleapis.com:8000" ), @@ -936,9 +1129,9 @@ def test_video_intelligence_service_transport_channel_mtls_with_client_cert_sour mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() with pytest.warns(DeprecationWarning): - with mock.patch.object(auth, "default") as adc: + with mock.patch.object(google.auth, "default") as adc: adc.return_value = (cred, None) transport = transport_class( host="squid.clam.whelk", @@ -1014,7 +1207,7 @@ def test_video_intelligence_service_transport_channel_mtls_with_adc(transport_cl def test_video_intelligence_service_grpc_lro_client(): client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) transport = client.transport @@ -1027,7 +1220,7 @@ def test_video_intelligence_service_grpc_lro_client(): def test_video_intelligence_service_grpc_lro_async_client(): client = VideoIntelligenceServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", ) transport = client.transport @@ -1040,7 +1233,6 @@ def test_video_intelligence_service_grpc_lro_async_client(): def test_common_billing_account_path(): billing_account = "squid" - expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -1061,7 +1253,6 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): folder = "whelk" - expected = "folders/{folder}".format(folder=folder,) actual = VideoIntelligenceServiceClient.common_folder_path(folder) assert expected == actual @@ -1080,7 +1271,6 @@ def test_parse_common_folder_path(): def test_common_organization_path(): organization = "oyster" - expected = "organizations/{organization}".format(organization=organization,) actual = VideoIntelligenceServiceClient.common_organization_path(organization) assert expected == actual @@ -1099,7 +1289,6 @@ def test_parse_common_organization_path(): def test_common_project_path(): project = "cuttlefish" - expected = "projects/{project}".format(project=project,) actual = VideoIntelligenceServiceClient.common_project_path(project) assert expected == actual @@ -1119,7 +1308,6 @@ def test_parse_common_project_path(): def test_common_location_path(): project = "winkle" location = "nautilus" - expected = "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -1146,7 +1334,7 @@ def test_client_withDEFAULT_CLIENT_INFO(): transports.VideoIntelligenceServiceTransport, "_prep_wrapped_messages" ) as prep: client = VideoIntelligenceServiceClient( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -1155,6 +1343,6 @@ def test_client_withDEFAULT_CLIENT_INFO(): ) as prep: transport_class = VideoIntelligenceServiceClient.get_transport_class() transport = transport_class( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info)