diff --git a/docs/speech_v1/types.rst b/docs/speech_v1/types.rst index 77537068..1f28fdd0 100644 --- a/docs/speech_v1/types.rst +++ b/docs/speech_v1/types.rst @@ -3,3 +3,4 @@ Types for Google Cloud Speech v1 API .. automodule:: google.cloud.speech_v1.types :members: + :show-inheritance: diff --git a/docs/speech_v1p1beta1/types.rst b/docs/speech_v1p1beta1/types.rst index 4c6b8421..96ebe607 100644 --- a/docs/speech_v1p1beta1/types.rst +++ b/docs/speech_v1p1beta1/types.rst @@ -3,3 +3,4 @@ Types for Google Cloud Speech v1p1beta1 API .. automodule:: google.cloud.speech_v1p1beta1.types :members: + :show-inheritance: diff --git a/google/cloud/speech_v1/services/speech/async_client.py b/google/cloud/speech_v1/services/speech/async_client.py index debb4a40..5fea5c72 100644 --- a/google/cloud/speech_v1/services/speech/async_client.py +++ b/google/cloud/speech_v1/services/speech/async_client.py @@ -18,7 +18,16 @@ from collections import OrderedDict import functools import re -from typing import Dict, AsyncIterable, AsyncIterator, Sequence, Tuple, Type, Union +from typing import ( + Dict, + AsyncIterable, + Awaitable, + AsyncIterator, + Sequence, + Tuple, + Type, + Union, +) import pkg_resources import google.api_core.client_options as ClientOptions # type: ignore @@ -46,9 +55,37 @@ class SpeechAsyncClient: DEFAULT_ENDPOINT = SpeechClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = SpeechClient.DEFAULT_MTLS_ENDPOINT + common_billing_account_path = staticmethod(SpeechClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod( + SpeechClient.parse_common_billing_account_path + ) + + common_folder_path = staticmethod(SpeechClient.common_folder_path) + parse_common_folder_path = staticmethod(SpeechClient.parse_common_folder_path) + + common_organization_path = staticmethod(SpeechClient.common_organization_path) + parse_common_organization_path = staticmethod( + SpeechClient.parse_common_organization_path + ) + + common_project_path = staticmethod(SpeechClient.common_project_path) + parse_common_project_path = staticmethod(SpeechClient.parse_common_project_path) + + common_location_path = staticmethod(SpeechClient.common_location_path) + parse_common_location_path = staticmethod(SpeechClient.parse_common_location_path) + from_service_account_file = SpeechClient.from_service_account_file from_service_account_json = from_service_account_file + @property + def transport(self) -> SpeechTransport: + """Return the transport used by the client instance. + + Returns: + SpeechTransport: The transport used by the client instance. + """ + return self._client.transport + get_transport_class = functools.partial( type(SpeechClient).get_transport_class, type(SpeechClient) ) @@ -148,7 +185,8 @@ async def recognize( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([config, audio]): + has_flattened_params = any([config, audio]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -245,7 +283,8 @@ async def long_running_recognize( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([config, audio]): + has_flattened_params = any([config, audio]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -290,7 +329,7 @@ def streaming_recognize( retry: retries.Retry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), - ) -> AsyncIterable[cloud_speech.StreamingRecognizeResponse]: + ) -> Awaitable[AsyncIterable[cloud_speech.StreamingRecognizeResponse]]: r"""Performs bidirectional streaming speech recognition: receive results while sending audio. This method is only available via the gRPC API (not REST). diff --git a/google/cloud/speech_v1/services/speech/client.py b/google/cloud/speech_v1/services/speech/client.py index 43bc479a..27b20723 100644 --- a/google/cloud/speech_v1/services/speech/client.py +++ b/google/cloud/speech_v1/services/speech/client.py @@ -140,6 +140,74 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file + @property + def transport(self) -> SpeechTransport: + """Return the transport used by the client instance. + + Returns: + SpeechTransport: 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.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Return a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Return a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Return a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Return a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + def __init__( self, *, @@ -175,10 +243,10 @@ def __init__( not provided, the default SSL client certificate will be used if present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not set, no client certificate will be used. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: diff --git a/google/cloud/speech_v1/services/speech/transports/__init__.py b/google/cloud/speech_v1/services/speech/transports/__init__.py index 3ec5f07e..d7ef55b1 100644 --- a/google/cloud/speech_v1/services/speech/transports/__init__.py +++ b/google/cloud/speech_v1/services/speech/transports/__init__.py @@ -28,7 +28,6 @@ _transport_registry["grpc"] = SpeechGrpcTransport _transport_registry["grpc_asyncio"] = SpeechGrpcAsyncIOTransport - __all__ = ( "SpeechTransport", "SpeechGrpcTransport", diff --git a/google/cloud/speech_v1/services/speech/transports/grpc.py b/google/cloud/speech_v1/services/speech/transports/grpc.py index 90ba7ead..5bb7ebdc 100644 --- a/google/cloud/speech_v1/services/speech/transports/grpc.py +++ b/google/cloud/speech_v1/services/speech/transports/grpc.py @@ -91,10 +91,10 @@ def __init__( for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -103,6 +103,8 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._ssl_channel_credentials = ssl_channel_credentials + if channel: # Sanity check: Ensure that channel and credentials are not both # provided. @@ -110,6 +112,7 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel + self._ssl_channel_credentials = None elif api_mtls_endpoint: warnings.warn( "api_mtls_endpoint and client_cert_source are deprecated", @@ -145,7 +148,12 @@ def __init__( ssl_credentials=ssl_credentials, scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], ) + self._ssl_channel_credentials = ssl_credentials else: host = host if ":" in host else host + ":443" @@ -162,9 +170,14 @@ def __init__( ssl_credentials=ssl_channel_credentials, scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], ) self._stubs = {} # type: Dict[str, Callable] + self._operations_client = None # Run the base constructor. super().__init__( @@ -188,7 +201,7 @@ def create_channel( ) -> grpc.Channel: """Create and return a gRPC channel object. Args: - address (Optionsl[str]): The host for the channel to use. + address (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If @@ -223,12 +236,8 @@ def create_channel( @property def grpc_channel(self) -> grpc.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. + """Return the channel designed to connect to this service. """ - # Return the channel from cache. return self._grpc_channel @property @@ -239,13 +248,11 @@ def operations_client(self) -> operations_v1.OperationsClient: client. """ # Sanity check: Only create a new client if we do not already have one. - if "operations_client" not in self.__dict__: - self.__dict__["operations_client"] = operations_v1.OperationsClient( - self.grpc_channel - ) + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient(self.grpc_channel) # Return the client from cache. - return self.__dict__["operations_client"] + return self._operations_client @property def recognize( diff --git a/google/cloud/speech_v1/services/speech/transports/grpc_asyncio.py b/google/cloud/speech_v1/services/speech/transports/grpc_asyncio.py index 4ec87eb7..8f6987dc 100644 --- a/google/cloud/speech_v1/services/speech/transports/grpc_asyncio.py +++ b/google/cloud/speech_v1/services/speech/transports/grpc_asyncio.py @@ -148,6 +148,8 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._ssl_channel_credentials = ssl_channel_credentials + if channel: # Sanity check: Ensure that channel and credentials are not both # provided. @@ -155,6 +157,7 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel + self._ssl_channel_credentials = None elif api_mtls_endpoint: warnings.warn( "api_mtls_endpoint and client_cert_source are deprecated", @@ -190,7 +193,12 @@ def __init__( ssl_credentials=ssl_credentials, scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], ) + self._ssl_channel_credentials = ssl_credentials else: host = host if ":" in host else host + ":443" @@ -207,6 +215,10 @@ def __init__( ssl_credentials=ssl_channel_credentials, scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], ) # Run the base constructor. @@ -220,6 +232,7 @@ def __init__( ) self._stubs = {} + self._operations_client = None @property def grpc_channel(self) -> aio.Channel: @@ -239,13 +252,13 @@ def operations_client(self) -> operations_v1.OperationsAsyncClient: client. """ # Sanity check: Only create a new client if we do not already have one. - if "operations_client" not in self.__dict__: - self.__dict__["operations_client"] = operations_v1.OperationsAsyncClient( + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( self.grpc_channel ) # Return the client from cache. - return self.__dict__["operations_client"] + return self._operations_client @property def recognize( diff --git a/google/cloud/speech_v1/types/__init__.py b/google/cloud/speech_v1/types/__init__.py index 19eeeafd..44034960 100644 --- a/google/cloud/speech_v1/types/__init__.py +++ b/google/cloud/speech_v1/types/__init__.py @@ -35,7 +35,6 @@ WordInfo, ) - __all__ = ( "RecognizeRequest", "LongRunningRecognizeRequest", diff --git a/google/cloud/speech_v1p1beta1/services/speech/async_client.py b/google/cloud/speech_v1p1beta1/services/speech/async_client.py index c2b596e6..71dc4ec7 100644 --- a/google/cloud/speech_v1p1beta1/services/speech/async_client.py +++ b/google/cloud/speech_v1p1beta1/services/speech/async_client.py @@ -18,7 +18,16 @@ from collections import OrderedDict import functools import re -from typing import Dict, AsyncIterable, AsyncIterator, Sequence, Tuple, Type, Union +from typing import ( + Dict, + AsyncIterable, + Awaitable, + AsyncIterator, + Sequence, + Tuple, + Type, + Union, +) import pkg_resources import google.api_core.client_options as ClientOptions # type: ignore @@ -51,9 +60,37 @@ class SpeechAsyncClient: phrase_set_path = staticmethod(SpeechClient.phrase_set_path) parse_phrase_set_path = staticmethod(SpeechClient.parse_phrase_set_path) + common_billing_account_path = staticmethod(SpeechClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod( + SpeechClient.parse_common_billing_account_path + ) + + common_folder_path = staticmethod(SpeechClient.common_folder_path) + parse_common_folder_path = staticmethod(SpeechClient.parse_common_folder_path) + + common_organization_path = staticmethod(SpeechClient.common_organization_path) + parse_common_organization_path = staticmethod( + SpeechClient.parse_common_organization_path + ) + + common_project_path = staticmethod(SpeechClient.common_project_path) + parse_common_project_path = staticmethod(SpeechClient.parse_common_project_path) + + common_location_path = staticmethod(SpeechClient.common_location_path) + parse_common_location_path = staticmethod(SpeechClient.parse_common_location_path) + from_service_account_file = SpeechClient.from_service_account_file from_service_account_json = from_service_account_file + @property + def transport(self) -> SpeechTransport: + """Return the transport used by the client instance. + + Returns: + SpeechTransport: The transport used by the client instance. + """ + return self._client.transport + get_transport_class = functools.partial( type(SpeechClient).get_transport_class, type(SpeechClient) ) @@ -153,7 +190,8 @@ async def recognize( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([config, audio]): + has_flattened_params = any([config, audio]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -178,7 +216,7 @@ async def recognize( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5000.0, @@ -250,7 +288,8 @@ async def long_running_recognize( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([config, audio]): + has_flattened_params = any([config, audio]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -295,7 +334,7 @@ def streaming_recognize( retry: retries.Retry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), - ) -> AsyncIterable[cloud_speech.StreamingRecognizeResponse]: + ) -> Awaitable[AsyncIterable[cloud_speech.StreamingRecognizeResponse]]: r"""Performs bidirectional streaming speech recognition: receive results while sending audio. This method is only available via the gRPC API (not REST). @@ -388,7 +427,7 @@ def streaming_recognize( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5000.0, diff --git a/google/cloud/speech_v1p1beta1/services/speech/client.py b/google/cloud/speech_v1p1beta1/services/speech/client.py index 2d7eaae4..14ea0e8e 100644 --- a/google/cloud/speech_v1p1beta1/services/speech/client.py +++ b/google/cloud/speech_v1p1beta1/services/speech/client.py @@ -140,6 +140,15 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file + @property + def transport(self) -> SpeechTransport: + """Return the transport used by the client instance. + + Returns: + SpeechTransport: The transport used by the client instance. + """ + return self._transport + @staticmethod def custom_class_path(project: str, location: str, custom_class: str,) -> str: """Return a fully-qualified custom_class string.""" @@ -172,6 +181,65 @@ def parse_phrase_set_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Return a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Return a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Return a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Return a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Return a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + def __init__( self, *, @@ -207,10 +275,10 @@ def __init__( not provided, the default SSL client certificate will be used if present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not set, no client certificate will be used. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: diff --git a/google/cloud/speech_v1p1beta1/services/speech/transports/__init__.py b/google/cloud/speech_v1p1beta1/services/speech/transports/__init__.py index 3ec5f07e..d7ef55b1 100644 --- a/google/cloud/speech_v1p1beta1/services/speech/transports/__init__.py +++ b/google/cloud/speech_v1p1beta1/services/speech/transports/__init__.py @@ -28,7 +28,6 @@ _transport_registry["grpc"] = SpeechGrpcTransport _transport_registry["grpc_asyncio"] = SpeechGrpcAsyncIOTransport - __all__ = ( "SpeechTransport", "SpeechGrpcTransport", diff --git a/google/cloud/speech_v1p1beta1/services/speech/transports/base.py b/google/cloud/speech_v1p1beta1/services/speech/transports/base.py index cb636182..7ede26a5 100644 --- a/google/cloud/speech_v1p1beta1/services/speech/transports/base.py +++ b/google/cloud/speech_v1p1beta1/services/speech/transports/base.py @@ -113,7 +113,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5000.0, @@ -131,7 +131,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5000.0, diff --git a/google/cloud/speech_v1p1beta1/services/speech/transports/grpc.py b/google/cloud/speech_v1p1beta1/services/speech/transports/grpc.py index 35de4eaa..2b86c6c7 100644 --- a/google/cloud/speech_v1p1beta1/services/speech/transports/grpc.py +++ b/google/cloud/speech_v1p1beta1/services/speech/transports/grpc.py @@ -91,10 +91,10 @@ def __init__( for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -103,6 +103,8 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._ssl_channel_credentials = ssl_channel_credentials + if channel: # Sanity check: Ensure that channel and credentials are not both # provided. @@ -110,6 +112,7 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel + self._ssl_channel_credentials = None elif api_mtls_endpoint: warnings.warn( "api_mtls_endpoint and client_cert_source are deprecated", @@ -145,7 +148,12 @@ def __init__( ssl_credentials=ssl_credentials, scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], ) + self._ssl_channel_credentials = ssl_credentials else: host = host if ":" in host else host + ":443" @@ -162,9 +170,14 @@ def __init__( ssl_credentials=ssl_channel_credentials, scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], ) self._stubs = {} # type: Dict[str, Callable] + self._operations_client = None # Run the base constructor. super().__init__( @@ -188,7 +201,7 @@ def create_channel( ) -> grpc.Channel: """Create and return a gRPC channel object. Args: - address (Optionsl[str]): The host for the channel to use. + address (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If @@ -223,12 +236,8 @@ def create_channel( @property def grpc_channel(self) -> grpc.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. + """Return the channel designed to connect to this service. """ - # Return the channel from cache. return self._grpc_channel @property @@ -239,13 +248,11 @@ def operations_client(self) -> operations_v1.OperationsClient: client. """ # Sanity check: Only create a new client if we do not already have one. - if "operations_client" not in self.__dict__: - self.__dict__["operations_client"] = operations_v1.OperationsClient( - self.grpc_channel - ) + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient(self.grpc_channel) # Return the client from cache. - return self.__dict__["operations_client"] + return self._operations_client @property def recognize( diff --git a/google/cloud/speech_v1p1beta1/services/speech/transports/grpc_asyncio.py b/google/cloud/speech_v1p1beta1/services/speech/transports/grpc_asyncio.py index 439d1b00..1efae229 100644 --- a/google/cloud/speech_v1p1beta1/services/speech/transports/grpc_asyncio.py +++ b/google/cloud/speech_v1p1beta1/services/speech/transports/grpc_asyncio.py @@ -148,6 +148,8 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._ssl_channel_credentials = ssl_channel_credentials + if channel: # Sanity check: Ensure that channel and credentials are not both # provided. @@ -155,6 +157,7 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel + self._ssl_channel_credentials = None elif api_mtls_endpoint: warnings.warn( "api_mtls_endpoint and client_cert_source are deprecated", @@ -190,7 +193,12 @@ def __init__( ssl_credentials=ssl_credentials, scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], ) + self._ssl_channel_credentials = ssl_credentials else: host = host if ":" in host else host + ":443" @@ -207,6 +215,10 @@ def __init__( ssl_credentials=ssl_channel_credentials, scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], ) # Run the base constructor. @@ -220,6 +232,7 @@ def __init__( ) self._stubs = {} + self._operations_client = None @property def grpc_channel(self) -> aio.Channel: @@ -239,13 +252,13 @@ def operations_client(self) -> operations_v1.OperationsAsyncClient: client. """ # Sanity check: Only create a new client if we do not already have one. - if "operations_client" not in self.__dict__: - self.__dict__["operations_client"] = operations_v1.OperationsAsyncClient( + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( self.grpc_channel ) # Return the client from cache. - return self.__dict__["operations_client"] + return self._operations_client @property def recognize( diff --git a/google/cloud/speech_v1p1beta1/types/__init__.py b/google/cloud/speech_v1p1beta1/types/__init__.py index f935f502..9713892d 100644 --- a/google/cloud/speech_v1p1beta1/types/__init__.py +++ b/google/cloud/speech_v1p1beta1/types/__init__.py @@ -40,7 +40,6 @@ WordInfo, ) - __all__ = ( "CustomClass", "PhraseSet", diff --git a/google/cloud/speech_v1p1beta1/types/resource.py b/google/cloud/speech_v1p1beta1/types/resource.py index 3eeba931..eb04c8ea 100644 --- a/google/cloud/speech_v1p1beta1/types/resource.py +++ b/google/cloud/speech_v1p1beta1/types/resource.py @@ -149,9 +149,11 @@ class SpeechAdaptation(proto.Message): ``custom_class_id``. """ - phrase_sets = proto.RepeatedField(proto.MESSAGE, number=1, message=PhraseSet,) + phrase_sets = proto.RepeatedField(proto.MESSAGE, number=1, message="PhraseSet",) - custom_classes = proto.RepeatedField(proto.MESSAGE, number=2, message=CustomClass,) + custom_classes = proto.RepeatedField( + proto.MESSAGE, number=2, message="CustomClass", + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/noxfile.py b/noxfile.py index c9434be4..c449062e 100644 --- a/noxfile.py +++ b/noxfile.py @@ -28,7 +28,7 @@ DEFAULT_PYTHON_VERSION = "3.8" SYSTEM_TEST_PYTHON_VERSIONS = ["3.8"] -UNIT_TEST_PYTHON_VERSIONS = ["3.6", "3.7", "3.8"] +UNIT_TEST_PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9"] @nox.session(python=DEFAULT_PYTHON_VERSION) diff --git a/scripts/fixup_speech_v1_keywords.py b/scripts/fixup_speech_v1_keywords.py index 9d4c6169..bcc5ab74 100644 --- a/scripts/fixup_speech_v1_keywords.py +++ b/scripts/fixup_speech_v1_keywords.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright 2020 Google LLC diff --git a/scripts/fixup_speech_v1p1beta1_keywords.py b/scripts/fixup_speech_v1p1beta1_keywords.py index 9d4c6169..bcc5ab74 100644 --- a/scripts/fixup_speech_v1p1beta1_keywords.py +++ b/scripts/fixup_speech_v1p1beta1_keywords.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright 2020 Google LLC diff --git a/synth.metadata b/synth.metadata index c8576a2a..6a591ba3 100644 --- a/synth.metadata +++ b/synth.metadata @@ -3,16 +3,16 @@ { "git": { "name": ".", - "remote": "git@github.com:googleapis/python-speech", - "sha": "64076bb484d3cf716f0a663f50956f147190e7c8" + "remote": "https://github.com/googleapis/python-speech.git", + "sha": "2cdb974d102ecea7fb57b1916a8c26f000c1fa17" } }, { "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "3dbeac0d54125b123c8dfd39c774b37473c36944", - "internalRef": "333159182" + "sha": "dd372aa22ded7a8ba6f0e03a80e06358a3fa0907", + "internalRef": "347055288" } }, { @@ -49,5 +49,115 @@ "generator": "bazel" } } + ], + "generatedFiles": [ + ".flake8", + ".github/CONTRIBUTING.md", + ".github/ISSUE_TEMPLATE/bug_report.md", + ".github/ISSUE_TEMPLATE/feature_request.md", + ".github/ISSUE_TEMPLATE/support_request.md", + ".github/PULL_REQUEST_TEMPLATE.md", + ".github/release-please.yml", + ".github/snippet-bot.yml", + ".gitignore", + ".kokoro/build.sh", + ".kokoro/continuous/common.cfg", + ".kokoro/continuous/continuous.cfg", + ".kokoro/docker/docs/Dockerfile", + ".kokoro/docker/docs/fetch_gpg_keys.sh", + ".kokoro/docs/common.cfg", + ".kokoro/docs/docs-presubmit.cfg", + ".kokoro/docs/docs.cfg", + ".kokoro/populate-secrets.sh", + ".kokoro/presubmit/common.cfg", + ".kokoro/presubmit/presubmit.cfg", + ".kokoro/publish-docs.sh", + ".kokoro/release.sh", + ".kokoro/release/common.cfg", + ".kokoro/release/release.cfg", + ".kokoro/samples/lint/common.cfg", + ".kokoro/samples/lint/continuous.cfg", + ".kokoro/samples/lint/periodic.cfg", + ".kokoro/samples/lint/presubmit.cfg", + ".kokoro/samples/python3.6/common.cfg", + ".kokoro/samples/python3.6/continuous.cfg", + ".kokoro/samples/python3.6/periodic.cfg", + ".kokoro/samples/python3.6/presubmit.cfg", + ".kokoro/samples/python3.7/common.cfg", + ".kokoro/samples/python3.7/continuous.cfg", + ".kokoro/samples/python3.7/periodic.cfg", + ".kokoro/samples/python3.7/presubmit.cfg", + ".kokoro/samples/python3.8/common.cfg", + ".kokoro/samples/python3.8/continuous.cfg", + ".kokoro/samples/python3.8/periodic.cfg", + ".kokoro/samples/python3.8/presubmit.cfg", + ".kokoro/test-samples.sh", + ".kokoro/trampoline.sh", + ".kokoro/trampoline_v2.sh", + ".trampolinerc", + "CODE_OF_CONDUCT.md", + "CONTRIBUTING.rst", + "LICENSE", + "MANIFEST.in", + "docs/_static/custom.css", + "docs/_templates/layout.html", + "docs/conf.py", + "docs/multiprocessing.rst", + "docs/speech_v1/services.rst", + "docs/speech_v1/types.rst", + "docs/speech_v1p1beta1/services.rst", + "docs/speech_v1p1beta1/types.rst", + "google/cloud/speech/__init__.py", + "google/cloud/speech/py.typed", + "google/cloud/speech_v1/__init__.py", + "google/cloud/speech_v1/proto/cloud_speech.proto", + "google/cloud/speech_v1/py.typed", + "google/cloud/speech_v1/services/__init__.py", + "google/cloud/speech_v1/services/speech/__init__.py", + "google/cloud/speech_v1/services/speech/async_client.py", + "google/cloud/speech_v1/services/speech/client.py", + "google/cloud/speech_v1/services/speech/transports/__init__.py", + "google/cloud/speech_v1/services/speech/transports/base.py", + "google/cloud/speech_v1/services/speech/transports/grpc.py", + "google/cloud/speech_v1/services/speech/transports/grpc_asyncio.py", + "google/cloud/speech_v1/types/__init__.py", + "google/cloud/speech_v1/types/cloud_speech.py", + "google/cloud/speech_v1p1beta1/__init__.py", + "google/cloud/speech_v1p1beta1/proto/cloud_speech.proto", + "google/cloud/speech_v1p1beta1/proto/resource.proto", + "google/cloud/speech_v1p1beta1/py.typed", + "google/cloud/speech_v1p1beta1/services/__init__.py", + "google/cloud/speech_v1p1beta1/services/speech/__init__.py", + "google/cloud/speech_v1p1beta1/services/speech/async_client.py", + "google/cloud/speech_v1p1beta1/services/speech/client.py", + "google/cloud/speech_v1p1beta1/services/speech/transports/__init__.py", + "google/cloud/speech_v1p1beta1/services/speech/transports/base.py", + "google/cloud/speech_v1p1beta1/services/speech/transports/grpc.py", + "google/cloud/speech_v1p1beta1/services/speech/transports/grpc_asyncio.py", + "google/cloud/speech_v1p1beta1/types/__init__.py", + "google/cloud/speech_v1p1beta1/types/cloud_speech.py", + "google/cloud/speech_v1p1beta1/types/resource.py", + "mypy.ini", + "noxfile.py", + "renovate.json", + "samples/AUTHORING_GUIDE.md", + "samples/CONTRIBUTING.md", + "samples/microphone/noxfile.py", + "samples/snippets/noxfile.py", + "scripts/decrypt-secrets.sh", + "scripts/fixup_speech_v1_keywords.py", + "scripts/fixup_speech_v1p1beta1_keywords.py", + "scripts/readme-gen/readme_gen.py", + "scripts/readme-gen/templates/README.tmpl.rst", + "scripts/readme-gen/templates/auth.tmpl.rst", + "scripts/readme-gen/templates/auth_api_key.tmpl.rst", + "scripts/readme-gen/templates/install_deps.tmpl.rst", + "scripts/readme-gen/templates/install_portaudio.tmpl.rst", + "setup.cfg", + "testing/.gitignore", + "tests/unit/gapic/speech_v1/__init__.py", + "tests/unit/gapic/speech_v1/test_speech.py", + "tests/unit/gapic/speech_v1p1beta1/__init__.py", + "tests/unit/gapic/speech_v1p1beta1/test_speech.py" ] } \ No newline at end of file diff --git a/tests/unit/gapic/speech_v1/test_speech.py b/tests/unit/gapic/speech_v1/test_speech.py index ccc2201b..55fee09c 100644 --- a/tests/unit/gapic/speech_v1/test_speech.py +++ b/tests/unit/gapic/speech_v1/test_speech.py @@ -90,12 +90,12 @@ def test_speech_client_from_service_account_file(client_class): ) as factory: factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds client = client_class.from_service_account_json("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds - assert client._transport._host == "speech.googleapis.com:443" + assert client.transport._host == "speech.googleapis.com:443" def test_speech_client_get_transport_class(): @@ -419,7 +419,7 @@ def test_recognize(transport: str = "grpc", request_type=cloud_speech.RecognizeR request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.recognize), "__call__") as call: + with mock.patch.object(type(client.transport.recognize), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = cloud_speech.RecognizeResponse() @@ -432,6 +432,7 @@ def test_recognize(transport: str = "grpc", request_type=cloud_speech.RecognizeR assert args[0] == cloud_speech.RecognizeRequest() # Establish that the response is the type that we expect. + assert isinstance(response, cloud_speech.RecognizeResponse) @@ -440,19 +441,19 @@ def test_recognize_from_dict(): @pytest.mark.asyncio -async def test_recognize_async(transport: str = "grpc_asyncio"): +async def test_recognize_async( + transport: str = "grpc_asyncio", request_type=cloud_speech.RecognizeRequest +): client = SpeechAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = cloud_speech.RecognizeRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.recognize), "__call__" - ) as call: + with mock.patch.object(type(client.transport.recognize), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( cloud_speech.RecognizeResponse() @@ -464,17 +465,22 @@ async def test_recognize_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == cloud_speech.RecognizeRequest() # Establish that the response is the type that we expect. assert isinstance(response, cloud_speech.RecognizeResponse) +@pytest.mark.asyncio +async def test_recognize_async_from_dict(): + await test_recognize_async(request_type=dict) + + def test_recognize_flattened(): client = SpeechClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.recognize), "__call__") as call: + with mock.patch.object(type(client.transport.recognize), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = cloud_speech.RecognizeResponse() @@ -519,9 +525,7 @@ async def test_recognize_flattened_async(): client = SpeechAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.recognize), "__call__" - ) as call: + with mock.patch.object(type(client.transport.recognize), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = cloud_speech.RecognizeResponse() @@ -578,7 +582,7 @@ def test_long_running_recognize( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.long_running_recognize), "__call__" + type(client.transport.long_running_recognize), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -600,18 +604,21 @@ def test_long_running_recognize_from_dict(): @pytest.mark.asyncio -async def test_long_running_recognize_async(transport: str = "grpc_asyncio"): +async def test_long_running_recognize_async( + transport: str = "grpc_asyncio", + request_type=cloud_speech.LongRunningRecognizeRequest, +): client = SpeechAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = cloud_speech.LongRunningRecognizeRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.long_running_recognize), "__call__" + type(client.transport.long_running_recognize), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -624,18 +631,23 @@ async def test_long_running_recognize_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == cloud_speech.LongRunningRecognizeRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_long_running_recognize_async_from_dict(): + await test_long_running_recognize_async(request_type=dict) + + def test_long_running_recognize_flattened(): client = SpeechClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.long_running_recognize), "__call__" + type(client.transport.long_running_recognize), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -682,7 +694,7 @@ async def test_long_running_recognize_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.long_running_recognize), "__call__" + type(client.transport.long_running_recognize), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -742,7 +754,7 @@ def test_streaming_recognize( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.streaming_recognize), "__call__" + type(client.transport.streaming_recognize), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = iter([cloud_speech.StreamingRecognizeResponse()]) @@ -765,20 +777,22 @@ def test_streaming_recognize_from_dict(): @pytest.mark.asyncio -async def test_streaming_recognize_async(transport: str = "grpc_asyncio"): +async def test_streaming_recognize_async( + transport: str = "grpc_asyncio", request_type=cloud_speech.StreamingRecognizeRequest +): client = SpeechAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = cloud_speech.StreamingRecognizeRequest() + request = request_type() requests = [request] # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.streaming_recognize), "__call__" + type(client.transport.streaming_recognize), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = mock.Mock(aio.StreamStreamCall, autospec=True) @@ -799,6 +813,11 @@ async def test_streaming_recognize_async(transport: str = "grpc_asyncio"): assert isinstance(message, cloud_speech.StreamingRecognizeResponse) +@pytest.mark.asyncio +async def test_streaming_recognize_async_from_dict(): + await test_streaming_recognize_async(request_type=dict) + + def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.SpeechGrpcTransport( @@ -835,7 +854,7 @@ def test_transport_instance(): credentials=credentials.AnonymousCredentials(), ) client = SpeechClient(transport=transport) - assert client._transport is transport + assert client.transport is transport def test_transport_get_channel(): @@ -868,7 +887,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = SpeechClient(credentials=credentials.AnonymousCredentials(),) - assert isinstance(client._transport, transports.SpeechGrpcTransport,) + assert isinstance(client.transport, transports.SpeechGrpcTransport,) def test_speech_base_transport_error(): @@ -969,7 +988,7 @@ def test_speech_host_no_port(): api_endpoint="speech.googleapis.com" ), ) - assert client._transport._host == "speech.googleapis.com:443" + assert client.transport._host == "speech.googleapis.com:443" def test_speech_host_with_port(): @@ -979,7 +998,7 @@ def test_speech_host_with_port(): api_endpoint="speech.googleapis.com:8000" ), ) - assert client._transport._host == "speech.googleapis.com:8000" + assert client.transport._host == "speech.googleapis.com:8000" def test_speech_grpc_transport_channel(): @@ -991,6 +1010,7 @@ def test_speech_grpc_transport_channel(): ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None def test_speech_grpc_asyncio_transport_channel(): @@ -1002,6 +1022,7 @@ def test_speech_grpc_asyncio_transport_channel(): ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None @pytest.mark.parametrize( @@ -1042,8 +1063,13 @@ def test_speech_transport_channel_mtls_with_client_cert_source(transport_class): scopes=("https://www.googleapis.com/auth/cloud-platform",), ssl_credentials=mock_ssl_cred, quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], ) assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred @pytest.mark.parametrize( @@ -1079,6 +1105,10 @@ def test_speech_transport_channel_mtls_with_adc(transport_class): scopes=("https://www.googleapis.com/auth/cloud-platform",), ssl_credentials=mock_ssl_cred, quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], ) assert transport.grpc_channel == mock_grpc_channel @@ -1087,7 +1117,7 @@ def test_speech_grpc_lro_client(): client = SpeechClient( credentials=credentials.AnonymousCredentials(), transport="grpc", ) - transport = client._transport + transport = client.transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsClient,) @@ -1100,7 +1130,7 @@ def test_speech_grpc_lro_async_client(): client = SpeechAsyncClient( credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio", ) - transport = client._client._transport + transport = client.transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsAsyncClient,) @@ -1109,6 +1139,107 @@ def test_speech_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client +def test_common_billing_account_path(): + billing_account = "squid" + + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = SpeechClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "clam", + } + path = SpeechClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = SpeechClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "whelk" + + expected = "folders/{folder}".format(folder=folder,) + actual = SpeechClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "octopus", + } + path = SpeechClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = SpeechClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "oyster" + + expected = "organizations/{organization}".format(organization=organization,) + actual = SpeechClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nudibranch", + } + path = SpeechClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = SpeechClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "cuttlefish" + + expected = "projects/{project}".format(project=project,) + actual = SpeechClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "mussel", + } + path = SpeechClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = SpeechClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "winkle" + location = "nautilus" + + expected = "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + actual = SpeechClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "scallop", + "location": "abalone", + } + path = SpeechClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = SpeechClient.parse_common_location_path(path) + assert expected == actual + + def test_client_withDEFAULT_CLIENT_INFO(): client_info = gapic_v1.client_info.ClientInfo() diff --git a/tests/unit/gapic/speech_v1p1beta1/test_speech.py b/tests/unit/gapic/speech_v1p1beta1/test_speech.py index 584ad0ac..e04fced2 100644 --- a/tests/unit/gapic/speech_v1p1beta1/test_speech.py +++ b/tests/unit/gapic/speech_v1p1beta1/test_speech.py @@ -91,12 +91,12 @@ def test_speech_client_from_service_account_file(client_class): ) as factory: factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds client = client_class.from_service_account_json("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds - assert client._transport._host == "speech.googleapis.com:443" + assert client.transport._host == "speech.googleapis.com:443" def test_speech_client_get_transport_class(): @@ -420,7 +420,7 @@ def test_recognize(transport: str = "grpc", request_type=cloud_speech.RecognizeR request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.recognize), "__call__") as call: + with mock.patch.object(type(client.transport.recognize), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = cloud_speech.RecognizeResponse() @@ -433,6 +433,7 @@ def test_recognize(transport: str = "grpc", request_type=cloud_speech.RecognizeR assert args[0] == cloud_speech.RecognizeRequest() # Establish that the response is the type that we expect. + assert isinstance(response, cloud_speech.RecognizeResponse) @@ -441,19 +442,19 @@ def test_recognize_from_dict(): @pytest.mark.asyncio -async def test_recognize_async(transport: str = "grpc_asyncio"): +async def test_recognize_async( + transport: str = "grpc_asyncio", request_type=cloud_speech.RecognizeRequest +): client = SpeechAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = cloud_speech.RecognizeRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.recognize), "__call__" - ) as call: + with mock.patch.object(type(client.transport.recognize), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( cloud_speech.RecognizeResponse() @@ -465,17 +466,22 @@ async def test_recognize_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == cloud_speech.RecognizeRequest() # Establish that the response is the type that we expect. assert isinstance(response, cloud_speech.RecognizeResponse) +@pytest.mark.asyncio +async def test_recognize_async_from_dict(): + await test_recognize_async(request_type=dict) + + def test_recognize_flattened(): client = SpeechClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.recognize), "__call__") as call: + with mock.patch.object(type(client.transport.recognize), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = cloud_speech.RecognizeResponse() @@ -520,9 +526,7 @@ async def test_recognize_flattened_async(): client = SpeechAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.recognize), "__call__" - ) as call: + with mock.patch.object(type(client.transport.recognize), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = cloud_speech.RecognizeResponse() @@ -579,7 +583,7 @@ def test_long_running_recognize( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.long_running_recognize), "__call__" + type(client.transport.long_running_recognize), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -601,18 +605,21 @@ def test_long_running_recognize_from_dict(): @pytest.mark.asyncio -async def test_long_running_recognize_async(transport: str = "grpc_asyncio"): +async def test_long_running_recognize_async( + transport: str = "grpc_asyncio", + request_type=cloud_speech.LongRunningRecognizeRequest, +): client = SpeechAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = cloud_speech.LongRunningRecognizeRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.long_running_recognize), "__call__" + type(client.transport.long_running_recognize), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -625,18 +632,23 @@ async def test_long_running_recognize_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == cloud_speech.LongRunningRecognizeRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_long_running_recognize_async_from_dict(): + await test_long_running_recognize_async(request_type=dict) + + def test_long_running_recognize_flattened(): client = SpeechClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.long_running_recognize), "__call__" + type(client.transport.long_running_recognize), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -683,7 +695,7 @@ async def test_long_running_recognize_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.long_running_recognize), "__call__" + type(client.transport.long_running_recognize), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -743,7 +755,7 @@ def test_streaming_recognize( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.streaming_recognize), "__call__" + type(client.transport.streaming_recognize), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = iter([cloud_speech.StreamingRecognizeResponse()]) @@ -766,20 +778,22 @@ def test_streaming_recognize_from_dict(): @pytest.mark.asyncio -async def test_streaming_recognize_async(transport: str = "grpc_asyncio"): +async def test_streaming_recognize_async( + transport: str = "grpc_asyncio", request_type=cloud_speech.StreamingRecognizeRequest +): client = SpeechAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = cloud_speech.StreamingRecognizeRequest() + request = request_type() requests = [request] # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.streaming_recognize), "__call__" + type(client.transport.streaming_recognize), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = mock.Mock(aio.StreamStreamCall, autospec=True) @@ -800,6 +814,11 @@ async def test_streaming_recognize_async(transport: str = "grpc_asyncio"): assert isinstance(message, cloud_speech.StreamingRecognizeResponse) +@pytest.mark.asyncio +async def test_streaming_recognize_async_from_dict(): + await test_streaming_recognize_async(request_type=dict) + + def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.SpeechGrpcTransport( @@ -836,7 +855,7 @@ def test_transport_instance(): credentials=credentials.AnonymousCredentials(), ) client = SpeechClient(transport=transport) - assert client._transport is transport + assert client.transport is transport def test_transport_get_channel(): @@ -869,7 +888,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = SpeechClient(credentials=credentials.AnonymousCredentials(),) - assert isinstance(client._transport, transports.SpeechGrpcTransport,) + assert isinstance(client.transport, transports.SpeechGrpcTransport,) def test_speech_base_transport_error(): @@ -970,7 +989,7 @@ def test_speech_host_no_port(): api_endpoint="speech.googleapis.com" ), ) - assert client._transport._host == "speech.googleapis.com:443" + assert client.transport._host == "speech.googleapis.com:443" def test_speech_host_with_port(): @@ -980,7 +999,7 @@ def test_speech_host_with_port(): api_endpoint="speech.googleapis.com:8000" ), ) - assert client._transport._host == "speech.googleapis.com:8000" + assert client.transport._host == "speech.googleapis.com:8000" def test_speech_grpc_transport_channel(): @@ -992,6 +1011,7 @@ def test_speech_grpc_transport_channel(): ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None def test_speech_grpc_asyncio_transport_channel(): @@ -1003,6 +1023,7 @@ def test_speech_grpc_asyncio_transport_channel(): ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None @pytest.mark.parametrize( @@ -1043,8 +1064,13 @@ def test_speech_transport_channel_mtls_with_client_cert_source(transport_class): scopes=("https://www.googleapis.com/auth/cloud-platform",), ssl_credentials=mock_ssl_cred, quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], ) assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred @pytest.mark.parametrize( @@ -1080,6 +1106,10 @@ def test_speech_transport_channel_mtls_with_adc(transport_class): scopes=("https://www.googleapis.com/auth/cloud-platform",), ssl_credentials=mock_ssl_cred, quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], ) assert transport.grpc_channel == mock_grpc_channel @@ -1088,7 +1118,7 @@ def test_speech_grpc_lro_client(): client = SpeechClient( credentials=credentials.AnonymousCredentials(), transport="grpc", ) - transport = client._transport + transport = client.transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsClient,) @@ -1101,7 +1131,7 @@ def test_speech_grpc_lro_async_client(): client = SpeechAsyncClient( credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio", ) - transport = client._client._transport + transport = client.transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsAsyncClient,) @@ -1136,9 +1166,9 @@ def test_parse_custom_class_path(): def test_phrase_set_path(): - project = "squid" - location = "clam" - phrase_set = "whelk" + project = "cuttlefish" + location = "mussel" + phrase_set = "winkle" expected = "projects/{project}/locations/{location}/phraseSets/{phrase_set}".format( project=project, location=location, phrase_set=phrase_set, @@ -1149,9 +1179,9 @@ def test_phrase_set_path(): def test_parse_phrase_set_path(): expected = { - "project": "octopus", - "location": "oyster", - "phrase_set": "nudibranch", + "project": "nautilus", + "location": "scallop", + "phrase_set": "abalone", } path = SpeechClient.phrase_set_path(**expected) @@ -1160,6 +1190,107 @@ def test_parse_phrase_set_path(): assert expected == actual +def test_common_billing_account_path(): + billing_account = "squid" + + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = SpeechClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "clam", + } + path = SpeechClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = SpeechClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "whelk" + + expected = "folders/{folder}".format(folder=folder,) + actual = SpeechClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "octopus", + } + path = SpeechClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = SpeechClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "oyster" + + expected = "organizations/{organization}".format(organization=organization,) + actual = SpeechClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nudibranch", + } + path = SpeechClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = SpeechClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "cuttlefish" + + expected = "projects/{project}".format(project=project,) + actual = SpeechClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "mussel", + } + path = SpeechClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = SpeechClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "winkle" + location = "nautilus" + + expected = "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + actual = SpeechClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "scallop", + "location": "abalone", + } + path = SpeechClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = SpeechClient.parse_common_location_path(path) + assert expected == actual + + def test_client_withDEFAULT_CLIENT_INFO(): client_info = gapic_v1.client_info.ClientInfo()