diff --git a/packages/google-cloud-retail/docs/retail_v2/model_service.rst b/packages/google-cloud-retail/docs/retail_v2/model_service.rst new file mode 100644 index 000000000000..68191fad3b1b --- /dev/null +++ b/packages/google-cloud-retail/docs/retail_v2/model_service.rst @@ -0,0 +1,10 @@ +ModelService +------------------------------ + +.. automodule:: google.cloud.retail_v2.services.model_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2.services.model_service.pagers + :members: + :inherited-members: diff --git a/packages/google-cloud-retail/docs/retail_v2/services.rst b/packages/google-cloud-retail/docs/retail_v2/services.rst index ef0ce8fbf87a..eba07fc3efbe 100644 --- a/packages/google-cloud-retail/docs/retail_v2/services.rst +++ b/packages/google-cloud-retail/docs/retail_v2/services.rst @@ -6,6 +6,7 @@ Services for Google Cloud Retail v2 API catalog_service completion_service control_service + model_service prediction_service product_service search_service diff --git a/packages/google-cloud-retail/docs/retail_v2alpha/merchant_center_account_link_service.rst b/packages/google-cloud-retail/docs/retail_v2alpha/merchant_center_account_link_service.rst new file mode 100644 index 000000000000..df93c4f8190c --- /dev/null +++ b/packages/google-cloud-retail/docs/retail_v2alpha/merchant_center_account_link_service.rst @@ -0,0 +1,6 @@ +MerchantCenterAccountLinkService +-------------------------------------------------- + +.. automodule:: google.cloud.retail_v2alpha.services.merchant_center_account_link_service + :members: + :inherited-members: diff --git a/packages/google-cloud-retail/docs/retail_v2alpha/services.rst b/packages/google-cloud-retail/docs/retail_v2alpha/services.rst index 5bb5aff7a5b7..464a57dc017f 100644 --- a/packages/google-cloud-retail/docs/retail_v2alpha/services.rst +++ b/packages/google-cloud-retail/docs/retail_v2alpha/services.rst @@ -6,6 +6,7 @@ Services for Google Cloud Retail v2alpha API catalog_service completion_service control_service + merchant_center_account_link_service model_service prediction_service product_service diff --git a/packages/google-cloud-retail/google/cloud/retail/__init__.py b/packages/google-cloud-retail/google/cloud/retail/__init__.py index 1273fc130af0..a8713a303c4d 100644 --- a/packages/google-cloud-retail/google/cloud/retail/__init__.py +++ b/packages/google-cloud-retail/google/cloud/retail/__init__.py @@ -32,6 +32,10 @@ ControlServiceAsyncClient, ) from google.cloud.retail_v2.services.control_service.client import ControlServiceClient +from google.cloud.retail_v2.services.model_service.async_client import ( + ModelServiceAsyncClient, +) +from google.cloud.retail_v2.services.model_service.client import ModelServiceClient from google.cloud.retail_v2.services.prediction_service.async_client import ( PredictionServiceAsyncClient, ) @@ -92,6 +96,7 @@ LocalInventory, PriceInfo, Rating, + RecommendationsFilteringOption, Rule, SearchSolutionUseCase, SolutionType, @@ -128,6 +133,21 @@ UserEventInlineSource, UserEventInputConfig, ) +from google.cloud.retail_v2.types.model import Model +from google.cloud.retail_v2.types.model_service import ( + CreateModelMetadata, + CreateModelRequest, + DeleteModelRequest, + GetModelRequest, + ListModelsRequest, + ListModelsResponse, + PauseModelRequest, + ResumeModelRequest, + TuneModelMetadata, + TuneModelRequest, + TuneModelResponse, + UpdateModelRequest, +) from google.cloud.retail_v2.types.prediction_service import ( PredictRequest, PredictResponse, @@ -162,7 +182,11 @@ PurgeUserEventsRequest, PurgeUserEventsResponse, ) -from google.cloud.retail_v2.types.search_service import SearchRequest, SearchResponse +from google.cloud.retail_v2.types.search_service import ( + ExperimentInfo, + SearchRequest, + SearchResponse, +) from google.cloud.retail_v2.types.serving_config import ServingConfig from google.cloud.retail_v2.types.serving_config_service import ( AddControlRequest, @@ -195,6 +219,8 @@ "CompletionServiceAsyncClient", "ControlServiceClient", "ControlServiceAsyncClient", + "ModelServiceClient", + "ModelServiceAsyncClient", "PredictionServiceClient", "PredictionServiceAsyncClient", "ProductServiceClient", @@ -236,6 +262,7 @@ "Rule", "UserInfo", "AttributeConfigLevel", + "RecommendationsFilteringOption", "SearchSolutionUseCase", "SolutionType", "CompleteQueryRequest", @@ -263,6 +290,19 @@ "UserEventImportSummary", "UserEventInlineSource", "UserEventInputConfig", + "Model", + "CreateModelMetadata", + "CreateModelRequest", + "DeleteModelRequest", + "GetModelRequest", + "ListModelsRequest", + "ListModelsResponse", + "PauseModelRequest", + "ResumeModelRequest", + "TuneModelMetadata", + "TuneModelRequest", + "TuneModelResponse", + "UpdateModelRequest", "PredictRequest", "PredictResponse", "Product", @@ -291,6 +331,7 @@ "PurgeMetadata", "PurgeUserEventsRequest", "PurgeUserEventsResponse", + "ExperimentInfo", "SearchRequest", "SearchResponse", "ServingConfig", diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/__init__.py b/packages/google-cloud-retail/google/cloud/retail_v2/__init__.py index e9eda32fef71..56f44b3bc559 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/__init__.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/__init__.py @@ -24,6 +24,7 @@ CompletionServiceClient, ) from .services.control_service import ControlServiceAsyncClient, ControlServiceClient +from .services.model_service import ModelServiceAsyncClient, ModelServiceClient from .services.prediction_service import ( PredictionServiceAsyncClient, PredictionServiceClient, @@ -72,6 +73,7 @@ LocalInventory, PriceInfo, Rating, + RecommendationsFilteringOption, Rule, SearchSolutionUseCase, SolutionType, @@ -105,6 +107,21 @@ UserEventInlineSource, UserEventInputConfig, ) +from .types.model import Model +from .types.model_service import ( + CreateModelMetadata, + CreateModelRequest, + DeleteModelRequest, + GetModelRequest, + ListModelsRequest, + ListModelsResponse, + PauseModelRequest, + ResumeModelRequest, + TuneModelMetadata, + TuneModelRequest, + TuneModelResponse, + UpdateModelRequest, +) from .types.prediction_service import PredictRequest, PredictResponse from .types.product import Product from .types.product_service import ( @@ -136,7 +153,7 @@ PurgeUserEventsRequest, PurgeUserEventsResponse, ) -from .types.search_service import SearchRequest, SearchResponse +from .types.search_service import ExperimentInfo, SearchRequest, SearchResponse from .types.serving_config import ServingConfig from .types.serving_config_service import ( AddControlRequest, @@ -166,6 +183,7 @@ "CatalogServiceAsyncClient", "CompletionServiceAsyncClient", "ControlServiceAsyncClient", + "ModelServiceAsyncClient", "PredictionServiceAsyncClient", "ProductServiceAsyncClient", "SearchServiceAsyncClient", @@ -198,12 +216,16 @@ "Control", "ControlServiceClient", "CreateControlRequest", + "CreateModelMetadata", + "CreateModelRequest", "CreateProductRequest", "CreateServingConfigRequest", "CustomAttribute", "DeleteControlRequest", + "DeleteModelRequest", "DeleteProductRequest", "DeleteServingConfigRequest", + "ExperimentInfo", "FulfillmentInfo", "GcsSource", "GetAttributesConfigRequest", @@ -211,6 +233,7 @@ "GetControlRequest", "GetDefaultBranchRequest", "GetDefaultBranchResponse", + "GetModelRequest", "GetProductRequest", "GetServingConfigRequest", "Image", @@ -227,11 +250,16 @@ "ListCatalogsResponse", "ListControlsRequest", "ListControlsResponse", + "ListModelsRequest", + "ListModelsResponse", "ListProductsRequest", "ListProductsResponse", "ListServingConfigsRequest", "ListServingConfigsResponse", "LocalInventory", + "Model", + "ModelServiceClient", + "PauseModelRequest", "PredictRequest", "PredictResponse", "PredictionServiceClient", @@ -248,6 +276,7 @@ "PurgeUserEventsRequest", "PurgeUserEventsResponse", "Rating", + "RecommendationsFilteringOption", "RejoinUserEventsMetadata", "RejoinUserEventsRequest", "RejoinUserEventsResponse", @@ -260,6 +289,7 @@ "RemoveLocalInventoriesRequest", "RemoveLocalInventoriesResponse", "ReplaceCatalogAttributeRequest", + "ResumeModelRequest", "Rule", "SearchRequest", "SearchResponse", @@ -272,10 +302,14 @@ "SetInventoryRequest", "SetInventoryResponse", "SolutionType", + "TuneModelMetadata", + "TuneModelRequest", + "TuneModelResponse", "UpdateAttributesConfigRequest", "UpdateCatalogRequest", "UpdateCompletionConfigRequest", "UpdateControlRequest", + "UpdateModelRequest", "UpdateProductRequest", "UpdateServingConfigRequest", "UserEvent", diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/gapic_metadata.json b/packages/google-cloud-retail/google/cloud/retail_v2/gapic_metadata.json index bf159db2495a..8130fa0158a3 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/gapic_metadata.json +++ b/packages/google-cloud-retail/google/cloud/retail_v2/gapic_metadata.json @@ -332,6 +332,145 @@ } } }, + "ModelService": { + "clients": { + "grpc": { + "libraryClient": "ModelServiceClient", + "rpcs": { + "CreateModel": { + "methods": [ + "create_model" + ] + }, + "DeleteModel": { + "methods": [ + "delete_model" + ] + }, + "GetModel": { + "methods": [ + "get_model" + ] + }, + "ListModels": { + "methods": [ + "list_models" + ] + }, + "PauseModel": { + "methods": [ + "pause_model" + ] + }, + "ResumeModel": { + "methods": [ + "resume_model" + ] + }, + "TuneModel": { + "methods": [ + "tune_model" + ] + }, + "UpdateModel": { + "methods": [ + "update_model" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ModelServiceAsyncClient", + "rpcs": { + "CreateModel": { + "methods": [ + "create_model" + ] + }, + "DeleteModel": { + "methods": [ + "delete_model" + ] + }, + "GetModel": { + "methods": [ + "get_model" + ] + }, + "ListModels": { + "methods": [ + "list_models" + ] + }, + "PauseModel": { + "methods": [ + "pause_model" + ] + }, + "ResumeModel": { + "methods": [ + "resume_model" + ] + }, + "TuneModel": { + "methods": [ + "tune_model" + ] + }, + "UpdateModel": { + "methods": [ + "update_model" + ] + } + } + }, + "rest": { + "libraryClient": "ModelServiceClient", + "rpcs": { + "CreateModel": { + "methods": [ + "create_model" + ] + }, + "DeleteModel": { + "methods": [ + "delete_model" + ] + }, + "GetModel": { + "methods": [ + "get_model" + ] + }, + "ListModels": { + "methods": [ + "list_models" + ] + }, + "PauseModel": { + "methods": [ + "pause_model" + ] + }, + "ResumeModel": { + "methods": [ + "resume_model" + ] + }, + "TuneModel": { + "methods": [ + "tune_model" + ] + }, + "UpdateModel": { + "methods": [ + "update_model" + ] + } + } + } + } + }, "PredictionService": { "clients": { "grpc": { diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/services/completion_service/async_client.py b/packages/google-cloud-retail/google/cloud/retail_v2/services/completion_service/async_client.py index 1b90404d50fd..0472fc4ed1b4 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/services/completion_service/async_client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/services/completion_service/async_client.py @@ -55,7 +55,7 @@ class CompletionServiceAsyncClient: - """Auto-completion service for retail. + """Autocomplete service for retail. This feature is only available for users who have Retail Search enabled. Enable Retail Search on Cloud Console before using this feature. @@ -265,7 +265,7 @@ async def sample_complete_query(): Args: request (Optional[Union[google.cloud.retail_v2.types.CompleteQueryRequest, dict]]): - The request object. Auto-complete parameters. + The request object. Autocomplete parameters. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -274,7 +274,7 @@ async def sample_complete_query(): Returns: google.cloud.retail_v2.types.CompleteQueryResponse: - Response of the auto-complete query. + Response of the autocomplete query. """ # Create or coerce a protobuf request object. request = completion_service.CompleteQueryRequest(request) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/services/completion_service/client.py b/packages/google-cloud-retail/google/cloud/retail_v2/services/completion_service/client.py index 01cbaac4fce0..3c8aca2b1a02 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/services/completion_service/client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/services/completion_service/client.py @@ -97,7 +97,7 @@ def get_transport_class( class CompletionServiceClient(metaclass=CompletionServiceClientMeta): - """Auto-completion service for retail. + """Autocomplete service for retail. This feature is only available for users who have Retail Search enabled. Enable Retail Search on Cloud Console before using this feature. @@ -494,7 +494,7 @@ def sample_complete_query(): Args: request (Union[google.cloud.retail_v2.types.CompleteQueryRequest, dict]): - The request object. Auto-complete parameters. + The request object. Autocomplete parameters. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -503,7 +503,7 @@ def sample_complete_query(): Returns: google.cloud.retail_v2.types.CompleteQueryResponse: - Response of the auto-complete query. + Response of the autocomplete query. """ # Create or coerce a protobuf request object. # Minor optimization to avoid making a copy if the user passes diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/services/completion_service/transports/grpc.py b/packages/google-cloud-retail/google/cloud/retail_v2/services/completion_service/transports/grpc.py index 06ddaac4ff50..203a28332d34 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/services/completion_service/transports/grpc.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/services/completion_service/transports/grpc.py @@ -32,7 +32,7 @@ class CompletionServiceGrpcTransport(CompletionServiceTransport): """gRPC backend transport for CompletionService. - Auto-completion service for retail. + Autocomplete service for retail. This feature is only available for users who have Retail Search enabled. Enable Retail Search on Cloud Console before using this feature. diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/services/completion_service/transports/grpc_asyncio.py b/packages/google-cloud-retail/google/cloud/retail_v2/services/completion_service/transports/grpc_asyncio.py index 949716c7498d..595d1d4db8b2 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/services/completion_service/transports/grpc_asyncio.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/services/completion_service/transports/grpc_asyncio.py @@ -33,7 +33,7 @@ class CompletionServiceGrpcAsyncIOTransport(CompletionServiceTransport): """gRPC AsyncIO backend transport for CompletionService. - Auto-completion service for retail. + Autocomplete service for retail. This feature is only available for users who have Retail Search enabled. Enable Retail Search on Cloud Console before using this feature. diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/services/completion_service/transports/rest.py b/packages/google-cloud-retail/google/cloud/retail_v2/services/completion_service/transports/rest.py index a6dc70eb5eba..72b339d46364 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/services/completion_service/transports/rest.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/services/completion_service/transports/rest.py @@ -198,7 +198,7 @@ class CompletionServiceRestStub: class CompletionServiceRestTransport(CompletionServiceTransport): """REST backend transport for CompletionService. - Auto-completion service for retail. + Autocomplete service for retail. This feature is only available for users who have Retail Search enabled. Enable Retail Search on Cloud Console before using this feature. @@ -376,7 +376,7 @@ def __call__( Args: request (~.completion_service.CompleteQueryRequest): - The request object. Auto-complete parameters. + The request object. Autocomplete parameters. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -385,7 +385,7 @@ def __call__( Returns: ~.completion_service.CompleteQueryResponse: - Response of the auto-complete query. + Response of the autocomplete query. """ http_options: List[Dict[str, str]] = [ diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/__init__.py b/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/__init__.py new file mode 100644 index 000000000000..fa113724a380 --- /dev/null +++ b/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .async_client import ModelServiceAsyncClient +from .client import ModelServiceClient + +__all__ = ( + "ModelServiceClient", + "ModelServiceAsyncClient", +) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/async_client.py b/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/async_client.py new file mode 100644 index 000000000000..56723f8e75c2 --- /dev/null +++ b/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/async_client.py @@ -0,0 +1,1261 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +import functools +import re +from typing import ( + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, +) + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core.client_options import ClientOptions +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.retail_v2 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + +from google.cloud.retail_v2.services.model_service import pagers +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import model +from google.cloud.retail_v2.types import model as gcr_model +from google.cloud.retail_v2.types import model_service + +from .client import ModelServiceClient +from .transports.base import DEFAULT_CLIENT_INFO, ModelServiceTransport +from .transports.grpc_asyncio import ModelServiceGrpcAsyncIOTransport + + +class ModelServiceAsyncClient: + """Service for performing CRUD operations on models. Recommendation + models contain all the metadata necessary to generate a set of + models for the ``Predict()`` API. A model is queried indirectly via + a ServingConfig, which associates a model with a given Placement + (e.g. Frequently Bought Together on Home Page). + + This service allows you to do the following: + + - Initiate training of a model. + - Pause training of an existing model. + - List all the available models along with their metadata. + - Control their tuning schedule. + """ + + _client: ModelServiceClient + + DEFAULT_ENDPOINT = ModelServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ModelServiceClient.DEFAULT_MTLS_ENDPOINT + + catalog_path = staticmethod(ModelServiceClient.catalog_path) + parse_catalog_path = staticmethod(ModelServiceClient.parse_catalog_path) + model_path = staticmethod(ModelServiceClient.model_path) + parse_model_path = staticmethod(ModelServiceClient.parse_model_path) + common_billing_account_path = staticmethod( + ModelServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + ModelServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(ModelServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(ModelServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(ModelServiceClient.common_organization_path) + parse_common_organization_path = staticmethod( + ModelServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod(ModelServiceClient.common_project_path) + parse_common_project_path = staticmethod( + ModelServiceClient.parse_common_project_path + ) + common_location_path = staticmethod(ModelServiceClient.common_location_path) + parse_common_location_path = staticmethod( + ModelServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ModelServiceAsyncClient: The constructed client. + """ + return ModelServiceClient.from_service_account_info.__func__(ModelServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ModelServiceAsyncClient: The constructed client. + """ + return ModelServiceClient.from_service_account_file.__func__(ModelServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ModelServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ModelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ModelServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial( + type(ModelServiceClient).get_transport_class, type(ModelServiceClient) + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ModelServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the model service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.ModelServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ModelServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + async def create_model( + self, + request: Optional[Union[model_service.CreateModelRequest, dict]] = None, + *, + parent: Optional[str] = None, + model: Optional[gcr_model.Model] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Creates a new model. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2 + + async def sample_create_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + model = retail_v2.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2.CreateModelRequest( + parent="parent_value", + model=model, + ) + + # Make the request + operation = client.create_model(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.CreateModelRequest, dict]]): + The request object. Request for creating a model. + parent (:class:`str`): + Required. The parent resource under which to create the + model. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + model (:class:`google.cloud.retail_v2.types.Model`): + Required. The payload of the + [Model][google.cloud.retail.v2.Model] to create. + + This corresponds to the ``model`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2.types.Model` Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, model]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = model_service.CreateModelRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if model is not None: + request.model = model + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_model, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + gcr_model.Model, + metadata_type=model_service.CreateModelMetadata, + ) + + # Done; return the response. + return response + + async def get_model( + self, + request: Optional[Union[model_service.GetModelRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> model.Model: + r"""Gets a model. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2 + + async def sample_get_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.GetModelRequest( + name="name_value", + ) + + # Make the request + response = await client.get_model(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.GetModelRequest, dict]]): + The request object. Request for getting a model. + name (:class:`str`): + Required. The resource name of the + [Model][google.cloud.retail.v2.Model] to get. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog}/models/{model_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = model_service.GetModelRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_model, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def pause_model( + self, + request: Optional[Union[model_service.PauseModelRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> model.Model: + r"""Pauses the training of an existing model. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2 + + async def sample_pause_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.PauseModelRequest( + name="name_value", + ) + + # Make the request + response = await client.pause_model(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.PauseModelRequest, dict]]): + The request object. Request for pausing training of a + model. + name (:class:`str`): + Required. The name of the model to pause. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = model_service.PauseModelRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.pause_model, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def resume_model( + self, + request: Optional[Union[model_service.ResumeModelRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> model.Model: + r"""Resumes the training of an existing model. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2 + + async def sample_resume_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.ResumeModelRequest( + name="name_value", + ) + + # Make the request + response = await client.resume_model(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.ResumeModelRequest, dict]]): + The request object. Request for resuming training of a + model. + name (:class:`str`): + Required. The name of the model to resume. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = model_service.ResumeModelRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.resume_model, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_model( + self, + request: Optional[Union[model_service.DeleteModelRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes an existing model. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2 + + async def sample_delete_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.DeleteModelRequest( + name="name_value", + ) + + # Make the request + await client.delete_model(request=request) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.DeleteModelRequest, dict]]): + The request object. Request for deleting a model. + name (:class:`str`): + Required. The resource name of the + [Model][google.cloud.retail.v2.Model] to delete. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = model_service.DeleteModelRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_model, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def list_models( + self, + request: Optional[Union[model_service.ListModelsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListModelsAsyncPager: + r"""Lists all the models linked to this event store. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2 + + async def sample_list_models(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.ListModelsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_models(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.ListModelsRequest, dict]]): + The request object. Request for listing models associated + with a resource. + parent (:class:`str`): + Required. The parent for which to list models. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.services.model_service.pagers.ListModelsAsyncPager: + Response to a ListModelRequest. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = model_service.ListModelsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_models, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListModelsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_model( + self, + request: Optional[Union[model_service.UpdateModelRequest, dict]] = None, + *, + model: Optional[gcr_model.Model] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_model.Model: + r"""Update of model metadata. Only fields that currently can be + updated are: ``filtering_option`` and ``periodic_tuning_state``. + If other values are provided, this API method ignores them. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2 + + async def sample_update_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + model = retail_v2.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2.UpdateModelRequest( + model=model, + ) + + # Make the request + response = await client.update_model(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.UpdateModelRequest, dict]]): + The request object. Request for updating an existing + model. + model (:class:`google.cloud.retail_v2.types.Model`): + Required. The body of the updated + [Model][google.cloud.retail.v2.Model]. + + This corresponds to the ``model`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Optional. Indicates which fields in + the provided 'model' to update. If not + set, by default updates all fields. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([model, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = model_service.UpdateModelRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if model is not None: + request.model = model + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_model, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("model.name", request.model.name),) + ), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def tune_model( + self, + request: Optional[Union[model_service.TuneModelRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Tunes an existing model. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2 + + async def sample_tune_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.TuneModelRequest( + name="name_value", + ) + + # Make the request + operation = client.tune_model(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.TuneModelRequest, dict]]): + The request object. Request to manually start a tuning + process now (instead of waiting for the + periodically scheduled tuning to + happen). + name (:class:`str`): + Required. The resource name of the model to tune. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.retail_v2.types.TuneModelResponse` + Response associated with a tune operation. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = model_service.TuneModelRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.tune_model, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + model_service.TuneModelResponse, + metadata_type=model_service.TuneModelMetadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + + +__all__ = ("ModelServiceAsyncClient",) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/client.py b/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/client.py new file mode 100644 index 000000000000..4c38c37fb3bc --- /dev/null +++ b/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/client.py @@ -0,0 +1,1521 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +import os +import re +from typing import ( + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.retail_v2 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + +from google.cloud.retail_v2.services.model_service import pagers +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import model +from google.cloud.retail_v2.types import model as gcr_model +from google.cloud.retail_v2.types import model_service + +from .transports.base import DEFAULT_CLIENT_INFO, ModelServiceTransport +from .transports.grpc import ModelServiceGrpcTransport +from .transports.grpc_asyncio import ModelServiceGrpcAsyncIOTransport +from .transports.rest import ModelServiceRestTransport + + +class ModelServiceClientMeta(type): + """Metaclass for the ModelService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = OrderedDict() # type: Dict[str, Type[ModelServiceTransport]] + _transport_registry["grpc"] = ModelServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ModelServiceGrpcAsyncIOTransport + _transport_registry["rest"] = ModelServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ModelServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ModelServiceClient(metaclass=ModelServiceClientMeta): + """Service for performing CRUD operations on models. Recommendation + models contain all the metadata necessary to generate a set of + models for the ``Predict()`` API. A model is queried indirectly via + a ServingConfig, which associates a model with a given Placement + (e.g. Frequently Bought Together on Home Page). + + This service allows you to do the following: + + - Initiate training of a model. + - Pause training of an existing model. + - List all the available models along with their metadata. + - Control their tuning schedule. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_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: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "retail.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ModelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ModelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file(filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ModelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ModelServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def catalog_path( + project: str, + location: str, + catalog: str, + ) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format( + project=project, + location=location, + catalog=catalog, + ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str, str]: + """Parses a catalog path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def model_path( + project: str, + location: str, + catalog: str, + model: str, + ) -> str: + """Returns a fully-qualified model string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/models/{model}".format( + project=project, + location=location, + catalog=catalog, + model=model, + ) + + @staticmethod + def parse_model_path(path: str) -> Dict[str, str]: + """Parses a model path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/models/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns 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: + """Returns 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: + """Returns 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: + """Returns 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: + """Returns 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 {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[Union[str, ModelServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the model service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ModelServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + client_options = cast(client_options_lib.ClientOptions, client_options) + + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source( + client_options + ) + + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ModelServiceTransport): + # transport is a ModelServiceTransport instance. + if credentials or client_options.credentials_file or api_key_value: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=client_options.api_audience, + ) + + def create_model( + self, + request: Optional[Union[model_service.CreateModelRequest, dict]] = None, + *, + parent: Optional[str] = None, + model: Optional[gcr_model.Model] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Creates a new model. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2 + + def sample_create_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + model = retail_v2.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2.CreateModelRequest( + parent="parent_value", + model=model, + ) + + # Make the request + operation = client.create_model(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.CreateModelRequest, dict]): + The request object. Request for creating a model. + parent (str): + Required. The parent resource under which to create the + model. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + model (google.cloud.retail_v2.types.Model): + Required. The payload of the + [Model][google.cloud.retail.v2.Model] to create. + + This corresponds to the ``model`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2.types.Model` Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, model]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a model_service.CreateModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.CreateModelRequest): + request = model_service.CreateModelRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if model is not None: + request.model = model + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_model] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + gcr_model.Model, + metadata_type=model_service.CreateModelMetadata, + ) + + # Done; return the response. + return response + + def get_model( + self, + request: Optional[Union[model_service.GetModelRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> model.Model: + r"""Gets a model. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2 + + def sample_get_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.GetModelRequest( + name="name_value", + ) + + # Make the request + response = client.get_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.GetModelRequest, dict]): + The request object. Request for getting a model. + name (str): + Required. The resource name of the + [Model][google.cloud.retail.v2.Model] to get. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog}/models/{model_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a model_service.GetModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.GetModelRequest): + request = model_service.GetModelRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_model] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def pause_model( + self, + request: Optional[Union[model_service.PauseModelRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> model.Model: + r"""Pauses the training of an existing model. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2 + + def sample_pause_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.PauseModelRequest( + name="name_value", + ) + + # Make the request + response = client.pause_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.PauseModelRequest, dict]): + The request object. Request for pausing training of a + model. + name (str): + Required. The name of the model to pause. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a model_service.PauseModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.PauseModelRequest): + request = model_service.PauseModelRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.pause_model] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def resume_model( + self, + request: Optional[Union[model_service.ResumeModelRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> model.Model: + r"""Resumes the training of an existing model. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2 + + def sample_resume_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.ResumeModelRequest( + name="name_value", + ) + + # Make the request + response = client.resume_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.ResumeModelRequest, dict]): + The request object. Request for resuming training of a + model. + name (str): + Required. The name of the model to resume. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a model_service.ResumeModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.ResumeModelRequest): + request = model_service.ResumeModelRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.resume_model] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_model( + self, + request: Optional[Union[model_service.DeleteModelRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes an existing model. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2 + + def sample_delete_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.DeleteModelRequest( + name="name_value", + ) + + # Make the request + client.delete_model(request=request) + + Args: + request (Union[google.cloud.retail_v2.types.DeleteModelRequest, dict]): + The request object. Request for deleting a model. + name (str): + Required. The resource name of the + [Model][google.cloud.retail.v2.Model] to delete. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a model_service.DeleteModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.DeleteModelRequest): + request = model_service.DeleteModelRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_model] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def list_models( + self, + request: Optional[Union[model_service.ListModelsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListModelsPager: + r"""Lists all the models linked to this event store. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2 + + def sample_list_models(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.ListModelsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_models(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.ListModelsRequest, dict]): + The request object. Request for listing models associated + with a resource. + parent (str): + Required. The parent for which to list models. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.services.model_service.pagers.ListModelsPager: + Response to a ListModelRequest. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a model_service.ListModelsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.ListModelsRequest): + request = model_service.ListModelsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_models] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListModelsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_model( + self, + request: Optional[Union[model_service.UpdateModelRequest, dict]] = None, + *, + model: Optional[gcr_model.Model] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_model.Model: + r"""Update of model metadata. Only fields that currently can be + updated are: ``filtering_option`` and ``periodic_tuning_state``. + If other values are provided, this API method ignores them. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2 + + def sample_update_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + model = retail_v2.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2.UpdateModelRequest( + model=model, + ) + + # Make the request + response = client.update_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.UpdateModelRequest, dict]): + The request object. Request for updating an existing + model. + model (google.cloud.retail_v2.types.Model): + Required. The body of the updated + [Model][google.cloud.retail.v2.Model]. + + This corresponds to the ``model`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. Indicates which fields in + the provided 'model' to update. If not + set, by default updates all fields. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([model, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a model_service.UpdateModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.UpdateModelRequest): + request = model_service.UpdateModelRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if model is not None: + request.model = model + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_model] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("model.name", request.model.name),) + ), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def tune_model( + self, + request: Optional[Union[model_service.TuneModelRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Tunes an existing model. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2 + + def sample_tune_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.TuneModelRequest( + name="name_value", + ) + + # Make the request + operation = client.tune_model(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.TuneModelRequest, dict]): + The request object. Request to manually start a tuning + process now (instead of waiting for the + periodically scheduled tuning to + happen). + name (str): + Required. The resource name of the model to tune. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.retail_v2.types.TuneModelResponse` + Response associated with a tune operation. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a model_service.TuneModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.TuneModelRequest): + request = model_service.TuneModelRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.tune_model] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + model_service.TuneModelResponse, + metadata_type=model_service.TuneModelMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ModelServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + + +__all__ = ("ModelServiceClient",) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/pagers.py b/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/pagers.py new file mode 100644 index 000000000000..4f83e33e8948 --- /dev/null +++ b/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/pagers.py @@ -0,0 +1,155 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, +) + +from google.cloud.retail_v2.types import model, model_service + + +class ListModelsPager: + """A pager for iterating through ``list_models`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2.types.ListModelsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``models`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListModels`` requests and continue to iterate + through the ``models`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2.types.ListModelsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., model_service.ListModelsResponse], + request: model_service.ListModelsRequest, + response: model_service.ListModelsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.retail_v2.types.ListModelsRequest): + The initial request object. + response (google.cloud.retail_v2.types.ListModelsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = model_service.ListModelsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[model_service.ListModelsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[model.Model]: + for page in self.pages: + yield from page.models + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListModelsAsyncPager: + """A pager for iterating through ``list_models`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2.types.ListModelsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``models`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListModels`` requests and continue to iterate + through the ``models`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2.types.ListModelsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., Awaitable[model_service.ListModelsResponse]], + request: model_service.ListModelsRequest, + response: model_service.ListModelsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.retail_v2.types.ListModelsRequest): + The initial request object. + response (google.cloud.retail_v2.types.ListModelsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = model_service.ListModelsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[model_service.ListModelsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__(self) -> AsyncIterator[model.Model]: + async def async_generator(): + async for page in self.pages: + for response in page.models: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/transports/__init__.py b/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/transports/__init__.py new file mode 100644 index 000000000000..5041c1c05a07 --- /dev/null +++ b/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/transports/__init__.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from typing import Dict, Type + +from .base import ModelServiceTransport +from .grpc import ModelServiceGrpcTransport +from .grpc_asyncio import ModelServiceGrpcAsyncIOTransport +from .rest import ModelServiceRestInterceptor, ModelServiceRestTransport + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ModelServiceTransport]] +_transport_registry["grpc"] = ModelServiceGrpcTransport +_transport_registry["grpc_asyncio"] = ModelServiceGrpcAsyncIOTransport +_transport_registry["rest"] = ModelServiceRestTransport + +__all__ = ( + "ModelServiceTransport", + "ModelServiceGrpcTransport", + "ModelServiceGrpcAsyncIOTransport", + "ModelServiceRestTransport", + "ModelServiceRestInterceptor", +) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/transports/base.py b/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/transports/base.py new file mode 100644 index 000000000000..b87c01d270fb --- /dev/null +++ b/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/transports/base.py @@ -0,0 +1,284 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, operations_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +from google.protobuf import empty_pb2 # type: ignore + +from google.cloud.retail_v2 import gapic_version as package_version +from google.cloud.retail_v2.types import model +from google.cloud.retail_v2.types import model as gcr_model +from google.cloud.retail_v2.types import model_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + + +class ModelServiceTransport(abc.ABC): + """Abstract transport class for ModelService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + + DEFAULT_HOST: str = "retail.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[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, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + 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): + 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. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, **scopes_kwargs, quota_project_id=quota_project_id + ) + elif credentials is None: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr(service_account.Credentials, "with_always_use_jwt_access") + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.create_model: gapic_v1.method.wrap_method( + self.create_model, + default_timeout=None, + client_info=client_info, + ), + self.get_model: gapic_v1.method.wrap_method( + self.get_model, + default_timeout=None, + client_info=client_info, + ), + self.pause_model: gapic_v1.method.wrap_method( + self.pause_model, + default_timeout=None, + client_info=client_info, + ), + self.resume_model: gapic_v1.method.wrap_method( + self.resume_model, + default_timeout=None, + client_info=client_info, + ), + self.delete_model: gapic_v1.method.wrap_method( + self.delete_model, + default_timeout=None, + client_info=client_info, + ), + self.list_models: gapic_v1.method.wrap_method( + self.list_models, + default_timeout=None, + client_info=client_info, + ), + self.update_model: gapic_v1.method.wrap_method( + self.update_model, + default_timeout=None, + client_info=client_info, + ), + self.tune_model: gapic_v1.method.wrap_method( + self.tune_model, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def create_model( + self, + ) -> Callable[ + [model_service.CreateModelRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def get_model( + self, + ) -> Callable[ + [model_service.GetModelRequest], Union[model.Model, Awaitable[model.Model]] + ]: + raise NotImplementedError() + + @property + def pause_model( + self, + ) -> Callable[ + [model_service.PauseModelRequest], Union[model.Model, Awaitable[model.Model]] + ]: + raise NotImplementedError() + + @property + def resume_model( + self, + ) -> Callable[ + [model_service.ResumeModelRequest], Union[model.Model, Awaitable[model.Model]] + ]: + raise NotImplementedError() + + @property + def delete_model( + self, + ) -> Callable[ + [model_service.DeleteModelRequest], + Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], + ]: + raise NotImplementedError() + + @property + def list_models( + self, + ) -> Callable[ + [model_service.ListModelsRequest], + Union[ + model_service.ListModelsResponse, + Awaitable[model_service.ListModelsResponse], + ], + ]: + raise NotImplementedError() + + @property + def update_model( + self, + ) -> Callable[ + [model_service.UpdateModelRequest], + Union[gcr_model.Model, Awaitable[gcr_model.Model]], + ]: + raise NotImplementedError() + + @property + def tune_model( + self, + ) -> Callable[ + [model_service.TuneModelRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[ + operations_pb2.ListOperationsResponse, + Awaitable[operations_pb2.ListOperationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ModelServiceTransport",) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/transports/grpc.py b/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/transports/grpc.py new file mode 100644 index 000000000000..33d6c6718453 --- /dev/null +++ b/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/transports/grpc.py @@ -0,0 +1,510 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import Callable, Dict, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import gapic_v1, grpc_helpers, operations_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +import grpc # type: ignore + +from google.cloud.retail_v2.types import model +from google.cloud.retail_v2.types import model as gcr_model +from google.cloud.retail_v2.types import model_service + +from .base import DEFAULT_CLIENT_INFO, ModelServiceTransport + + +class ModelServiceGrpcTransport(ModelServiceTransport): + """gRPC backend transport for ModelService. + + Service for performing CRUD operations on models. Recommendation + models contain all the metadata necessary to generate a set of + models for the ``Predict()`` API. A model is queried indirectly via + a ServingConfig, which associates a model with a given Placement + (e.g. Frequently Bought Together on Home Page). + + This service allows you to do the following: + + - Initiate training of a model. + - Pause training of an existing model. + - List all the available models along with their metadata. + - Control their tuning schedule. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "retail.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[grpc.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # 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 + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "retail.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient(self.grpc_channel) + + # Return the client from cache. + return self._operations_client + + @property + def create_model( + self, + ) -> Callable[[model_service.CreateModelRequest], operations_pb2.Operation]: + r"""Return a callable for the create model method over gRPC. + + Creates a new model. + + Returns: + Callable[[~.CreateModelRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_model" not in self._stubs: + self._stubs["create_model"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2.ModelService/CreateModel", + request_serializer=model_service.CreateModelRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_model"] + + @property + def get_model(self) -> Callable[[model_service.GetModelRequest], model.Model]: + r"""Return a callable for the get model method over gRPC. + + Gets a model. + + Returns: + Callable[[~.GetModelRequest], + ~.Model]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_model" not in self._stubs: + self._stubs["get_model"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2.ModelService/GetModel", + request_serializer=model_service.GetModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs["get_model"] + + @property + def pause_model(self) -> Callable[[model_service.PauseModelRequest], model.Model]: + r"""Return a callable for the pause model method over gRPC. + + Pauses the training of an existing model. + + Returns: + Callable[[~.PauseModelRequest], + ~.Model]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "pause_model" not in self._stubs: + self._stubs["pause_model"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2.ModelService/PauseModel", + request_serializer=model_service.PauseModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs["pause_model"] + + @property + def resume_model(self) -> Callable[[model_service.ResumeModelRequest], model.Model]: + r"""Return a callable for the resume model method over gRPC. + + Resumes the training of an existing model. + + Returns: + Callable[[~.ResumeModelRequest], + ~.Model]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "resume_model" not in self._stubs: + self._stubs["resume_model"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2.ModelService/ResumeModel", + request_serializer=model_service.ResumeModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs["resume_model"] + + @property + def delete_model( + self, + ) -> Callable[[model_service.DeleteModelRequest], empty_pb2.Empty]: + r"""Return a callable for the delete model method over gRPC. + + Deletes an existing model. + + Returns: + Callable[[~.DeleteModelRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_model" not in self._stubs: + self._stubs["delete_model"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2.ModelService/DeleteModel", + request_serializer=model_service.DeleteModelRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_model"] + + @property + def list_models( + self, + ) -> Callable[[model_service.ListModelsRequest], model_service.ListModelsResponse]: + r"""Return a callable for the list models method over gRPC. + + Lists all the models linked to this event store. + + Returns: + Callable[[~.ListModelsRequest], + ~.ListModelsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_models" not in self._stubs: + self._stubs["list_models"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2.ModelService/ListModels", + request_serializer=model_service.ListModelsRequest.serialize, + response_deserializer=model_service.ListModelsResponse.deserialize, + ) + return self._stubs["list_models"] + + @property + def update_model( + self, + ) -> Callable[[model_service.UpdateModelRequest], gcr_model.Model]: + r"""Return a callable for the update model method over gRPC. + + Update of model metadata. Only fields that currently can be + updated are: ``filtering_option`` and ``periodic_tuning_state``. + If other values are provided, this API method ignores them. + + Returns: + Callable[[~.UpdateModelRequest], + ~.Model]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_model" not in self._stubs: + self._stubs["update_model"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2.ModelService/UpdateModel", + request_serializer=model_service.UpdateModelRequest.serialize, + response_deserializer=gcr_model.Model.deserialize, + ) + return self._stubs["update_model"] + + @property + def tune_model( + self, + ) -> Callable[[model_service.TuneModelRequest], operations_pb2.Operation]: + r"""Return a callable for the tune model method over gRPC. + + Tunes an existing model. + + Returns: + Callable[[~.TuneModelRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "tune_model" not in self._stubs: + self._stubs["tune_model"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2.ModelService/TuneModel", + request_serializer=model_service.TuneModelRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["tune_model"] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("ModelServiceGrpcTransport",) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/transports/grpc_asyncio.py b/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/transports/grpc_asyncio.py new file mode 100644 index 000000000000..b2c8676ed784 --- /dev/null +++ b/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/transports/grpc_asyncio.py @@ -0,0 +1,523 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import gapic_v1, grpc_helpers_async, operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.retail_v2.types import model +from google.cloud.retail_v2.types import model as gcr_model +from google.cloud.retail_v2.types import model_service + +from .base import DEFAULT_CLIENT_INFO, ModelServiceTransport +from .grpc import ModelServiceGrpcTransport + + +class ModelServiceGrpcAsyncIOTransport(ModelServiceTransport): + """gRPC AsyncIO backend transport for ModelService. + + Service for performing CRUD operations on models. Recommendation + models contain all the metadata necessary to generate a set of + models for the ``Predict()`` API. A model is queried indirectly via + a ServingConfig, which associates a model with a given Placement + (e.g. Frequently Bought Together on Home Page). + + This service allows you to do the following: + + - Initiate training of a model. + - Pause training of an existing model. + - List all the available models along with their metadata. + - Control their tuning schedule. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "retail.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "retail.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[aio.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # 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 + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def create_model( + self, + ) -> Callable[ + [model_service.CreateModelRequest], Awaitable[operations_pb2.Operation] + ]: + r"""Return a callable for the create model method over gRPC. + + Creates a new model. + + Returns: + Callable[[~.CreateModelRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_model" not in self._stubs: + self._stubs["create_model"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2.ModelService/CreateModel", + request_serializer=model_service.CreateModelRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_model"] + + @property + def get_model( + self, + ) -> Callable[[model_service.GetModelRequest], Awaitable[model.Model]]: + r"""Return a callable for the get model method over gRPC. + + Gets a model. + + Returns: + Callable[[~.GetModelRequest], + Awaitable[~.Model]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_model" not in self._stubs: + self._stubs["get_model"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2.ModelService/GetModel", + request_serializer=model_service.GetModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs["get_model"] + + @property + def pause_model( + self, + ) -> Callable[[model_service.PauseModelRequest], Awaitable[model.Model]]: + r"""Return a callable for the pause model method over gRPC. + + Pauses the training of an existing model. + + Returns: + Callable[[~.PauseModelRequest], + Awaitable[~.Model]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "pause_model" not in self._stubs: + self._stubs["pause_model"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2.ModelService/PauseModel", + request_serializer=model_service.PauseModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs["pause_model"] + + @property + def resume_model( + self, + ) -> Callable[[model_service.ResumeModelRequest], Awaitable[model.Model]]: + r"""Return a callable for the resume model method over gRPC. + + Resumes the training of an existing model. + + Returns: + Callable[[~.ResumeModelRequest], + Awaitable[~.Model]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "resume_model" not in self._stubs: + self._stubs["resume_model"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2.ModelService/ResumeModel", + request_serializer=model_service.ResumeModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs["resume_model"] + + @property + def delete_model( + self, + ) -> Callable[[model_service.DeleteModelRequest], Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete model method over gRPC. + + Deletes an existing model. + + Returns: + Callable[[~.DeleteModelRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_model" not in self._stubs: + self._stubs["delete_model"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2.ModelService/DeleteModel", + request_serializer=model_service.DeleteModelRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_model"] + + @property + def list_models( + self, + ) -> Callable[ + [model_service.ListModelsRequest], Awaitable[model_service.ListModelsResponse] + ]: + r"""Return a callable for the list models method over gRPC. + + Lists all the models linked to this event store. + + Returns: + Callable[[~.ListModelsRequest], + Awaitable[~.ListModelsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_models" not in self._stubs: + self._stubs["list_models"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2.ModelService/ListModels", + request_serializer=model_service.ListModelsRequest.serialize, + response_deserializer=model_service.ListModelsResponse.deserialize, + ) + return self._stubs["list_models"] + + @property + def update_model( + self, + ) -> Callable[[model_service.UpdateModelRequest], Awaitable[gcr_model.Model]]: + r"""Return a callable for the update model method over gRPC. + + Update of model metadata. Only fields that currently can be + updated are: ``filtering_option`` and ``periodic_tuning_state``. + If other values are provided, this API method ignores them. + + Returns: + Callable[[~.UpdateModelRequest], + Awaitable[~.Model]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_model" not in self._stubs: + self._stubs["update_model"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2.ModelService/UpdateModel", + request_serializer=model_service.UpdateModelRequest.serialize, + response_deserializer=gcr_model.Model.deserialize, + ) + return self._stubs["update_model"] + + @property + def tune_model( + self, + ) -> Callable[ + [model_service.TuneModelRequest], Awaitable[operations_pb2.Operation] + ]: + r"""Return a callable for the tune model method over gRPC. + + Tunes an existing model. + + Returns: + Callable[[~.TuneModelRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "tune_model" not in self._stubs: + self._stubs["tune_model"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2.ModelService/TuneModel", + request_serializer=model_service.TuneModelRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["tune_model"] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ("ModelServiceGrpcAsyncIOTransport",) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/transports/rest.py b/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/transports/rest.py new file mode 100644 index 000000000000..0d7d69b50df7 --- /dev/null +++ b/packages/google-cloud-retail/google/cloud/retail_v2/services/model_service/transports/rest.py @@ -0,0 +1,1499 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import dataclasses +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import ( + gapic_v1, + operations_v1, + path_template, + rest_helpers, + rest_streaming, +) +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 +from google.protobuf import json_format +import grpc # type: ignore +from requests import __version__ as requests_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + + +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore + +from google.cloud.retail_v2.types import model +from google.cloud.retail_v2.types import model as gcr_model +from google.cloud.retail_v2.types import model_service + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .base import ModelServiceTransport + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=requests_version, +) + + +class ModelServiceRestInterceptor: + """Interceptor for ModelService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the ModelServiceRestTransport. + + .. code-block:: python + class MyCustomModelServiceInterceptor(ModelServiceRestInterceptor): + def pre_create_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_model(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_get_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_model(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_models(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_models(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_pause_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_pause_model(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_resume_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_resume_model(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_tune_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_tune_model(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_model(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ModelServiceRestTransport(interceptor=MyCustomModelServiceInterceptor()) + client = ModelServiceClient(transport=transport) + + + """ + + def pre_create_model( + self, + request: model_service.CreateModelRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[model_service.CreateModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_create_model( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for create_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + + def pre_delete_model( + self, + request: model_service.DeleteModelRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[model_service.DeleteModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def pre_get_model( + self, + request: model_service.GetModelRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[model_service.GetModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_get_model(self, response: model.Model) -> model.Model: + """Post-rpc interceptor for get_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + + def pre_list_models( + self, + request: model_service.ListModelsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[model_service.ListModelsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_models + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_list_models( + self, response: model_service.ListModelsResponse + ) -> model_service.ListModelsResponse: + """Post-rpc interceptor for list_models + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + + def pre_pause_model( + self, + request: model_service.PauseModelRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[model_service.PauseModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for pause_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_pause_model(self, response: model.Model) -> model.Model: + """Post-rpc interceptor for pause_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + + def pre_resume_model( + self, + request: model_service.ResumeModelRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[model_service.ResumeModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for resume_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_resume_model(self, response: model.Model) -> model.Model: + """Post-rpc interceptor for resume_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + + def pre_tune_model( + self, + request: model_service.TuneModelRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[model_service.TuneModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for tune_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_tune_model( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for tune_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + + def pre_update_model( + self, + request: model_service.UpdateModelRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[model_service.UpdateModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_update_model(self, response: gcr_model.Model) -> gcr_model.Model: + """Post-rpc interceptor for update_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + + def pre_list_operations( + self, + request: operations_pb2.ListOperationsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ModelServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ModelServiceRestInterceptor + + +class ModelServiceRestTransport(ModelServiceTransport): + """REST backend transport for ModelService. + + Service for performing CRUD operations on models. Recommendation + models contain all the metadata necessary to generate a set of + models for the ``Predict()`` API. A model is queried indirectly via + a ServingConfig, which associates a model with a given Placement + (e.g. Frequently Bought Together on Home Page). + + This service allows you to do the following: + + - Initiate training of a model. + - Pause training of an existing model. + - List all the available models along with their metadata. + - Control their tuning schedule. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + + """ + + def __init__( + self, + *, + host: str = "retail.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[ModelServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP 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 are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or ModelServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + @property + def operations_client(self) -> operations_v1.AbstractOperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Only create a new client if we do not already have one. + if self._operations_client is None: + http_options: Dict[str, List[Dict[str, str]]] = { + "google.longrunning.Operations.GetOperation": [ + { + "method": "get", + "uri": "/v2/{name=projects/*/locations/*/operations/*}", + }, + { + "method": "get", + "uri": "/v2/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}", + }, + { + "method": "get", + "uri": "/v2/{name=projects/*/locations/*/catalogs/*/operations/*}", + }, + { + "method": "get", + "uri": "/v2/{name=projects/*/operations/*}", + }, + ], + "google.longrunning.Operations.ListOperations": [ + { + "method": "get", + "uri": "/v2/{name=projects/*/locations/*}/operations", + }, + { + "method": "get", + "uri": "/v2/{name=projects/*/locations/*/catalogs/*}/operations", + }, + { + "method": "get", + "uri": "/v2/{name=projects/*}/operations", + }, + ], + } + + rest_transport = operations_v1.OperationsRestTransport( + host=self._host, + # use the credentials which are saved + credentials=self._credentials, + scopes=self._scopes, + http_options=http_options, + path_prefix="v2", + ) + + self._operations_client = operations_v1.AbstractOperationsClient( + transport=rest_transport + ) + + # Return the client from cache. + return self._operations_client + + class _CreateModel(ModelServiceRestStub): + def __hash__(self): + return hash("CreateModel") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: model_service.CreateModelRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Call the create model method over HTTP. + + Args: + request (~.model_service.CreateModelRequest): + The request object. Request for creating a model. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2/{parent=projects/*/locations/*/catalogs/*}/models", + "body": "model", + }, + ] + request, metadata = self._interceptor.pre_create_model(request, metadata) + pb_request = model_service.CreateModelRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_model(resp) + return resp + + class _DeleteModel(ModelServiceRestStub): + def __hash__(self): + return hash("DeleteModel") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: model_service.DeleteModelRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ): + r"""Call the delete model method over HTTP. + + Args: + request (~.model_service.DeleteModelRequest): + The request object. Request for deleting a model. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v2/{name=projects/*/locations/*/catalogs/*/models/*}", + }, + ] + request, metadata = self._interceptor.pre_delete_model(request, metadata) + pb_request = model_service.DeleteModelRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _GetModel(ModelServiceRestStub): + def __hash__(self): + return hash("GetModel") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: model_service.GetModelRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> model.Model: + r"""Call the get model method over HTTP. + + Args: + request (~.model_service.GetModelRequest): + The request object. Request for getting a model. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.model.Model: + Metadata that describes the training and serving + parameters of a [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be associated + with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{name=projects/*/locations/*/catalogs/*/models/*}", + }, + ] + request, metadata = self._interceptor.pre_get_model(request, metadata) + pb_request = model_service.GetModelRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = model.Model() + pb_resp = model.Model.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_model(resp) + return resp + + class _ListModels(ModelServiceRestStub): + def __hash__(self): + return hash("ListModels") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: model_service.ListModelsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> model_service.ListModelsResponse: + r"""Call the list models method over HTTP. + + Args: + request (~.model_service.ListModelsRequest): + The request object. Request for listing models associated + with a resource. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.model_service.ListModelsResponse: + Response to a ListModelRequest. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{parent=projects/*/locations/*/catalogs/*}/models", + }, + ] + request, metadata = self._interceptor.pre_list_models(request, metadata) + pb_request = model_service.ListModelsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = model_service.ListModelsResponse() + pb_resp = model_service.ListModelsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_models(resp) + return resp + + class _PauseModel(ModelServiceRestStub): + def __hash__(self): + return hash("PauseModel") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: model_service.PauseModelRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> model.Model: + r"""Call the pause model method over HTTP. + + Args: + request (~.model_service.PauseModelRequest): + The request object. Request for pausing training of a + model. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.model.Model: + Metadata that describes the training and serving + parameters of a [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be associated + with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2/{name=projects/*/locations/*/catalogs/*/models/*}:pause", + "body": "*", + }, + ] + request, metadata = self._interceptor.pre_pause_model(request, metadata) + pb_request = model_service.PauseModelRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = model.Model() + pb_resp = model.Model.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_pause_model(resp) + return resp + + class _ResumeModel(ModelServiceRestStub): + def __hash__(self): + return hash("ResumeModel") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: model_service.ResumeModelRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> model.Model: + r"""Call the resume model method over HTTP. + + Args: + request (~.model_service.ResumeModelRequest): + The request object. Request for resuming training of a + model. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.model.Model: + Metadata that describes the training and serving + parameters of a [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be associated + with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2/{name=projects/*/locations/*/catalogs/*/models/*}:resume", + "body": "*", + }, + ] + request, metadata = self._interceptor.pre_resume_model(request, metadata) + pb_request = model_service.ResumeModelRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = model.Model() + pb_resp = model.Model.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_resume_model(resp) + return resp + + class _TuneModel(ModelServiceRestStub): + def __hash__(self): + return hash("TuneModel") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: model_service.TuneModelRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Call the tune model method over HTTP. + + Args: + request (~.model_service.TuneModelRequest): + The request object. Request to manually start a tuning + process now (instead of waiting for the + periodically scheduled tuning to + happen). + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2/{name=projects/*/locations/*/catalogs/*/models/*}:tune", + "body": "*", + }, + ] + request, metadata = self._interceptor.pre_tune_model(request, metadata) + pb_request = model_service.TuneModelRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_tune_model(resp) + return resp + + class _UpdateModel(ModelServiceRestStub): + def __hash__(self): + return hash("UpdateModel") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: model_service.UpdateModelRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_model.Model: + r"""Call the update model method over HTTP. + + Args: + request (~.model_service.UpdateModelRequest): + The request object. Request for updating an existing + model. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.gcr_model.Model: + Metadata that describes the training and serving + parameters of a [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be associated + with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v2/{model.name=projects/*/locations/*/catalogs/*/models/*}", + "body": "model", + }, + ] + request, metadata = self._interceptor.pre_update_model(request, metadata) + pb_request = model_service.UpdateModelRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = gcr_model.Model() + pb_resp = gcr_model.Model.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_model(resp) + return resp + + @property + def create_model( + self, + ) -> Callable[[model_service.CreateModelRequest], operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_model( + self, + ) -> Callable[[model_service.DeleteModelRequest], empty_pb2.Empty]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_model(self) -> Callable[[model_service.GetModelRequest], model.Model]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_models( + self, + ) -> Callable[[model_service.ListModelsRequest], model_service.ListModelsResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListModels(self._session, self._host, self._interceptor) # type: ignore + + @property + def pause_model(self) -> Callable[[model_service.PauseModelRequest], model.Model]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._PauseModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def resume_model(self) -> Callable[[model_service.ResumeModelRequest], model.Model]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ResumeModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def tune_model( + self, + ) -> Callable[[model_service.TuneModelRequest], operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._TuneModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_model( + self, + ) -> Callable[[model_service.UpdateModelRequest], gcr_model.Model]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(ModelServiceRestStub): + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{name=projects/*/locations/*/operations/*}", + }, + { + "method": "get", + "uri": "/v2/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}", + }, + { + "method": "get", + "uri": "/v2/{name=projects/*/locations/*/catalogs/*/operations/*}", + }, + { + "method": "get", + "uri": "/v2/{name=projects/*/operations/*}", + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(ModelServiceRestStub): + def __call__( + self, + request: operations_pb2.ListOperationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + operations_pb2.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{name=projects/*/locations/*}/operations", + }, + { + "method": "get", + "uri": "/v2/{name=projects/*/locations/*/catalogs/*}/operations", + }, + { + "method": "get", + "uri": "/v2/{name=projects/*}/operations", + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("ModelServiceRestTransport",) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/services/product_service/async_client.py b/packages/google-cloud-retail/google/cloud/retail_v2/services/product_service/async_client.py index 571ea3de262d..5463d3031189 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/services/product_service/async_client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/services/product_service/async_client.py @@ -1049,10 +1049,6 @@ async def set_inventory( [done][google.longrunning.Operation.done] until they are obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -1255,7 +1251,15 @@ async def add_fulfillment_places( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, str]] = (), ) -> operation_async.AsyncOperation: - r"""Incrementally adds place IDs to + r"""It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally adds place IDs to [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. This process is asynchronous and does not require the @@ -1279,10 +1283,6 @@ async def add_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -1410,7 +1410,15 @@ async def remove_fulfillment_places( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, str]] = (), ) -> operation_async.AsyncOperation: - r"""Incrementally removes place IDs from a + r"""It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally removes place IDs from a [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. This process is asynchronous and does not require the @@ -1434,10 +1442,6 @@ async def remove_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -1598,10 +1602,6 @@ async def add_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -1759,10 +1759,6 @@ async def remove_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/services/product_service/client.py b/packages/google-cloud-retail/google/cloud/retail_v2/services/product_service/client.py index 9e290f7bd60d..56870cc27609 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/services/product_service/client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/services/product_service/client.py @@ -1295,10 +1295,6 @@ def set_inventory( [done][google.longrunning.Operation.done] until they are obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -1501,7 +1497,15 @@ def add_fulfillment_places( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, str]] = (), ) -> operation.Operation: - r"""Incrementally adds place IDs to + r"""It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally adds place IDs to [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. This process is asynchronous and does not require the @@ -1525,10 +1529,6 @@ def add_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -1656,7 +1656,15 @@ def remove_fulfillment_places( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, str]] = (), ) -> operation.Operation: - r"""Incrementally removes place IDs from a + r"""It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally removes place IDs from a [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. This process is asynchronous and does not require the @@ -1680,10 +1688,6 @@ def remove_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -1846,10 +1850,6 @@ def add_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -2007,10 +2007,6 @@ def remove_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/services/product_service/transports/grpc.py b/packages/google-cloud-retail/google/cloud/retail_v2/services/product_service/transports/grpc.py index f53a0b3cabd4..df06caf73616 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/services/product_service/transports/grpc.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/services/product_service/transports/grpc.py @@ -476,10 +476,6 @@ def set_inventory( [done][google.longrunning.Operation.done] until they are obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.SetInventoryRequest], ~.Operation]: @@ -506,6 +502,14 @@ def add_fulfillment_places( ]: r"""Return a callable for the add fulfillment places method over gRPC. + It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + Incrementally adds place IDs to [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. @@ -530,10 +534,6 @@ def add_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.AddFulfillmentPlacesRequest], ~.Operation]: @@ -560,6 +560,14 @@ def remove_fulfillment_places( ]: r"""Return a callable for the remove fulfillment places method over gRPC. + It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + Incrementally removes place IDs from a [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. @@ -584,10 +592,6 @@ def remove_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.RemoveFulfillmentPlacesRequest], ~.Operation]: @@ -647,10 +651,6 @@ def add_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.AddLocalInventoriesRequest], ~.Operation]: @@ -707,10 +707,6 @@ def remove_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.RemoveLocalInventoriesRequest], ~.Operation]: diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/services/product_service/transports/grpc_asyncio.py b/packages/google-cloud-retail/google/cloud/retail_v2/services/product_service/transports/grpc_asyncio.py index 26243f3f3887..a2d22d94c11b 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/services/product_service/transports/grpc_asyncio.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/services/product_service/transports/grpc_asyncio.py @@ -490,10 +490,6 @@ def set_inventory( [done][google.longrunning.Operation.done] until they are obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.SetInventoryRequest], Awaitable[~.Operation]]: @@ -521,6 +517,14 @@ def add_fulfillment_places( ]: r"""Return a callable for the add fulfillment places method over gRPC. + It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + Incrementally adds place IDs to [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. @@ -545,10 +549,6 @@ def add_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.AddFulfillmentPlacesRequest], Awaitable[~.Operation]]: @@ -576,6 +576,14 @@ def remove_fulfillment_places( ]: r"""Return a callable for the remove fulfillment places method over gRPC. + It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + Incrementally removes place IDs from a [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. @@ -600,10 +608,6 @@ def remove_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.RemoveFulfillmentPlacesRequest], Awaitable[~.Operation]]: @@ -664,10 +668,6 @@ def add_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.AddLocalInventoriesRequest], Awaitable[~.Operation]]: @@ -725,10 +725,6 @@ def remove_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.RemoveLocalInventoriesRequest], Awaitable[~.Operation]]: diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/services/search_service/async_client.py b/packages/google-cloud-retail/google/cloud/retail_v2/services/search_service/async_client.py index 04380ba4a0e0..584aa1b1a03f 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/services/search_service/async_client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/services/search_service/async_client.py @@ -67,8 +67,14 @@ class SearchServiceAsyncClient: branch_path = staticmethod(SearchServiceClient.branch_path) parse_branch_path = staticmethod(SearchServiceClient.parse_branch_path) + experiment_path = staticmethod(SearchServiceClient.experiment_path) + parse_experiment_path = staticmethod(SearchServiceClient.parse_experiment_path) product_path = staticmethod(SearchServiceClient.product_path) parse_product_path = staticmethod(SearchServiceClient.parse_product_path) + serving_config_path = staticmethod(SearchServiceClient.serving_config_path) + parse_serving_config_path = staticmethod( + SearchServiceClient.parse_serving_config_path + ) common_billing_account_path = staticmethod( SearchServiceClient.common_billing_account_path ) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/services/search_service/client.py b/packages/google-cloud-retail/google/cloud/retail_v2/services/search_service/client.py index 1cb155416e07..cbf53eb05ae4 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/services/search_service/client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/services/search_service/client.py @@ -206,6 +206,30 @@ def parse_branch_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def experiment_path( + project: str, + location: str, + catalog: str, + experiment: str, + ) -> str: + """Returns a fully-qualified experiment string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/experiments/{experiment}".format( + project=project, + location=location, + catalog=catalog, + experiment=experiment, + ) + + @staticmethod + def parse_experiment_path(path: str) -> Dict[str, str]: + """Parses a experiment path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/experiments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def product_path( project: str, @@ -232,6 +256,30 @@ def parse_product_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def serving_config_path( + project: str, + location: str, + catalog: str, + serving_config: str, + ) -> str: + """Returns a fully-qualified serving_config string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/servingConfigs/{serving_config}".format( + project=project, + location=location, + catalog=catalog, + serving_config=serving_config, + ) + + @staticmethod + def parse_serving_config_path(path: str) -> Dict[str, str]: + """Parses a serving_config path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/servingConfigs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def common_billing_account_path( billing_account: str, diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/types/__init__.py b/packages/google-cloud-retail/google/cloud/retail_v2/types/__init__.py index 814f058c5a5c..61e581137ec5 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/types/__init__.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/types/__init__.py @@ -47,6 +47,7 @@ LocalInventory, PriceInfo, Rating, + RecommendationsFilteringOption, Rule, SearchSolutionUseCase, SolutionType, @@ -80,6 +81,21 @@ UserEventInlineSource, UserEventInputConfig, ) +from .model import Model +from .model_service import ( + CreateModelMetadata, + CreateModelRequest, + DeleteModelRequest, + GetModelRequest, + ListModelsRequest, + ListModelsResponse, + PauseModelRequest, + ResumeModelRequest, + TuneModelMetadata, + TuneModelRequest, + TuneModelResponse, + UpdateModelRequest, +) from .prediction_service import PredictRequest, PredictResponse from .product import Product from .product_service import ( @@ -107,7 +123,7 @@ ) from .promotion import Promotion from .purge_config import PurgeMetadata, PurgeUserEventsRequest, PurgeUserEventsResponse -from .search_service import SearchRequest, SearchResponse +from .search_service import ExperimentInfo, SearchRequest, SearchResponse from .serving_config import ServingConfig from .serving_config_service import ( AddControlRequest, @@ -160,6 +176,7 @@ "Rule", "UserInfo", "AttributeConfigLevel", + "RecommendationsFilteringOption", "SearchSolutionUseCase", "SolutionType", "CompleteQueryRequest", @@ -187,6 +204,19 @@ "UserEventImportSummary", "UserEventInlineSource", "UserEventInputConfig", + "Model", + "CreateModelMetadata", + "CreateModelRequest", + "DeleteModelRequest", + "GetModelRequest", + "ListModelsRequest", + "ListModelsResponse", + "PauseModelRequest", + "ResumeModelRequest", + "TuneModelMetadata", + "TuneModelRequest", + "TuneModelResponse", + "UpdateModelRequest", "PredictRequest", "PredictResponse", "Product", @@ -215,6 +245,7 @@ "PurgeMetadata", "PurgeUserEventsRequest", "PurgeUserEventsResponse", + "ExperimentInfo", "SearchRequest", "SearchResponse", "ServingConfig", diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/types/catalog.py b/packages/google-cloud-retail/google/cloud/retail_v2/types/catalog.py index 72da2883c912..077b4f611cf5 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/types/catalog.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/types/catalog.py @@ -118,6 +118,11 @@ class CatalogAttribute(proto.Message): example, an attribute named ``attributes.abc_xyz`` can be indexed, but an attribute named ``attributes.abc-xyz`` cannot be indexed. + + If the attribute key starts with ``attributes.``, then the + attribute is a custom attribute. Attributes such as + ``brands``, ``patterns``, and ``title`` are built-in and + called system attributes. in_use (bool): Output only. Indicates whether this attribute has been used by any products. ``True`` if at least one @@ -185,10 +190,13 @@ class CatalogAttribute(proto.Message): If EXACT_SEARCHABLE_ENABLED, attribute values will be exact searchable. This property only applies to textual custom attributes and requires indexable set to enabled to enable - exact-searchable. + exact-searchable. If unset, the server behavior defaults to + [EXACT_SEARCHABLE_DISABLED][google.cloud.retail.v2.CatalogAttribute.ExactSearchableOption.EXACT_SEARCHABLE_DISABLED]. retrievable_option (google.cloud.retail_v2.types.CatalogAttribute.RetrievableOption): If RETRIEVABLE_ENABLED, attribute values are retrievable in - the search results. + the search results. If unset, the server behavior defaults + to + [RETRIEVABLE_DISABLED][google.cloud.retail.v2.CatalogAttribute.RetrievableOption.RETRIEVABLE_DISABLED]. """ class AttributeType(proto.Enum): @@ -263,8 +271,7 @@ class ExactSearchableOption(proto.Enum): Values: EXACT_SEARCHABLE_OPTION_UNSPECIFIED (0): - Value used when unset. Defaults to - [EXACT_SEARCHABLE_DISABLED][google.cloud.retail.v2.CatalogAttribute.ExactSearchableOption.EXACT_SEARCHABLE_DISABLED]. + Value used when unset. EXACT_SEARCHABLE_ENABLED (1): Exact searchable option enabled for an attribute. @@ -281,8 +288,7 @@ class RetrievableOption(proto.Enum): Values: RETRIEVABLE_OPTION_UNSPECIFIED (0): - Value used when unset. Defaults to - [RETRIEVABLE_DISABLED][google.cloud.retail.v2.CatalogAttribute.RetrievableOption.RETRIEVABLE_DISABLED]. + Value used when unset. RETRIEVABLE_ENABLED (1): Retrievable option enabled for an attribute. RETRIEVABLE_DISABLED (2): diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/types/common.py b/packages/google-cloud-retail/google/cloud/retail_v2/types/common.py index be34cf860ad4..da1419798937 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/types/common.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/types/common.py @@ -25,6 +25,7 @@ manifest={ "AttributeConfigLevel", "SolutionType", + "RecommendationsFilteringOption", "SearchSolutionUseCase", "Condition", "Rule", @@ -78,6 +79,24 @@ class SolutionType(proto.Enum): SOLUTION_TYPE_SEARCH = 2 +class RecommendationsFilteringOption(proto.Enum): + r"""If filtering for recommendations is enabled. + + Values: + RECOMMENDATIONS_FILTERING_OPTION_UNSPECIFIED (0): + Value used when unset. In this case, server behavior + defaults to + [RECOMMENDATIONS_FILTERING_DISABLED][google.cloud.retail.v2.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED]. + RECOMMENDATIONS_FILTERING_DISABLED (1): + Recommendation filtering is disabled. + RECOMMENDATIONS_FILTERING_ENABLED (3): + Recommendation filtering is enabled. + """ + RECOMMENDATIONS_FILTERING_OPTION_UNSPECIFIED = 0 + RECOMMENDATIONS_FILTERING_DISABLED = 1 + RECOMMENDATIONS_FILTERING_ENABLED = 3 + + class SearchSolutionUseCase(proto.Enum): r"""The use case of Cloud Retail Search. @@ -603,7 +622,7 @@ class ColorInfo(proto.Message): only 1 color. May consider using single "Mixed" instead of multiple values. - A maximum of 25 colors are allowed. Each value must be a + A maximum of 75 colors are allowed. Each value must be a UTF-8 encoded string with a length limit of 128 characters. Otherwise, an INVALID_ARGUMENT error is returned. diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/types/completion_service.py b/packages/google-cloud-retail/google/cloud/retail_v2/types/completion_service.py index 93a73af4fc5f..827aeede604f 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/types/completion_service.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/types/completion_service.py @@ -31,7 +31,7 @@ class CompleteQueryRequest(proto.Message): - r"""Auto-complete parameters. + r"""Autocomplete parameters. Attributes: catalog (str): @@ -106,6 +106,14 @@ class CompleteQueryRequest(proto.Message): The maximum allowed max suggestions is 20. If it is set higher, it will be capped by 20. + entity (str): + The entity for customers that may run multiple different + entities, domains, sites or regions, for example, + ``Google US``, ``Google Ads``, ``Waymo``, ``google.com``, + ``youtube.com``, etc. If this is set, it should be exactly + matched with + [UserEvent.entity][google.cloud.retail.v2.UserEvent.entity] + to get per-entity autocomplete results. """ catalog: str = proto.Field( @@ -136,10 +144,14 @@ class CompleteQueryRequest(proto.Message): proto.INT32, number=5, ) + entity: str = proto.Field( + proto.STRING, + number=10, + ) class CompleteQueryResponse(proto.Message): - r"""Response of the auto-complete query. + r"""Response of the autocomplete query. Attributes: completion_results (MutableSequence[google.cloud.retail_v2.types.CompleteQueryResponse.CompletionResult]): diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/types/import_config.py b/packages/google-cloud-retail/google/cloud/retail_v2/types/import_config.py index 7e5ea28b72ee..707cda6b00a5 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/types/import_config.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/types/import_config.py @@ -158,7 +158,7 @@ class BigQuerySource(proto.Message): - ``user_event_ga4``: The schema is available here: https://support.google.com/analytics/answer/7029846. - Supported values for auto-completion imports: + Supported values for autocomplete imports: - ``suggestions`` (default): One JSON completion suggestion per line. diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/types/model.py b/packages/google-cloud-retail/google/cloud/retail_v2/types/model.py new file mode 100644 index 000000000000..41889a8c6793 --- /dev/null +++ b/packages/google-cloud-retail/google/cloud/retail_v2/types/model.py @@ -0,0 +1,319 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import timestamp_pb2 # type: ignore +import proto # type: ignore + +from google.cloud.retail_v2.types import common + +__protobuf__ = proto.module( + package="google.cloud.retail.v2", + manifest={ + "Model", + }, +) + + +class Model(proto.Message): + r"""Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] and then + queried through the Predict API. + + Attributes: + name (str): + Required. The fully qualified resource name of the model. + + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + catalog_id has char limit of 50. recommendation_model_id has + char limit of 40. + display_name (str): + Required. The display name of the model. + Should be human readable, used to display + Recommendation Models in the Retail Cloud + Console Dashboard. UTF-8 encoded string with + limit of 1024 characters. + training_state (google.cloud.retail_v2.types.Model.TrainingState): + Optional. The training state that the model is in (e.g. + ``TRAINING`` or ``PAUSED``). + + Since part of the cost of running the service is frequency + of training - this can be used to determine when to train + model in order to control cost. If not specified: the + default value for ``CreateModel`` method is ``TRAINING``. + The default value for ``UpdateModel`` method is to keep the + state the same as before. + serving_state (google.cloud.retail_v2.types.Model.ServingState): + Output only. The serving state of the model: ``ACTIVE``, + ``NOT_ACTIVE``. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Timestamp the Recommendation + Model was created at. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Timestamp the Recommendation + Model was last updated. E.g. if a Recommendation + Model was paused - this would be the time the + pause was initiated. + type_ (str): + Required. The type of model e.g. ``home-page``. + + Currently supported values: ``recommended-for-you``, + ``others-you-may-like``, ``frequently-bought-together``, + ``page-optimization``, ``similar-items``, ``buy-it-again``, + ``on-sale-items``, and ``recently-viewed``\ (readonly + value). + + This field together with + [optimization_objective][google.cloud.retail.v2.Model.optimization_objective] + describe model metadata to use to control model training and + serving. See https://cloud.google.com/retail/docs/models for + more details on what the model metadata control and which + combination of parameters are valid. For invalid + combinations of parameters (e.g. type = + ``frequently-bought-together`` and optimization_objective = + ``ctr``), you receive an error 400 if you try to + create/update a recommendation with this set of knobs. + optimization_objective (str): + Optional. The optimization objective e.g. ``cvr``. + + Currently supported values: ``ctr``, ``cvr``, + ``revenue-per-order``. + + If not specified, we choose default based on model type. + Default depends on type of recommendation: + + ``recommended-for-you`` => ``ctr`` + + ``others-you-may-like`` => ``ctr`` + + ``frequently-bought-together`` => ``revenue_per_order`` + + This field together with + [optimization_objective][google.cloud.retail.v2.Model.type] + describe model metadata to use to control model training and + serving. See https://cloud.google.com/retail/docs/models for + more details on what the model metadata control and which + combination of parameters are valid. For invalid + combinations of parameters (e.g. type = + ``frequently-bought-together`` and optimization_objective = + ``ctr``), you receive an error 400 if you try to + create/update a recommendation with this set of knobs. + periodic_tuning_state (google.cloud.retail_v2.types.Model.PeriodicTuningState): + Optional. The state of periodic tuning. + + The period we use is 3 months - to do a one-off tune earlier + use the ``TuneModel`` method. Default value is + ``PERIODIC_TUNING_ENABLED``. + last_tune_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The timestamp when the latest + successful tune finished. + tuning_operation (str): + Output only. The tune operation associated + with the model. + Can be used to determine if there is an ongoing + tune for this recommendation. Empty field + implies no tune is goig on. + data_state (google.cloud.retail_v2.types.Model.DataState): + Output only. The state of data requirements for this model: + ``DATA_OK`` and ``DATA_ERROR``. + + Recommendation model cannot be trained if the data is in + ``DATA_ERROR`` state. Recommendation model can have + ``DATA_ERROR`` state even if serving state is ``ACTIVE``: + models were trained successfully before, but cannot be + refreshed because model no longer has sufficient data for + training. + filtering_option (google.cloud.retail_v2.types.RecommendationsFilteringOption): + Optional. If ``RECOMMENDATIONS_FILTERING_ENABLED``, + recommendation filtering by attributes is enabled for the + model. + serving_config_lists (MutableSequence[google.cloud.retail_v2.types.Model.ServingConfigList]): + Output only. The list of valid serving + configs associated with the + PageOptimizationConfig. + """ + + class ServingState(proto.Enum): + r"""The serving state of the model. + + Values: + SERVING_STATE_UNSPECIFIED (0): + Unspecified serving state. + INACTIVE (1): + The model is not serving. + ACTIVE (2): + The model is serving and can be queried. + TUNED (3): + The model is trained on tuned hyperparameters + and can be queried. + """ + SERVING_STATE_UNSPECIFIED = 0 + INACTIVE = 1 + ACTIVE = 2 + TUNED = 3 + + class TrainingState(proto.Enum): + r"""The training state of the model. + + Values: + TRAINING_STATE_UNSPECIFIED (0): + Unspecified training state. + PAUSED (1): + The model training is paused. + TRAINING (2): + The model is training. + """ + TRAINING_STATE_UNSPECIFIED = 0 + PAUSED = 1 + TRAINING = 2 + + class PeriodicTuningState(proto.Enum): + r"""Describes whether periodic tuning is enabled for this model or not. + Periodic tuning is scheduled at most every three months. You can + start a tuning process manually by using the ``TuneModel`` method, + which starts a tuning process immediately and resets the quarterly + schedule. Enabling or disabling periodic tuning does not affect any + current tuning processes. + + Values: + PERIODIC_TUNING_STATE_UNSPECIFIED (0): + Unspecified default value, should never be + explicitly set. + PERIODIC_TUNING_DISABLED (1): + The model has periodic tuning disabled. Tuning can be + reenabled by calling the ``EnableModelPeriodicTuning`` + method or by calling the ``TuneModel`` method. + ALL_TUNING_DISABLED (3): + The model cannot be tuned with periodic tuning OR the + ``TuneModel`` method. Hide the options in customer UI and + reject any requests through the backend self serve API. + PERIODIC_TUNING_ENABLED (2): + The model has periodic tuning enabled. Tuning can be + disabled by calling the ``DisableModelPeriodicTuning`` + method. + """ + PERIODIC_TUNING_STATE_UNSPECIFIED = 0 + PERIODIC_TUNING_DISABLED = 1 + ALL_TUNING_DISABLED = 3 + PERIODIC_TUNING_ENABLED = 2 + + class DataState(proto.Enum): + r"""Describes whether this model have sufficient training data + to be continuously trained. + + Values: + DATA_STATE_UNSPECIFIED (0): + Unspecified default value, should never be + explicitly set. + DATA_OK (1): + The model has sufficient training data. + DATA_ERROR (2): + The model does not have sufficient training + data. Error messages can be queried via + Stackdriver. + """ + DATA_STATE_UNSPECIFIED = 0 + DATA_OK = 1 + DATA_ERROR = 2 + + class ServingConfigList(proto.Message): + r"""Represents an ordered combination of valid serving configs, which + can be used for ``PAGE_OPTIMIZATION`` recommendations. + + Attributes: + serving_config_ids (MutableSequence[str]): + Optional. A set of valid serving configs that may be used + for ``PAGE_OPTIMIZATION``. + """ + + serving_config_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + training_state: TrainingState = proto.Field( + proto.ENUM, + number=3, + enum=TrainingState, + ) + serving_state: ServingState = proto.Field( + proto.ENUM, + number=4, + enum=ServingState, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + type_: str = proto.Field( + proto.STRING, + number=7, + ) + optimization_objective: str = proto.Field( + proto.STRING, + number=8, + ) + periodic_tuning_state: PeriodicTuningState = proto.Field( + proto.ENUM, + number=11, + enum=PeriodicTuningState, + ) + last_tune_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=12, + message=timestamp_pb2.Timestamp, + ) + tuning_operation: str = proto.Field( + proto.STRING, + number=15, + ) + data_state: DataState = proto.Field( + proto.ENUM, + number=16, + enum=DataState, + ) + filtering_option: common.RecommendationsFilteringOption = proto.Field( + proto.ENUM, + number=18, + enum=common.RecommendationsFilteringOption, + ) + serving_config_lists: MutableSequence[ServingConfigList] = proto.RepeatedField( + proto.MESSAGE, + number=19, + message=ServingConfigList, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/types/model_service.py b/packages/google-cloud-retail/google/cloud/retail_v2/types/model_service.py new file mode 100644 index 000000000000..3bf132b16de0 --- /dev/null +++ b/packages/google-cloud-retail/google/cloud/retail_v2/types/model_service.py @@ -0,0 +1,272 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import field_mask_pb2 # type: ignore +import proto # type: ignore + +from google.cloud.retail_v2.types import model as gcr_model + +__protobuf__ = proto.module( + package="google.cloud.retail.v2", + manifest={ + "CreateModelRequest", + "UpdateModelRequest", + "GetModelRequest", + "PauseModelRequest", + "ResumeModelRequest", + "ListModelsRequest", + "DeleteModelRequest", + "ListModelsResponse", + "TuneModelRequest", + "CreateModelMetadata", + "TuneModelMetadata", + "TuneModelResponse", + }, +) + + +class CreateModelRequest(proto.Message): + r"""Request for creating a model. + + Attributes: + parent (str): + Required. The parent resource under which to create the + model. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + model (google.cloud.retail_v2.types.Model): + Required. The payload of the + [Model][google.cloud.retail.v2.Model] to create. + dry_run (bool): + Optional. Whether to run a dry run to + validate the request (without actually creating + the model). + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + model: gcr_model.Model = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_model.Model, + ) + dry_run: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class UpdateModelRequest(proto.Message): + r"""Request for updating an existing model. + + Attributes: + model (google.cloud.retail_v2.types.Model): + Required. The body of the updated + [Model][google.cloud.retail.v2.Model]. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. Indicates which fields in the + provided 'model' to update. If not set, by + default updates all fields. + """ + + model: gcr_model.Model = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_model.Model, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class GetModelRequest(proto.Message): + r"""Request for getting a model. + + Attributes: + name (str): + Required. The resource name of the + [Model][google.cloud.retail.v2.Model] to get. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class PauseModelRequest(proto.Message): + r"""Request for pausing training of a model. + + Attributes: + name (str): + Required. The name of the model to pause. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ResumeModelRequest(proto.Message): + r"""Request for resuming training of a model. + + Attributes: + name (str): + Required. The name of the model to resume. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListModelsRequest(proto.Message): + r"""Request for listing models associated with a resource. + + Attributes: + parent (str): + Required. The parent for which to list models. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + page_size (int): + Optional. Maximum number of results to + return. If unspecified, defaults to 50. Max + allowed value is 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListModels`` call. Provide this to retrieve the subsequent + page. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class DeleteModelRequest(proto.Message): + r"""Request for deleting a model. + + Attributes: + name (str): + Required. The resource name of the + [Model][google.cloud.retail.v2.Model] to delete. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListModelsResponse(proto.Message): + r"""Response to a ListModelRequest. + + Attributes: + models (MutableSequence[google.cloud.retail_v2.types.Model]): + List of Models. + next_page_token (str): + Pagination token, if not returned indicates + the last page. + """ + + @property + def raw_page(self): + return self + + models: MutableSequence[gcr_model.Model] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcr_model.Model, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class TuneModelRequest(proto.Message): + r"""Request to manually start a tuning process now (instead of + waiting for the periodically scheduled tuning to happen). + + Attributes: + name (str): + Required. The resource name of the model to tune. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class CreateModelMetadata(proto.Message): + r"""Metadata associated with a create operation. + + Attributes: + model (str): + The resource name of the model that this create applies to. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + model: str = proto.Field( + proto.STRING, + number=1, + ) + + +class TuneModelMetadata(proto.Message): + r"""Metadata associated with a tune operation. + + Attributes: + model (str): + The resource name of the model that this tune applies to. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + model: str = proto.Field( + proto.STRING, + number=1, + ) + + +class TuneModelResponse(proto.Message): + r"""Response associated with a tune operation.""" + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/types/prediction_service.py b/packages/google-cloud-retail/google/cloud/retail_v2/types/prediction_service.py index 8193e130fe4a..ddd71a617c6f 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/types/prediction_service.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/types/prediction_service.py @@ -119,6 +119,9 @@ class PredictRequest(proto.Message): ANY("Phones")) - (availability: ANY("IN_STOCK")) AND (colors: ANY("Red") OR categories: ANY("Phones")) + + For more information, see `Filter + recommendations `__. validate_only (bool): Use validate only mode for this prediction query. If set to true, a dummy model will be diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/types/product.py b/packages/google-cloud-retail/google/cloud/retail_v2/types/product.py index 132e93716389..94164ec3372e 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/types/product.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/types/product.py @@ -559,12 +559,11 @@ class Product(proto.Message): Output only. A list of local inventories specific to different places. - This is only available for users who have Retail Search - enabled, and it can be managed by + This field can be managed by [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] and [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] - APIs. + APIs if fine-grained, high-volume updates are necessary. """ class Type(proto.Enum): diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/types/search_service.py b/packages/google-cloud-retail/google/cloud/retail_v2/types/search_service.py index 6dc1eeb4917b..6bc457b64002 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/types/search_service.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/types/search_service.py @@ -29,6 +29,7 @@ manifest={ "SearchRequest", "SearchResponse", + "ExperimentInfo", }, ) @@ -145,7 +146,7 @@ class SearchRequest(proto.Message): Facet specifications for faceted search. If empty, no facets are returned. - A maximum of 100 values are allowed. Otherwise, an + A maximum of 200 values are allowed. Otherwise, an INVALID_ARGUMENT error is returned. dynamic_facet_spec (google.cloud.retail_v2.types.SearchRequest.DynamicFacetSpec): Deprecated. Refer to @@ -313,6 +314,14 @@ class SearchRequest(proto.Message): will take effect. This field is a member of `oneof`_ ``_spell_correction_spec``. + entity (str): + The entity for customers that may run multiple different + entities, domains, sites or regions, for example, + ``Google US``, ``Google Ads``, ``Waymo``, ``google.com``, + ``youtube.com``, etc. If this is set, it should be exactly + matched with + [UserEvent.entity][google.cloud.retail.v2.UserEvent.entity] + to get search results boosted by entity. """ class SearchMode(proto.Enum): @@ -491,7 +500,19 @@ class FacetKey(proto.Message): Set only if values should be bucketized into intervals. Must be set for facets with numerical values. Must not be set for facet with text - values. Maximum number of intervals is 30. + values. Maximum number of intervals is 40. + + For all numerical facet keys that appear in the + list of products from the catalog, the + percentiles 0, 10, 30, 50, 70, 90 and 100 are + computed from their distribution weekly. If the + model assigns a high score to a numerical facet + key and its intervals are not specified in the + search request, these percentiles will become + the bounds for its intervals and will be + returned in the response. If the facet key + intervals are specified in the request, then the + specified intervals will be returned instead. restricted_values (MutableSequence[str]): Only get facet for the given restricted values. For example, when using "pickupInStore" as key and set restricted values @@ -978,6 +999,10 @@ class Mode(proto.Enum): optional=True, message=SpellCorrectionSpec, ) + entity: str = proto.Field( + proto.STRING, + number=38, + ) class SearchResponse(proto.Message): @@ -1030,6 +1055,10 @@ class SearchResponse(proto.Message): The invalid [SearchRequest.BoostSpec.condition_boost_specs][google.cloud.retail.v2.SearchRequest.BoostSpec.condition_boost_specs] that are not applied during serving. + experiment_info (MutableSequence[google.cloud.retail_v2.types.ExperimentInfo]): + Metadata related to A/B testing [Experiment][] associated + with this response. Only exists when an experiment is + triggered. """ class SearchResult(proto.Message): @@ -1326,6 +1355,67 @@ def raw_page(self): number=14, message="SearchRequest.BoostSpec.ConditionBoostSpec", ) + experiment_info: MutableSequence["ExperimentInfo"] = proto.RepeatedField( + proto.MESSAGE, + number=17, + message="ExperimentInfo", + ) + + +class ExperimentInfo(proto.Message): + r"""Metadata for active A/B testing [Experiments][]. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + serving_config_experiment (google.cloud.retail_v2.types.ExperimentInfo.ServingConfigExperiment): + A/B test between existing Cloud Retail Search + [ServingConfig][google.cloud.retail.v2.ServingConfig]s. + + This field is a member of `oneof`_ ``experiment_metadata``. + experiment (str): + The fully qualified resource name of the experiment that + provides the serving config under test, should an active + experiment exist. For example: + ``projects/*/locations/global/catalogs/default_catalog/experiments/experiment_id`` + """ + + class ServingConfigExperiment(proto.Message): + r"""Metadata for active serving config A/B tests. + + Attributes: + original_serving_config (str): + The fully qualified resource name of the original + [SearchRequest.placement][google.cloud.retail.v2.SearchRequest.placement] + in the search request prior to reassignment by experiment + API. For example: + ``projects/*/locations/*/catalogs/*/servingConfigs/*``. + experiment_serving_config (str): + The fully qualified resource name of the serving config + [VariantArm.serving_config_id][] responsible for generating + the search response. For example: + ``projects/*/locations/*/catalogs/*/servingConfigs/*``. + """ + + original_serving_config: str = proto.Field( + proto.STRING, + number=1, + ) + experiment_serving_config: str = proto.Field( + proto.STRING, + number=2, + ) + + serving_config_experiment: ServingConfigExperiment = proto.Field( + proto.MESSAGE, + number=2, + oneof="experiment_metadata", + message=ServingConfigExperiment, + ) + experiment: str = proto.Field( + proto.STRING, + number=1, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/types/serving_config.py b/packages/google-cloud-retail/google/cloud/retail_v2/types/serving_config.py index 25f215b56337..7279ff5ab267 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/types/serving_config.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/types/serving_config.py @@ -64,7 +64,7 @@ class ServingConfig(proto.Message): click-through and conversion rates. Allowed values are: - ``no-price-reranking`` - - ``low-price-raranking`` + - ``low-price-reranking`` - ``medium-price-reranking`` - ``high-price-reranking`` diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/types/user_event.py b/packages/google-cloud-retail/google/cloud/retail_v2/types/user_event.py index e7022ebde44f..7e1a5f0c6df0 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/types/user_event.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/types/user_event.py @@ -290,6 +290,13 @@ class UserEvent(proto.Message): When using the client side event reporting with JavaScript pixel and Google Tag Manager, this value is filled in automatically. + entity (str): + The entity for customers that may run multiple different + entities, domains, sites or regions, for example, + ``Google US``, ``Google Ads``, ``Waymo``, ``google.com``, + ``youtube.com``, etc. It is recommended to set this field to + get better per-entity search, completion and prediction + results. """ event_type: str = proto.Field( @@ -379,6 +386,10 @@ class UserEvent(proto.Message): proto.STRING, number=15, ) + entity: str = proto.Field( + proto.STRING, + number=23, + ) class ProductDetail(proto.Message): diff --git a/packages/google-cloud-retail/google/cloud/retail_v2/types/user_event_service.py b/packages/google-cloud-retail/google/cloud/retail_v2/types/user_event_service.py index d79032987bb9..97093f4785d9 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2/types/user_event_service.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2/types/user_event_service.py @@ -74,7 +74,8 @@ class CollectUserEventRequest(proto.Message): Attributes: prebuilt_rule (str): The prebuilt rule name that can convert a specific type of - raw_json. For example: "default_schema/v1.0". + raw_json. For example: "ga4_bq" rule for the GA4 user event + schema. This field is a member of `oneof`_ ``conversion_rule``. parent (str): diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/__init__.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/__init__.py index 9e2c9bed6cdd..e8882b95a448 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/__init__.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/__init__.py @@ -24,6 +24,10 @@ CompletionServiceClient, ) from .services.control_service import ControlServiceAsyncClient, ControlServiceClient +from .services.merchant_center_account_link_service import ( + MerchantCenterAccountLinkServiceAsyncClient, + MerchantCenterAccountLinkServiceClient, +) from .services.model_service import ModelServiceAsyncClient, ModelServiceClient from .services.prediction_service import ( PredictionServiceAsyncClient, @@ -122,11 +126,22 @@ UserEventInlineSource, UserEventInputConfig, ) +from .types.merchant_center_account_link import ( + CreateMerchantCenterAccountLinkMetadata, + MerchantCenterAccountLink, +) +from .types.merchant_center_account_link_service import ( + CreateMerchantCenterAccountLinkRequest, + DeleteMerchantCenterAccountLinkRequest, + ListMerchantCenterAccountLinksRequest, + ListMerchantCenterAccountLinksResponse, +) from .types.model import Model from .types.model_service import ( CreateModelMetadata, CreateModelRequest, DeleteModelRequest, + GetModelRequest, ListModelsRequest, ListModelsResponse, PauseModelRequest, @@ -170,7 +185,7 @@ PurgeUserEventsRequest, PurgeUserEventsResponse, ) -from .types.search_service import SearchRequest, SearchResponse +from .types.search_service import ExperimentInfo, SearchRequest, SearchResponse from .types.serving_config import ServingConfig from .types.serving_config_service import ( AddControlRequest, @@ -200,6 +215,7 @@ "CatalogServiceAsyncClient", "CompletionServiceAsyncClient", "ControlServiceAsyncClient", + "MerchantCenterAccountLinkServiceAsyncClient", "ModelServiceAsyncClient", "PredictionServiceAsyncClient", "ProductServiceAsyncClient", @@ -236,15 +252,19 @@ "Control", "ControlServiceClient", "CreateControlRequest", + "CreateMerchantCenterAccountLinkMetadata", + "CreateMerchantCenterAccountLinkRequest", "CreateModelMetadata", "CreateModelRequest", "CreateProductRequest", "CreateServingConfigRequest", "CustomAttribute", "DeleteControlRequest", + "DeleteMerchantCenterAccountLinkRequest", "DeleteModelRequest", "DeleteProductRequest", "DeleteServingConfigRequest", + "ExperimentInfo", "ExportErrorsConfig", "ExportMetadata", "ExportProductsResponse", @@ -257,6 +277,7 @@ "GetControlRequest", "GetDefaultBranchRequest", "GetDefaultBranchResponse", + "GetModelRequest", "GetProductRequest", "GetServingConfigRequest", "Image", @@ -273,6 +294,8 @@ "ListCatalogsResponse", "ListControlsRequest", "ListControlsResponse", + "ListMerchantCenterAccountLinksRequest", + "ListMerchantCenterAccountLinksResponse", "ListModelsRequest", "ListModelsResponse", "ListProductsRequest", @@ -280,6 +303,8 @@ "ListServingConfigsRequest", "ListServingConfigsResponse", "LocalInventory", + "MerchantCenterAccountLink", + "MerchantCenterAccountLinkServiceClient", "MerchantCenterFeedFilter", "MerchantCenterLink", "MerchantCenterLinkingConfig", diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/gapic_metadata.json b/packages/google-cloud-retail/google/cloud/retail_v2alpha/gapic_metadata.json index a7d747d31f2f..05416941fc23 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/gapic_metadata.json +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/gapic_metadata.json @@ -347,6 +347,70 @@ } } }, + "MerchantCenterAccountLinkService": { + "clients": { + "grpc": { + "libraryClient": "MerchantCenterAccountLinkServiceClient", + "rpcs": { + "CreateMerchantCenterAccountLink": { + "methods": [ + "create_merchant_center_account_link" + ] + }, + "DeleteMerchantCenterAccountLink": { + "methods": [ + "delete_merchant_center_account_link" + ] + }, + "ListMerchantCenterAccountLinks": { + "methods": [ + "list_merchant_center_account_links" + ] + } + } + }, + "grpc-async": { + "libraryClient": "MerchantCenterAccountLinkServiceAsyncClient", + "rpcs": { + "CreateMerchantCenterAccountLink": { + "methods": [ + "create_merchant_center_account_link" + ] + }, + "DeleteMerchantCenterAccountLink": { + "methods": [ + "delete_merchant_center_account_link" + ] + }, + "ListMerchantCenterAccountLinks": { + "methods": [ + "list_merchant_center_account_links" + ] + } + } + }, + "rest": { + "libraryClient": "MerchantCenterAccountLinkServiceClient", + "rpcs": { + "CreateMerchantCenterAccountLink": { + "methods": [ + "create_merchant_center_account_link" + ] + }, + "DeleteMerchantCenterAccountLink": { + "methods": [ + "delete_merchant_center_account_link" + ] + }, + "ListMerchantCenterAccountLinks": { + "methods": [ + "list_merchant_center_account_links" + ] + } + } + } + } + }, "ModelService": { "clients": { "grpc": { @@ -362,6 +426,11 @@ "delete_model" ] }, + "GetModel": { + "methods": [ + "get_model" + ] + }, "ListModels": { "methods": [ "list_models" @@ -402,6 +471,11 @@ "delete_model" ] }, + "GetModel": { + "methods": [ + "get_model" + ] + }, "ListModels": { "methods": [ "list_models" @@ -442,6 +516,11 @@ "delete_model" ] }, + "GetModel": { + "methods": [ + "get_model" + ] + }, "ListModels": { "methods": [ "list_models" diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/completion_service/async_client.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/completion_service/async_client.py index 4700c16299e0..262042786292 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/completion_service/async_client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/completion_service/async_client.py @@ -55,7 +55,7 @@ class CompletionServiceAsyncClient: - """Auto-completion service for retail. + """Autocomplete service for retail. This feature is only available for users who have Retail Search enabled. Enable Retail Search on Cloud Console before using this feature. @@ -265,7 +265,7 @@ async def sample_complete_query(): Args: request (Optional[Union[google.cloud.retail_v2alpha.types.CompleteQueryRequest, dict]]): - The request object. Auto-complete parameters. + The request object. Autocomplete parameters. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -274,7 +274,7 @@ async def sample_complete_query(): Returns: google.cloud.retail_v2alpha.types.CompleteQueryResponse: - Response of the auto-complete query. + Response of the autocomplete query. """ # Create or coerce a protobuf request object. request = completion_service.CompleteQueryRequest(request) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/completion_service/client.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/completion_service/client.py index 6c3e470d97e5..3237c26654f5 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/completion_service/client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/completion_service/client.py @@ -97,7 +97,7 @@ def get_transport_class( class CompletionServiceClient(metaclass=CompletionServiceClientMeta): - """Auto-completion service for retail. + """Autocomplete service for retail. This feature is only available for users who have Retail Search enabled. Enable Retail Search on Cloud Console before using this feature. @@ -494,7 +494,7 @@ def sample_complete_query(): Args: request (Union[google.cloud.retail_v2alpha.types.CompleteQueryRequest, dict]): - The request object. Auto-complete parameters. + The request object. Autocomplete parameters. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -503,7 +503,7 @@ def sample_complete_query(): Returns: google.cloud.retail_v2alpha.types.CompleteQueryResponse: - Response of the auto-complete query. + Response of the autocomplete query. """ # Create or coerce a protobuf request object. # Minor optimization to avoid making a copy if the user passes diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/completion_service/transports/grpc.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/completion_service/transports/grpc.py index 6691bc48607b..b91fd9d47a01 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/completion_service/transports/grpc.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/completion_service/transports/grpc.py @@ -32,7 +32,7 @@ class CompletionServiceGrpcTransport(CompletionServiceTransport): """gRPC backend transport for CompletionService. - Auto-completion service for retail. + Autocomplete service for retail. This feature is only available for users who have Retail Search enabled. Enable Retail Search on Cloud Console before using this feature. diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/completion_service/transports/grpc_asyncio.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/completion_service/transports/grpc_asyncio.py index 2a9a23b53e89..00e4ce7f8329 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/completion_service/transports/grpc_asyncio.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/completion_service/transports/grpc_asyncio.py @@ -33,7 +33,7 @@ class CompletionServiceGrpcAsyncIOTransport(CompletionServiceTransport): """gRPC AsyncIO backend transport for CompletionService. - Auto-completion service for retail. + Autocomplete service for retail. This feature is only available for users who have Retail Search enabled. Enable Retail Search on Cloud Console before using this feature. diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/completion_service/transports/rest.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/completion_service/transports/rest.py index 14158e1742f5..a8388f869e60 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/completion_service/transports/rest.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/completion_service/transports/rest.py @@ -198,7 +198,7 @@ class CompletionServiceRestStub: class CompletionServiceRestTransport(CompletionServiceTransport): """REST backend transport for CompletionService. - Auto-completion service for retail. + Autocomplete service for retail. This feature is only available for users who have Retail Search enabled. Enable Retail Search on Cloud Console before using this feature. @@ -380,7 +380,7 @@ def __call__( Args: request (~.completion_service.CompleteQueryRequest): - The request object. Auto-complete parameters. + The request object. Autocomplete parameters. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -389,7 +389,7 @@ def __call__( Returns: ~.completion_service.CompleteQueryResponse: - Response of the auto-complete query. + Response of the autocomplete query. """ http_options: List[Dict[str, str]] = [ diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/__init__.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/__init__.py new file mode 100644 index 000000000000..774b4c25eead --- /dev/null +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .async_client import MerchantCenterAccountLinkServiceAsyncClient +from .client import MerchantCenterAccountLinkServiceClient + +__all__ = ( + "MerchantCenterAccountLinkServiceClient", + "MerchantCenterAccountLinkServiceAsyncClient", +) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/async_client.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/async_client.py new file mode 100644 index 000000000000..0bbfa4705cac --- /dev/null +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/async_client.py @@ -0,0 +1,751 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +import functools +import re +from typing import ( + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, +) + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core.client_options import ClientOptions +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.retail_v2alpha import gapic_version as package_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 + +from google.cloud.retail_v2alpha.types import ( + merchant_center_account_link as gcr_merchant_center_account_link, +) +from google.cloud.retail_v2alpha.types import merchant_center_account_link_service +from google.cloud.retail_v2alpha.types import merchant_center_account_link + +from .client import MerchantCenterAccountLinkServiceClient +from .transports.base import ( + DEFAULT_CLIENT_INFO, + MerchantCenterAccountLinkServiceTransport, +) +from .transports.grpc_asyncio import ( + MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, +) + + +class MerchantCenterAccountLinkServiceAsyncClient: + """Merchant Center Link service to link a Branch to a Merchant + Center Account. + """ + + _client: MerchantCenterAccountLinkServiceClient + + DEFAULT_ENDPOINT = MerchantCenterAccountLinkServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = MerchantCenterAccountLinkServiceClient.DEFAULT_MTLS_ENDPOINT + + catalog_path = staticmethod(MerchantCenterAccountLinkServiceClient.catalog_path) + parse_catalog_path = staticmethod( + MerchantCenterAccountLinkServiceClient.parse_catalog_path + ) + merchant_center_account_link_path = staticmethod( + MerchantCenterAccountLinkServiceClient.merchant_center_account_link_path + ) + parse_merchant_center_account_link_path = staticmethod( + MerchantCenterAccountLinkServiceClient.parse_merchant_center_account_link_path + ) + common_billing_account_path = staticmethod( + MerchantCenterAccountLinkServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + MerchantCenterAccountLinkServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + MerchantCenterAccountLinkServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + MerchantCenterAccountLinkServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + MerchantCenterAccountLinkServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + MerchantCenterAccountLinkServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + MerchantCenterAccountLinkServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + MerchantCenterAccountLinkServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + MerchantCenterAccountLinkServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + MerchantCenterAccountLinkServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + MerchantCenterAccountLinkServiceAsyncClient: The constructed client. + """ + return MerchantCenterAccountLinkServiceClient.from_service_account_info.__func__(MerchantCenterAccountLinkServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + MerchantCenterAccountLinkServiceAsyncClient: The constructed client. + """ + return MerchantCenterAccountLinkServiceClient.from_service_account_file.__func__(MerchantCenterAccountLinkServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return MerchantCenterAccountLinkServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> MerchantCenterAccountLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + MerchantCenterAccountLinkServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial( + type(MerchantCenterAccountLinkServiceClient).get_transport_class, + type(MerchantCenterAccountLinkServiceClient), + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, MerchantCenterAccountLinkServiceTransport + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the merchant center account link service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.MerchantCenterAccountLinkServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = MerchantCenterAccountLinkServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + async def list_merchant_center_account_links( + self, + request: Optional[ + Union[ + merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest, + dict, + ] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse: + r"""Lists all + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink]s + under the specified parent + [Catalog][google.cloud.retail.v2alpha.Catalog]. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2alpha + + async def sample_list_merchant_center_account_links(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListMerchantCenterAccountLinksRequest( + parent="parent_value", + ) + + # Make the request + response = await client.list_merchant_center_account_links(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.ListMerchantCenterAccountLinksRequest, dict]]): + The request object. Request for + [MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks] + method. + parent (:class:`str`): + Required. The parent Catalog of the resource. It must + match this format: + projects/{PROJECT_NUMBER}/locations/global/catalogs/{CATALOG_ID} + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2alpha.types.ListMerchantCenterAccountLinksResponse: + Response for + [MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks] + method. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = ( + merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_merchant_center_account_links, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def create_merchant_center_account_link( + self, + request: Optional[ + Union[ + merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest, + dict, + ] + ] = None, + *, + parent: Optional[str] = None, + merchant_center_account_link: Optional[ + gcr_merchant_center_account_link.MerchantCenterAccountLink + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Creates a MerchantCenterAccountLink. + + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink] + cannot be set to a different oneof field, if so an + INVALID_ARGUMENT is returned. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2alpha + + async def sample_create_merchant_center_account_link(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient() + + # Initialize request argument(s) + merchant_center_account_link = retail_v2alpha.MerchantCenterAccountLink() + merchant_center_account_link.merchant_center_account_id = 2730 + merchant_center_account_link.branch_id = "branch_id_value" + + request = retail_v2alpha.CreateMerchantCenterAccountLinkRequest( + parent="parent_value", + merchant_center_account_link=merchant_center_account_link, + ) + + # Make the request + operation = client.create_merchant_center_account_link(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.CreateMerchantCenterAccountLinkRequest, dict]]): + The request object. Request for + [MerchantCenterAccountLinkService.CreateMerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.CreateMerchantCenterAccountLink] + method. + parent (:class:`str`): + Required. The branch resource where this + MerchantCenterAccountLink will be created. Format: + projects/{PROJECT_NUMBER}/locations/global/catalogs/{CATALOG_ID}} + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + merchant_center_account_link (:class:`google.cloud.retail_v2alpha.types.MerchantCenterAccountLink`): + Required. The + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink] + to create. + + If the caller does not have permission to create the + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + This corresponds to the ``merchant_center_account_link`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2alpha.types.MerchantCenterAccountLink` Represents a link between a Merchant Center account and a branch. + Once a link is established, products from the linked + merchant center account will be streamed to the + linked branch. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, merchant_center_account_link]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = ( + merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if merchant_center_account_link is not None: + request.merchant_center_account_link = merchant_center_account_link + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_merchant_center_account_link, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + ( + ( + "merchant_center_account_link.name", + request.merchant_center_account_link.name, + ), + ) + ), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + gcr_merchant_center_account_link.MerchantCenterAccountLink, + metadata_type=gcr_merchant_center_account_link.CreateMerchantCenterAccountLinkMetadata, + ) + + # Done; return the response. + return response + + async def delete_merchant_center_account_link( + self, + request: Optional[ + Union[ + merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest, + dict, + ] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes a MerchantCenterAccountLink. If the + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink] + to delete does not exist, a NOT_FOUND error is returned. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2alpha + + async def sample_delete_merchant_center_account_link(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteMerchantCenterAccountLinkRequest( + name="name_value", + ) + + # Make the request + await client.delete_merchant_center_account_link(request=request) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.DeleteMerchantCenterAccountLinkRequest, dict]]): + The request object. Request for + [MerchantCenterAccountLinkService.DeleteMerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.DeleteMerchantCenterAccountLink] + method. + name (:class:`str`): + Required. Full resource name. Format: + projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/merchantCenterAccountLinks/{merchant_center_account_link_id} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = ( + merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_merchant_center_account_link, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + + +__all__ = ("MerchantCenterAccountLinkServiceAsyncClient",) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/client.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/client.py new file mode 100644 index 000000000000..269838942e4d --- /dev/null +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/client.py @@ -0,0 +1,1009 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +import os +import re +from typing import ( + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.retail_v2alpha import gapic_version as package_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 + +from google.cloud.retail_v2alpha.types import ( + merchant_center_account_link as gcr_merchant_center_account_link, +) +from google.cloud.retail_v2alpha.types import merchant_center_account_link_service +from google.cloud.retail_v2alpha.types import merchant_center_account_link + +from .transports.base import ( + DEFAULT_CLIENT_INFO, + MerchantCenterAccountLinkServiceTransport, +) +from .transports.grpc import MerchantCenterAccountLinkServiceGrpcTransport +from .transports.grpc_asyncio import ( + MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, +) +from .transports.rest import MerchantCenterAccountLinkServiceRestTransport + + +class MerchantCenterAccountLinkServiceClientMeta(type): + """Metaclass for the MerchantCenterAccountLinkService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[MerchantCenterAccountLinkServiceTransport]] + _transport_registry["grpc"] = MerchantCenterAccountLinkServiceGrpcTransport + _transport_registry[ + "grpc_asyncio" + ] = MerchantCenterAccountLinkServiceGrpcAsyncIOTransport + _transport_registry["rest"] = MerchantCenterAccountLinkServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[MerchantCenterAccountLinkServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class MerchantCenterAccountLinkServiceClient( + metaclass=MerchantCenterAccountLinkServiceClientMeta +): + """Merchant Center Link service to link a Branch to a Merchant + Center Account. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_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: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "retail.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + MerchantCenterAccountLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + MerchantCenterAccountLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file(filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> MerchantCenterAccountLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + MerchantCenterAccountLinkServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def catalog_path( + project: str, + location: str, + catalog: str, + ) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format( + project=project, + location=location, + catalog=catalog, + ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str, str]: + """Parses a catalog path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def merchant_center_account_link_path( + project: str, + location: str, + catalog: str, + merchant_center_account_link: str, + ) -> str: + """Returns a fully-qualified merchant_center_account_link string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/merchantCenterAccountLinks/{merchant_center_account_link}".format( + project=project, + location=location, + catalog=catalog, + merchant_center_account_link=merchant_center_account_link, + ) + + @staticmethod + def parse_merchant_center_account_link_path(path: str) -> Dict[str, str]: + """Parses a merchant_center_account_link path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/merchantCenterAccountLinks/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns 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: + """Returns 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: + """Returns 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: + """Returns 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: + """Returns 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 {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[str, MerchantCenterAccountLinkServiceTransport] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the merchant center account link service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, MerchantCenterAccountLinkServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + client_options = cast(client_options_lib.ClientOptions, client_options) + + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source( + client_options + ) + + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, MerchantCenterAccountLinkServiceTransport): + # transport is a MerchantCenterAccountLinkServiceTransport instance. + if credentials or client_options.credentials_file or api_key_value: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=client_options.api_audience, + ) + + def list_merchant_center_account_links( + self, + request: Optional[ + Union[ + merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest, + dict, + ] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse: + r"""Lists all + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink]s + under the specified parent + [Catalog][google.cloud.retail.v2alpha.Catalog]. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2alpha + + def sample_list_merchant_center_account_links(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListMerchantCenterAccountLinksRequest( + parent="parent_value", + ) + + # Make the request + response = client.list_merchant_center_account_links(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.ListMerchantCenterAccountLinksRequest, dict]): + The request object. Request for + [MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks] + method. + parent (str): + Required. The parent Catalog of the resource. It must + match this format: + projects/{PROJECT_NUMBER}/locations/global/catalogs/{CATALOG_ID} + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2alpha.types.ListMerchantCenterAccountLinksResponse: + Response for + [MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks] + method. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest, + ): + request = merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_merchant_center_account_links + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def create_merchant_center_account_link( + self, + request: Optional[ + Union[ + merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest, + dict, + ] + ] = None, + *, + parent: Optional[str] = None, + merchant_center_account_link: Optional[ + gcr_merchant_center_account_link.MerchantCenterAccountLink + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Creates a MerchantCenterAccountLink. + + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink] + cannot be set to a different oneof field, if so an + INVALID_ARGUMENT is returned. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2alpha + + def sample_create_merchant_center_account_link(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceClient() + + # Initialize request argument(s) + merchant_center_account_link = retail_v2alpha.MerchantCenterAccountLink() + merchant_center_account_link.merchant_center_account_id = 2730 + merchant_center_account_link.branch_id = "branch_id_value" + + request = retail_v2alpha.CreateMerchantCenterAccountLinkRequest( + parent="parent_value", + merchant_center_account_link=merchant_center_account_link, + ) + + # Make the request + operation = client.create_merchant_center_account_link(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.CreateMerchantCenterAccountLinkRequest, dict]): + The request object. Request for + [MerchantCenterAccountLinkService.CreateMerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.CreateMerchantCenterAccountLink] + method. + parent (str): + Required. The branch resource where this + MerchantCenterAccountLink will be created. Format: + projects/{PROJECT_NUMBER}/locations/global/catalogs/{CATALOG_ID}} + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + merchant_center_account_link (google.cloud.retail_v2alpha.types.MerchantCenterAccountLink): + Required. The + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink] + to create. + + If the caller does not have permission to create the + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + This corresponds to the ``merchant_center_account_link`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2alpha.types.MerchantCenterAccountLink` Represents a link between a Merchant Center account and a branch. + Once a link is established, products from the linked + merchant center account will be streamed to the + linked branch. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, merchant_center_account_link]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest, + ): + request = merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if merchant_center_account_link is not None: + request.merchant_center_account_link = merchant_center_account_link + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.create_merchant_center_account_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + ( + ( + "merchant_center_account_link.name", + request.merchant_center_account_link.name, + ), + ) + ), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + gcr_merchant_center_account_link.MerchantCenterAccountLink, + metadata_type=gcr_merchant_center_account_link.CreateMerchantCenterAccountLinkMetadata, + ) + + # Done; return the response. + return response + + def delete_merchant_center_account_link( + self, + request: Optional[ + Union[ + merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest, + dict, + ] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes a MerchantCenterAccountLink. If the + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink] + to delete does not exist, a NOT_FOUND error is returned. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2alpha + + def sample_delete_merchant_center_account_link(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteMerchantCenterAccountLinkRequest( + name="name_value", + ) + + # Make the request + client.delete_merchant_center_account_link(request=request) + + Args: + request (Union[google.cloud.retail_v2alpha.types.DeleteMerchantCenterAccountLinkRequest, dict]): + The request object. Request for + [MerchantCenterAccountLinkService.DeleteMerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.DeleteMerchantCenterAccountLink] + method. + name (str): + Required. Full resource name. Format: + projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/merchantCenterAccountLinks/{merchant_center_account_link_id} + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest, + ): + request = merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.delete_merchant_center_account_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def __enter__(self) -> "MerchantCenterAccountLinkServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + + +__all__ = ("MerchantCenterAccountLinkServiceClient",) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/__init__.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/__init__.py new file mode 100644 index 000000000000..8eadb9b5cca0 --- /dev/null +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/__init__.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from typing import Dict, Type + +from .base import MerchantCenterAccountLinkServiceTransport +from .grpc import MerchantCenterAccountLinkServiceGrpcTransport +from .grpc_asyncio import MerchantCenterAccountLinkServiceGrpcAsyncIOTransport +from .rest import ( + MerchantCenterAccountLinkServiceRestInterceptor, + MerchantCenterAccountLinkServiceRestTransport, +) + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[MerchantCenterAccountLinkServiceTransport]] +_transport_registry["grpc"] = MerchantCenterAccountLinkServiceGrpcTransport +_transport_registry[ + "grpc_asyncio" +] = MerchantCenterAccountLinkServiceGrpcAsyncIOTransport +_transport_registry["rest"] = MerchantCenterAccountLinkServiceRestTransport + +__all__ = ( + "MerchantCenterAccountLinkServiceTransport", + "MerchantCenterAccountLinkServiceGrpcTransport", + "MerchantCenterAccountLinkServiceGrpcAsyncIOTransport", + "MerchantCenterAccountLinkServiceRestTransport", + "MerchantCenterAccountLinkServiceRestInterceptor", +) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/base.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/base.py new file mode 100644 index 000000000000..8fb644b7cb9c --- /dev/null +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/base.py @@ -0,0 +1,217 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, operations_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +from google.protobuf import empty_pb2 # type: ignore + +from google.cloud.retail_v2alpha import gapic_version as package_version +from google.cloud.retail_v2alpha.types import merchant_center_account_link_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + + +class MerchantCenterAccountLinkServiceTransport(abc.ABC): + """Abstract transport class for MerchantCenterAccountLinkService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + + DEFAULT_HOST: str = "retail.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[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, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + 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): + 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. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, **scopes_kwargs, quota_project_id=quota_project_id + ) + elif credentials is None: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr(service_account.Credentials, "with_always_use_jwt_access") + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.list_merchant_center_account_links: gapic_v1.method.wrap_method( + self.list_merchant_center_account_links, + default_timeout=None, + client_info=client_info, + ), + self.create_merchant_center_account_link: gapic_v1.method.wrap_method( + self.create_merchant_center_account_link, + default_timeout=None, + client_info=client_info, + ), + self.delete_merchant_center_account_link: gapic_v1.method.wrap_method( + self.delete_merchant_center_account_link, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def list_merchant_center_account_links( + self, + ) -> Callable[ + [merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest], + Union[ + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse, + Awaitable[ + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def create_merchant_center_account_link( + self, + ) -> Callable[ + [merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def delete_merchant_center_account_link( + self, + ) -> Callable[ + [merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest], + Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], + ]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[ + operations_pb2.ListOperationsResponse, + Awaitable[operations_pb2.ListOperationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("MerchantCenterAccountLinkServiceTransport",) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/grpc.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/grpc.py new file mode 100644 index 000000000000..705e9d409e0f --- /dev/null +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/grpc.py @@ -0,0 +1,401 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import Callable, Dict, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import gapic_v1, grpc_helpers, operations_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +import grpc # type: ignore + +from google.cloud.retail_v2alpha.types import merchant_center_account_link_service + +from .base import DEFAULT_CLIENT_INFO, MerchantCenterAccountLinkServiceTransport + + +class MerchantCenterAccountLinkServiceGrpcTransport( + MerchantCenterAccountLinkServiceTransport +): + """gRPC backend transport for MerchantCenterAccountLinkService. + + Merchant Center Link service to link a Branch to a Merchant + Center Account. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "retail.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[grpc.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # 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 + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "retail.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient(self.grpc_channel) + + # Return the client from cache. + return self._operations_client + + @property + def list_merchant_center_account_links( + self, + ) -> Callable[ + [merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest], + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse, + ]: + r"""Return a callable for the list merchant center account + links method over gRPC. + + Lists all + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink]s + under the specified parent + [Catalog][google.cloud.retail.v2alpha.Catalog]. + + Returns: + Callable[[~.ListMerchantCenterAccountLinksRequest], + ~.ListMerchantCenterAccountLinksResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_merchant_center_account_links" not in self._stubs: + self._stubs[ + "list_merchant_center_account_links" + ] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2alpha.MerchantCenterAccountLinkService/ListMerchantCenterAccountLinks", + request_serializer=merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest.serialize, + response_deserializer=merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse.deserialize, + ) + return self._stubs["list_merchant_center_account_links"] + + @property + def create_merchant_center_account_link( + self, + ) -> Callable[ + [merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest], + operations_pb2.Operation, + ]: + r"""Return a callable for the create merchant center account + link method over gRPC. + + Creates a MerchantCenterAccountLink. + + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink] + cannot be set to a different oneof field, if so an + INVALID_ARGUMENT is returned. + + Returns: + Callable[[~.CreateMerchantCenterAccountLinkRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_merchant_center_account_link" not in self._stubs: + self._stubs[ + "create_merchant_center_account_link" + ] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2alpha.MerchantCenterAccountLinkService/CreateMerchantCenterAccountLink", + request_serializer=merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_merchant_center_account_link"] + + @property + def delete_merchant_center_account_link( + self, + ) -> Callable[ + [merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest], + empty_pb2.Empty, + ]: + r"""Return a callable for the delete merchant center account + link method over gRPC. + + Deletes a MerchantCenterAccountLink. If the + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink] + to delete does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.DeleteMerchantCenterAccountLinkRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_merchant_center_account_link" not in self._stubs: + self._stubs[ + "delete_merchant_center_account_link" + ] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2alpha.MerchantCenterAccountLinkService/DeleteMerchantCenterAccountLink", + request_serializer=merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_merchant_center_account_link"] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("MerchantCenterAccountLinkServiceGrpcTransport",) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/grpc_asyncio.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/grpc_asyncio.py new file mode 100644 index 000000000000..d84de76fe6fb --- /dev/null +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/grpc_asyncio.py @@ -0,0 +1,404 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import gapic_v1, grpc_helpers_async, operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.retail_v2alpha.types import merchant_center_account_link_service + +from .base import DEFAULT_CLIENT_INFO, MerchantCenterAccountLinkServiceTransport +from .grpc import MerchantCenterAccountLinkServiceGrpcTransport + + +class MerchantCenterAccountLinkServiceGrpcAsyncIOTransport( + MerchantCenterAccountLinkServiceTransport +): + """gRPC AsyncIO backend transport for MerchantCenterAccountLinkService. + + Merchant Center Link service to link a Branch to a Merchant + Center Account. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "retail.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "retail.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[aio.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # 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 + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def list_merchant_center_account_links( + self, + ) -> Callable[ + [merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest], + Awaitable[ + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse + ], + ]: + r"""Return a callable for the list merchant center account + links method over gRPC. + + Lists all + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink]s + under the specified parent + [Catalog][google.cloud.retail.v2alpha.Catalog]. + + Returns: + Callable[[~.ListMerchantCenterAccountLinksRequest], + Awaitable[~.ListMerchantCenterAccountLinksResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_merchant_center_account_links" not in self._stubs: + self._stubs[ + "list_merchant_center_account_links" + ] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2alpha.MerchantCenterAccountLinkService/ListMerchantCenterAccountLinks", + request_serializer=merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest.serialize, + response_deserializer=merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse.deserialize, + ) + return self._stubs["list_merchant_center_account_links"] + + @property + def create_merchant_center_account_link( + self, + ) -> Callable[ + [merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the create merchant center account + link method over gRPC. + + Creates a MerchantCenterAccountLink. + + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink] + cannot be set to a different oneof field, if so an + INVALID_ARGUMENT is returned. + + Returns: + Callable[[~.CreateMerchantCenterAccountLinkRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_merchant_center_account_link" not in self._stubs: + self._stubs[ + "create_merchant_center_account_link" + ] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2alpha.MerchantCenterAccountLinkService/CreateMerchantCenterAccountLink", + request_serializer=merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_merchant_center_account_link"] + + @property + def delete_merchant_center_account_link( + self, + ) -> Callable[ + [merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest], + Awaitable[empty_pb2.Empty], + ]: + r"""Return a callable for the delete merchant center account + link method over gRPC. + + Deletes a MerchantCenterAccountLink. If the + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink] + to delete does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.DeleteMerchantCenterAccountLinkRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_merchant_center_account_link" not in self._stubs: + self._stubs[ + "delete_merchant_center_account_link" + ] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2alpha.MerchantCenterAccountLinkService/DeleteMerchantCenterAccountLink", + request_serializer=merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_merchant_center_account_link"] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ("MerchantCenterAccountLinkServiceGrpcAsyncIOTransport",) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/rest.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/rest.py new file mode 100644 index 000000000000..e9bba943c84a --- /dev/null +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/rest.py @@ -0,0 +1,878 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import dataclasses +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import ( + gapic_v1, + operations_v1, + path_template, + rest_helpers, + rest_streaming, +) +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 +from google.protobuf import json_format +import grpc # type: ignore +from requests import __version__ as requests_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + + +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore + +from google.cloud.retail_v2alpha.types import merchant_center_account_link_service + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .base import MerchantCenterAccountLinkServiceTransport + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=requests_version, +) + + +class MerchantCenterAccountLinkServiceRestInterceptor: + """Interceptor for MerchantCenterAccountLinkService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the MerchantCenterAccountLinkServiceRestTransport. + + .. code-block:: python + class MyCustomMerchantCenterAccountLinkServiceInterceptor(MerchantCenterAccountLinkServiceRestInterceptor): + def pre_create_merchant_center_account_link(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_merchant_center_account_link(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_merchant_center_account_link(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_list_merchant_center_account_links(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_merchant_center_account_links(self, response): + logging.log(f"Received response: {response}") + return response + + transport = MerchantCenterAccountLinkServiceRestTransport(interceptor=MyCustomMerchantCenterAccountLinkServiceInterceptor()) + client = MerchantCenterAccountLinkServiceClient(transport=transport) + + + """ + + def pre_create_merchant_center_account_link( + self, + request: merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest, + Sequence[Tuple[str, str]], + ]: + """Pre-rpc interceptor for create_merchant_center_account_link + + Override in a subclass to manipulate the request or metadata + before they are sent to the MerchantCenterAccountLinkService server. + """ + return request, metadata + + def post_create_merchant_center_account_link( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for create_merchant_center_account_link + + Override in a subclass to manipulate the response + after it is returned by the MerchantCenterAccountLinkService server but before + it is returned to user code. + """ + return response + + def pre_delete_merchant_center_account_link( + self, + request: merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest, + Sequence[Tuple[str, str]], + ]: + """Pre-rpc interceptor for delete_merchant_center_account_link + + Override in a subclass to manipulate the request or metadata + before they are sent to the MerchantCenterAccountLinkService server. + """ + return request, metadata + + def pre_list_merchant_center_account_links( + self, + request: merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest, + Sequence[Tuple[str, str]], + ]: + """Pre-rpc interceptor for list_merchant_center_account_links + + Override in a subclass to manipulate the request or metadata + before they are sent to the MerchantCenterAccountLinkService server. + """ + return request, metadata + + def post_list_merchant_center_account_links( + self, + response: merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse, + ) -> merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse: + """Post-rpc interceptor for list_merchant_center_account_links + + Override in a subclass to manipulate the response + after it is returned by the MerchantCenterAccountLinkService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the MerchantCenterAccountLinkService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the MerchantCenterAccountLinkService server but before + it is returned to user code. + """ + return response + + def pre_list_operations( + self, + request: operations_pb2.ListOperationsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the MerchantCenterAccountLinkService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the MerchantCenterAccountLinkService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class MerchantCenterAccountLinkServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: MerchantCenterAccountLinkServiceRestInterceptor + + +class MerchantCenterAccountLinkServiceRestTransport( + MerchantCenterAccountLinkServiceTransport +): + """REST backend transport for MerchantCenterAccountLinkService. + + Merchant Center Link service to link a Branch to a Merchant + Center Account. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + + """ + + def __init__( + self, + *, + host: str = "retail.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[MerchantCenterAccountLinkServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP 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 are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = ( + interceptor or MerchantCenterAccountLinkServiceRestInterceptor() + ) + self._prep_wrapped_messages(client_info) + + @property + def operations_client(self) -> operations_v1.AbstractOperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Only create a new client if we do not already have one. + if self._operations_client is None: + http_options: Dict[str, List[Dict[str, str]]] = { + "google.longrunning.Operations.GetOperation": [ + { + "method": "get", + "uri": "/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}", + }, + { + "method": "get", + "uri": "/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/places/*/operations/*}", + }, + { + "method": "get", + "uri": "/v2alpha/{name=projects/*/locations/*/catalogs/*/operations/*}", + }, + { + "method": "get", + "uri": "/v2alpha/{name=projects/*/locations/*/operations/*}", + }, + { + "method": "get", + "uri": "/v2alpha/{name=projects/*/operations/*}", + }, + ], + "google.longrunning.Operations.ListOperations": [ + { + "method": "get", + "uri": "/v2alpha/{name=projects/*/locations/*/catalogs/*}/operations", + }, + { + "method": "get", + "uri": "/v2alpha/{name=projects/*/locations/*}/operations", + }, + { + "method": "get", + "uri": "/v2alpha/{name=projects/*}/operations", + }, + ], + } + + rest_transport = operations_v1.OperationsRestTransport( + host=self._host, + # use the credentials which are saved + credentials=self._credentials, + scopes=self._scopes, + http_options=http_options, + path_prefix="v2alpha", + ) + + self._operations_client = operations_v1.AbstractOperationsClient( + transport=rest_transport + ) + + # Return the client from cache. + return self._operations_client + + class _CreateMerchantCenterAccountLink(MerchantCenterAccountLinkServiceRestStub): + def __hash__(self): + return hash("CreateMerchantCenterAccountLink") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "parent": "", + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Call the create merchant center + account link method over HTTP. + + Args: + request (~.merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest): + The request object. Request for + [MerchantCenterAccountLinkService.CreateMerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.CreateMerchantCenterAccountLink] + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2alpha/{merchant_center_account_link.name=projects/*/locations/*/catalogs/*/merchantCenterAccountLinks/*}", + "body": "merchant_center_account_link", + }, + ] + ( + request, + metadata, + ) = self._interceptor.pre_create_merchant_center_account_link( + request, metadata + ) + pb_request = merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_merchant_center_account_link(resp) + return resp + + class _DeleteMerchantCenterAccountLink(MerchantCenterAccountLinkServiceRestStub): + def __hash__(self): + return hash("DeleteMerchantCenterAccountLink") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ): + r"""Call the delete merchant center + account link method over HTTP. + + Args: + request (~.merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest): + The request object. Request for + [MerchantCenterAccountLinkService.DeleteMerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.DeleteMerchantCenterAccountLink] + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v2alpha/{name=projects/*/locations/*/catalogs/*/merchantCenterAccountLinks/*}", + }, + ] + ( + request, + metadata, + ) = self._interceptor.pre_delete_merchant_center_account_link( + request, metadata + ) + pb_request = merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _ListMerchantCenterAccountLinks(MerchantCenterAccountLinkServiceRestStub): + def __hash__(self): + return hash("ListMerchantCenterAccountLinks") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse: + r"""Call the list merchant center + account links method over HTTP. + + Args: + request (~.merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest): + The request object. Request for + [MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks] + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse: + Response for + [MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks] + method. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2alpha/{parent=projects/*/locations/*/catalogs/*}/merchantCenterAccountLinks", + }, + ] + ( + request, + metadata, + ) = self._interceptor.pre_list_merchant_center_account_links( + request, metadata + ) + pb_request = merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = ( + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse() + ) + pb_resp = merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse.pb( + resp + ) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_merchant_center_account_links(resp) + return resp + + @property + def create_merchant_center_account_link( + self, + ) -> Callable[ + [merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest], + operations_pb2.Operation, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateMerchantCenterAccountLink(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_merchant_center_account_link( + self, + ) -> Callable[ + [merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest], + empty_pb2.Empty, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteMerchantCenterAccountLink(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_merchant_center_account_links( + self, + ) -> Callable[ + [merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest], + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListMerchantCenterAccountLinks(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(MerchantCenterAccountLinkServiceRestStub): + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}", + }, + { + "method": "get", + "uri": "/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/places/*/operations/*}", + }, + { + "method": "get", + "uri": "/v2alpha/{name=projects/*/locations/*/catalogs/*/operations/*}", + }, + { + "method": "get", + "uri": "/v2alpha/{name=projects/*/locations/*/operations/*}", + }, + { + "method": "get", + "uri": "/v2alpha/{name=projects/*/operations/*}", + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(MerchantCenterAccountLinkServiceRestStub): + def __call__( + self, + request: operations_pb2.ListOperationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + operations_pb2.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2alpha/{name=projects/*/locations/*/catalogs/*}/operations", + }, + { + "method": "get", + "uri": "/v2alpha/{name=projects/*/locations/*}/operations", + }, + { + "method": "get", + "uri": "/v2alpha/{name=projects/*}/operations", + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("MerchantCenterAccountLinkServiceRestTransport",) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/async_client.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/async_client.py index 9581f8103d7f..bd13f831b8c1 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/async_client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/async_client.py @@ -373,6 +373,113 @@ async def sample_create_model(): # Done; return the response. return response + async def get_model( + self, + request: Optional[Union[model_service.GetModelRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> model.Model: + r"""Gets a model. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2alpha + + async def sample_get_model(): + # Create a client + client = retail_v2alpha.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetModelRequest( + name="name_value", + ) + + # Make the request + response = await client.get_model(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.GetModelRequest, dict]]): + The request object. Request for getting a model. + name (:class:`str`): + Required. The resource name of the + [Model][google.cloud.retail.v2alpha.Model] to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog}/models/{model_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2alpha.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2alpha.Model]. A + [Model][google.cloud.retail.v2alpha.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and then queried through the Predict API. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = model_service.GetModelRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_model, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + async def pause_model( self, request: Optional[Union[model_service.PauseModelRequest, dict]] = None, diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/client.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/client.py index aae8f0cc7a81..9f4442036831 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/client.py @@ -626,6 +626,113 @@ def sample_create_model(): # Done; return the response. return response + def get_model( + self, + request: Optional[Union[model_service.GetModelRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> model.Model: + r"""Gets a model. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2alpha + + def sample_get_model(): + # Create a client + client = retail_v2alpha.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetModelRequest( + name="name_value", + ) + + # Make the request + response = client.get_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.GetModelRequest, dict]): + The request object. Request for getting a model. + name (str): + Required. The resource name of the + [Model][google.cloud.retail.v2alpha.Model] to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog}/models/{model_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2alpha.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2alpha.Model]. A + [Model][google.cloud.retail.v2alpha.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and then queried through the Predict API. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a model_service.GetModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.GetModelRequest): + request = model_service.GetModelRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_model] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + def pause_model( self, request: Optional[Union[model_service.PauseModelRequest, dict]] = None, diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/transports/base.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/transports/base.py index 727d8f6a9665..4030f6c84516 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/transports/base.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/transports/base.py @@ -132,6 +132,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.get_model: gapic_v1.method.wrap_method( + self.get_model, + default_timeout=None, + client_info=client_info, + ), self.pause_model: gapic_v1.method.wrap_method( self.pause_model, default_timeout=None, @@ -187,6 +192,14 @@ def create_model( ]: raise NotImplementedError() + @property + def get_model( + self, + ) -> Callable[ + [model_service.GetModelRequest], Union[model.Model, Awaitable[model.Model]] + ]: + raise NotImplementedError() + @property def pause_model( self, diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/transports/grpc.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/transports/grpc.py index 44f408267013..6f9952a11805 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/transports/grpc.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/transports/grpc.py @@ -285,6 +285,30 @@ def create_model( ) return self._stubs["create_model"] + @property + def get_model(self) -> Callable[[model_service.GetModelRequest], model.Model]: + r"""Return a callable for the get model method over gRPC. + + Gets a model. + + Returns: + Callable[[~.GetModelRequest], + ~.Model]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_model" not in self._stubs: + self._stubs["get_model"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2alpha.ModelService/GetModel", + request_serializer=model_service.GetModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs["get_model"] + @property def pause_model(self) -> Callable[[model_service.PauseModelRequest], model.Model]: r"""Return a callable for the pause model method over gRPC. diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/transports/grpc_asyncio.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/transports/grpc_asyncio.py index 6483226428f9..95db273f247d 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/transports/grpc_asyncio.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/transports/grpc_asyncio.py @@ -292,6 +292,32 @@ def create_model( ) return self._stubs["create_model"] + @property + def get_model( + self, + ) -> Callable[[model_service.GetModelRequest], Awaitable[model.Model]]: + r"""Return a callable for the get model method over gRPC. + + Gets a model. + + Returns: + Callable[[~.GetModelRequest], + Awaitable[~.Model]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_model" not in self._stubs: + self._stubs["get_model"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2alpha.ModelService/GetModel", + request_serializer=model_service.GetModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs["get_model"] + @property def pause_model( self, diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/transports/rest.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/transports/rest.py index f5d5693dc953..d0365cdc5bfa 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/transports/rest.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/model_service/transports/rest.py @@ -88,6 +88,14 @@ def pre_delete_model(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata + def pre_get_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_model(self, response): + logging.log(f"Received response: {response}") + return response + def pre_list_models(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -169,6 +177,27 @@ def pre_delete_model( """ return request, metadata + def pre_get_model( + self, + request: model_service.GetModelRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[model_service.GetModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_get_model(self, response: model.Model) -> model.Model: + """Post-rpc interceptor for get_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_list_models( self, request: model_service.ListModelsRequest, @@ -667,6 +696,99 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) + class _GetModel(ModelServiceRestStub): + def __hash__(self): + return hash("GetModel") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: model_service.GetModelRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> model.Model: + r"""Call the get model method over HTTP. + + Args: + request (~.model_service.GetModelRequest): + The request object. Request for getting a model. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.model.Model: + Metadata that describes the training and serving + parameters of a + [Model][google.cloud.retail.v2alpha.Model]. A + [Model][google.cloud.retail.v2alpha.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and then queried through the Predict API. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2alpha/{name=projects/*/locations/*/catalogs/*/models/*}", + }, + ] + request, metadata = self._interceptor.pre_get_model(request, metadata) + pb_request = model_service.GetModelRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = model.Model() + pb_resp = model.Model.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_model(resp) + return resp + class _ListModels(ModelServiceRestStub): def __hash__(self): return hash("ListModels") @@ -1178,6 +1300,12 @@ def delete_model( # In C++ this would require a dynamic_cast return self._DeleteModel(self._session, self._host, self._interceptor) # type: ignore + @property + def get_model(self) -> Callable[[model_service.GetModelRequest], model.Model]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetModel(self._session, self._host, self._interceptor) # type: ignore + @property def list_models( self, diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/product_service/async_client.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/product_service/async_client.py index 6a3afe4c1207..e04bca5fc085 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/product_service/async_client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/product_service/async_client.py @@ -1167,10 +1167,6 @@ async def set_inventory( [done][google.longrunning.Operation.done] until they are obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -1374,7 +1370,15 @@ async def add_fulfillment_places( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, str]] = (), ) -> operation_async.AsyncOperation: - r"""Incrementally adds place IDs to + r"""It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally adds place IDs to [Product.fulfillment_info.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids]. This process is asynchronous and does not require the @@ -1398,10 +1402,6 @@ async def add_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -1529,7 +1529,15 @@ async def remove_fulfillment_places( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, str]] = (), ) -> operation_async.AsyncOperation: - r"""Incrementally removes place IDs from a + r"""It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally removes place IDs from a [Product.fulfillment_info.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids]. This process is asynchronous and does not require the @@ -1553,10 +1561,6 @@ async def remove_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -1717,10 +1721,6 @@ async def add_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -1878,10 +1878,6 @@ async def remove_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/product_service/client.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/product_service/client.py index 1c1c48839d8d..67abe14c4f3d 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/product_service/client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/product_service/client.py @@ -1414,10 +1414,6 @@ def set_inventory( [done][google.longrunning.Operation.done] until they are obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -1621,7 +1617,15 @@ def add_fulfillment_places( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, str]] = (), ) -> operation.Operation: - r"""Incrementally adds place IDs to + r"""It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally adds place IDs to [Product.fulfillment_info.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids]. This process is asynchronous and does not require the @@ -1645,10 +1649,6 @@ def add_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -1776,7 +1776,15 @@ def remove_fulfillment_places( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, str]] = (), ) -> operation.Operation: - r"""Incrementally removes place IDs from a + r"""It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally removes place IDs from a [Product.fulfillment_info.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids]. This process is asynchronous and does not require the @@ -1800,10 +1808,6 @@ def remove_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -1966,10 +1970,6 @@ def add_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -2127,10 +2127,6 @@ def remove_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/product_service/transports/grpc.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/product_service/transports/grpc.py index 88e3b0141a07..6d394bb9f6d8 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/product_service/transports/grpc.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/product_service/transports/grpc.py @@ -521,10 +521,6 @@ def set_inventory( [done][google.longrunning.Operation.done] until they are obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.SetInventoryRequest], ~.Operation]: @@ -551,6 +547,14 @@ def add_fulfillment_places( ]: r"""Return a callable for the add fulfillment places method over gRPC. + It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + Incrementally adds place IDs to [Product.fulfillment_info.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids]. @@ -575,10 +579,6 @@ def add_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.AddFulfillmentPlacesRequest], ~.Operation]: @@ -605,6 +605,14 @@ def remove_fulfillment_places( ]: r"""Return a callable for the remove fulfillment places method over gRPC. + It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + Incrementally removes place IDs from a [Product.fulfillment_info.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids]. @@ -629,10 +637,6 @@ def remove_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.RemoveFulfillmentPlacesRequest], ~.Operation]: @@ -692,10 +696,6 @@ def add_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.AddLocalInventoriesRequest], ~.Operation]: @@ -752,10 +752,6 @@ def remove_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.RemoveLocalInventoriesRequest], ~.Operation]: diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/product_service/transports/grpc_asyncio.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/product_service/transports/grpc_asyncio.py index 56ae21fd3013..76498da545d0 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/product_service/transports/grpc_asyncio.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/product_service/transports/grpc_asyncio.py @@ -537,10 +537,6 @@ def set_inventory( [done][google.longrunning.Operation.done] until they are obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.SetInventoryRequest], Awaitable[~.Operation]]: @@ -568,6 +564,14 @@ def add_fulfillment_places( ]: r"""Return a callable for the add fulfillment places method over gRPC. + It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + Incrementally adds place IDs to [Product.fulfillment_info.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids]. @@ -592,10 +596,6 @@ def add_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.AddFulfillmentPlacesRequest], Awaitable[~.Operation]]: @@ -623,6 +623,14 @@ def remove_fulfillment_places( ]: r"""Return a callable for the remove fulfillment places method over gRPC. + It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + Incrementally removes place IDs from a [Product.fulfillment_info.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids]. @@ -647,10 +655,6 @@ def remove_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.RemoveFulfillmentPlacesRequest], Awaitable[~.Operation]]: @@ -711,10 +715,6 @@ def add_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.AddLocalInventoriesRequest], Awaitable[~.Operation]]: @@ -772,10 +772,6 @@ def remove_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.RemoveLocalInventoriesRequest], Awaitable[~.Operation]]: diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/search_service/async_client.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/search_service/async_client.py index a48a99bfa0f1..124dcaf63654 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/search_service/async_client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/search_service/async_client.py @@ -67,8 +67,14 @@ class SearchServiceAsyncClient: branch_path = staticmethod(SearchServiceClient.branch_path) parse_branch_path = staticmethod(SearchServiceClient.parse_branch_path) + experiment_path = staticmethod(SearchServiceClient.experiment_path) + parse_experiment_path = staticmethod(SearchServiceClient.parse_experiment_path) product_path = staticmethod(SearchServiceClient.product_path) parse_product_path = staticmethod(SearchServiceClient.parse_product_path) + serving_config_path = staticmethod(SearchServiceClient.serving_config_path) + parse_serving_config_path = staticmethod( + SearchServiceClient.parse_serving_config_path + ) common_billing_account_path = staticmethod( SearchServiceClient.common_billing_account_path ) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/search_service/client.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/search_service/client.py index b54b65b742b7..de944056b6f1 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/search_service/client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/services/search_service/client.py @@ -206,6 +206,30 @@ def parse_branch_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def experiment_path( + project: str, + location: str, + catalog: str, + experiment: str, + ) -> str: + """Returns a fully-qualified experiment string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/experiments/{experiment}".format( + project=project, + location=location, + catalog=catalog, + experiment=experiment, + ) + + @staticmethod + def parse_experiment_path(path: str) -> Dict[str, str]: + """Parses a experiment path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/experiments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def product_path( project: str, @@ -232,6 +256,30 @@ def parse_product_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def serving_config_path( + project: str, + location: str, + catalog: str, + serving_config: str, + ) -> str: + """Returns a fully-qualified serving_config string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/servingConfigs/{serving_config}".format( + project=project, + location=location, + catalog=catalog, + serving_config=serving_config, + ) + + @staticmethod + def parse_serving_config_path(path: str) -> Dict[str, str]: + """Parses a serving_config path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/servingConfigs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def common_billing_account_path( billing_account: str, diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/__init__.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/__init__.py index e370016a45de..fa3fae0ab578 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/__init__.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/__init__.py @@ -96,11 +96,22 @@ UserEventInlineSource, UserEventInputConfig, ) +from .merchant_center_account_link import ( + CreateMerchantCenterAccountLinkMetadata, + MerchantCenterAccountLink, +) +from .merchant_center_account_link_service import ( + CreateMerchantCenterAccountLinkRequest, + DeleteMerchantCenterAccountLinkRequest, + ListMerchantCenterAccountLinksRequest, + ListMerchantCenterAccountLinksResponse, +) from .model import Model from .model_service import ( CreateModelMetadata, CreateModelRequest, DeleteModelRequest, + GetModelRequest, ListModelsRequest, ListModelsResponse, PauseModelRequest, @@ -144,7 +155,7 @@ PurgeUserEventsRequest, PurgeUserEventsResponse, ) -from .search_service import SearchRequest, SearchResponse +from .search_service import ExperimentInfo, SearchRequest, SearchResponse from .serving_config import ServingConfig from .serving_config_service import ( AddControlRequest, @@ -238,10 +249,17 @@ "UserEventImportSummary", "UserEventInlineSource", "UserEventInputConfig", + "CreateMerchantCenterAccountLinkMetadata", + "MerchantCenterAccountLink", + "CreateMerchantCenterAccountLinkRequest", + "DeleteMerchantCenterAccountLinkRequest", + "ListMerchantCenterAccountLinksRequest", + "ListMerchantCenterAccountLinksResponse", "Model", "CreateModelMetadata", "CreateModelRequest", "DeleteModelRequest", + "GetModelRequest", "ListModelsRequest", "ListModelsResponse", "PauseModelRequest", @@ -281,6 +299,7 @@ "PurgeProductsResponse", "PurgeUserEventsRequest", "PurgeUserEventsResponse", + "ExperimentInfo", "SearchRequest", "SearchResponse", "ServingConfig", diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/catalog.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/catalog.py index a7358365af48..553be4eab966 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/catalog.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/catalog.py @@ -122,6 +122,11 @@ class CatalogAttribute(proto.Message): example, an attribute named ``attributes.abc_xyz`` can be indexed, but an attribute named ``attributes.abc-xyz`` cannot be indexed. + + If the attribute key starts with ``attributes.``, then the + attribute is a custom attribute. Attributes such as + ``brands``, ``patterns``, and ``title`` are built-in and + called system attributes. in_use (bool): Output only. Indicates whether this attribute has been used by any products. ``True`` if at least one @@ -199,10 +204,13 @@ class CatalogAttribute(proto.Message): If EXACT_SEARCHABLE_ENABLED, attribute values will be exact searchable. This property only applies to textual custom attributes and requires indexable set to enabled to enable - exact-searchable. + exact-searchable. If unset, the server behavior defaults to + [EXACT_SEARCHABLE_DISABLED][google.cloud.retail.v2alpha.CatalogAttribute.ExactSearchableOption.EXACT_SEARCHABLE_DISABLED]. retrievable_option (google.cloud.retail_v2alpha.types.CatalogAttribute.RetrievableOption): If RETRIEVABLE_ENABLED, attribute values are retrievable in - the search results. + the search results. If unset, the server behavior defaults + to + [RETRIEVABLE_DISABLED][google.cloud.retail.v2alpha.CatalogAttribute.RetrievableOption.RETRIEVABLE_DISABLED]. """ class AttributeType(proto.Enum): @@ -277,8 +285,7 @@ class ExactSearchableOption(proto.Enum): Values: EXACT_SEARCHABLE_OPTION_UNSPECIFIED (0): - Value used when unset. Defaults to - [EXACT_SEARCHABLE_DISABLED][google.cloud.retail.v2alpha.CatalogAttribute.ExactSearchableOption.EXACT_SEARCHABLE_DISABLED]. + Value used when unset. EXACT_SEARCHABLE_ENABLED (1): Exact searchable option enabled for an attribute. @@ -295,8 +302,7 @@ class RetrievableOption(proto.Enum): Values: RETRIEVABLE_OPTION_UNSPECIFIED (0): - Value used when unset. Defaults to - [RETRIEVABLE_DISABLED][google.cloud.retail.v2alpha.CatalogAttribute.RetrievableOption.RETRIEVABLE_DISABLED]. + Value used when unset. RETRIEVABLE_ENABLED (1): Retrievable option enabled for an attribute. RETRIEVABLE_DISABLED (2): diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/common.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/common.py index 411598523f0a..f4f4f93009ed 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/common.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/common.py @@ -623,7 +623,7 @@ class ColorInfo(proto.Message): only 1 color. May consider using single "Mixed" instead of multiple values. - A maximum of 25 colors are allowed. Each value must be a + A maximum of 75 colors are allowed. Each value must be a UTF-8 encoded string with a length limit of 128 characters. Otherwise, an INVALID_ARGUMENT error is returned. diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/completion_service.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/completion_service.py index 5e1d8909a75c..ad996399dc34 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/completion_service.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/completion_service.py @@ -19,7 +19,7 @@ import proto # type: ignore -from google.cloud.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import common, search_service __protobuf__ = proto.module( package="google.cloud.retail.v2alpha", @@ -31,7 +31,7 @@ class CompleteQueryRequest(proto.Message): - r"""Auto-complete parameters. + r"""Autocomplete parameters. Attributes: catalog (str): @@ -111,6 +111,14 @@ class CompleteQueryRequest(proto.Message): and provided in response. This field is only available for "cloud-retail" dataset. + entity (str): + The entity for customers that may run multiple different + entities, domains, sites or regions, for example, + ``Google US``, ``Google Ads``, ``Waymo``, ``google.com``, + ``youtube.com``, etc. If this is set, it should be exactly + matched with + [UserEvent.entity][google.cloud.retail.v2alpha.UserEvent.entity] + to get per-entity autocomplete results. """ catalog: str = proto.Field( @@ -145,10 +153,14 @@ class CompleteQueryRequest(proto.Message): proto.BOOL, number=9, ) + entity: str = proto.Field( + proto.STRING, + number=10, + ) class CompleteQueryResponse(proto.Message): - r"""Response of the auto-complete query. + r"""Response of the autocomplete query. Attributes: completion_results (MutableSequence[google.cloud.retail_v2alpha.types.CompleteQueryResponse.CompletionResult]): @@ -211,6 +223,19 @@ class CompletionResult(proto.Message): generated by Cloud Retail. It requires [UserEvent.product_details][google.cloud.retail.v2alpha.UserEvent.product_details] is imported properly. + facets (MutableSequence[google.cloud.retail_v2alpha.types.SearchResponse.Facet]): + Facet information for the suggestion term. + Gives the number of items resulting from a + search with this suggestion term for each facet. + This is an experimental feature for limited + customers. Please reach out to the support team + if you would like to receive this information. + total_product_count (int): + Total number of products associated with a + search with this suggestion. + This is an experimental feature for limited + customers. Please reach out to the support team + if you would like to receive this information. """ suggestion: str = proto.Field( @@ -223,6 +248,17 @@ class CompletionResult(proto.Message): number=2, message=common.CustomAttribute, ) + facets: MutableSequence[ + search_service.SearchResponse.Facet + ] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=search_service.SearchResponse.Facet, + ) + total_product_count: int = proto.Field( + proto.INT32, + number=4, + ) class RecentSearchResult(proto.Message): r"""Recent search of this user. diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/import_config.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/import_config.py index e7d72298baa0..b88c3e45106c 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/import_config.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/import_config.py @@ -161,7 +161,7 @@ class BigQuerySource(proto.Message): - ``user_event_ga4``: The schema is available here: https://support.google.com/analytics/answer/7029846. - Supported values for auto-completion imports: + Supported values for autocomplete imports: - ``suggestions`` (default): One JSON completion suggestion per line. diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/merchant_center_account_link.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/merchant_center_account_link.py new file mode 100644 index 000000000000..7c5bb3be471a --- /dev/null +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/merchant_center_account_link.py @@ -0,0 +1,193 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import timestamp_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.retail.v2alpha", + manifest={ + "MerchantCenterAccountLink", + "CreateMerchantCenterAccountLinkMetadata", + }, +) + + +class MerchantCenterAccountLink(proto.Message): + r"""Represents a link between a Merchant Center account and a + branch. Once a link is established, products from the linked + merchant center account will be streamed to the linked branch. + + Attributes: + name (str): + Output only. Immutable. Full resource name of the Merchant + Center Account Link, such as + ``projects/*/locations/global/catalogs/default_catalog/merchantCenterAccountLinks/merchant_center_account_link``. + id (str): + Output only. Immutable. + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink] + identifier, which is the final component of + [name][google.cloud.retail.v2alpha.MerchantCenterAccountLink.name]. + This field is auto generated and follows the convention: + ``BranchId_MerchantCenterAccountId``. + ``projects/*/locations/global/catalogs/default_catalog/merchantCenterAccountLinks/id_1``. + merchant_center_account_id (int): + Required. The linked `Merchant center account + id `__. + The account must be a standalone account or a sub-account of + a MCA. + branch_id (str): + Required. The branch id (e.g. 0/1/2) within the catalog that + products from merchant_center_account_id are streamed to. + When updating this field, an empty value will use the + currently configured default branch. However, changing the + default branch later on won't change the linked branch here. + + A single branch id can only have one linked merchant center + account id. + feed_label (str): + The FeedLabel used to perform filtering. Note: this replaces + `region_id `__. + + Example value: ``US``. Example value: ``FeedLabel1``. + language_code (str): + Language of the title/description and other string + attributes. Use language tags defined by `BCP + 47 `__. ISO + 639-1. + + This specifies the language of offers in Merchant Center + that will be accepted. If empty, no language filtering will + be performed. + + Example value: ``en``. + feed_filters (MutableSequence[google.cloud.retail_v2alpha.types.MerchantCenterAccountLink.MerchantCenterFeedFilter]): + Criteria for the Merchant Center feeds to be + ingested via the link. All offers will be + ingested if the list is empty. Otherwise the + offers will be ingested from selected feeds. + state (google.cloud.retail_v2alpha.types.MerchantCenterAccountLink.State): + Output only. Represents the state of the + link. + project_id (str): + Output only. GCP project ID. + """ + + class State(proto.Enum): + r"""The state of the link. + + Values: + STATE_UNSPECIFIED (0): + Default value. + PENDING (1): + Link is created and LRO is not complete. + ACTIVE (2): + Link is active. + FAILED (3): + Link creation failed. + """ + STATE_UNSPECIFIED = 0 + PENDING = 1 + ACTIVE = 2 + FAILED = 3 + + class MerchantCenterFeedFilter(proto.Message): + r"""Merchant Center Feed filter criterion. + + Attributes: + primary_feed_id (int): + Merchant Center primary feed ID. + primary_feed_name (str): + Merchant Center primary feed name. The name + is used for the display purposes only. + """ + + primary_feed_id: int = proto.Field( + proto.INT64, + number=1, + ) + primary_feed_name: str = proto.Field( + proto.STRING, + number=2, + ) + + name: str = proto.Field( + proto.STRING, + number=1, + ) + id: str = proto.Field( + proto.STRING, + number=8, + ) + merchant_center_account_id: int = proto.Field( + proto.INT64, + number=2, + ) + branch_id: str = proto.Field( + proto.STRING, + number=3, + ) + feed_label: str = proto.Field( + proto.STRING, + number=4, + ) + language_code: str = proto.Field( + proto.STRING, + number=5, + ) + feed_filters: MutableSequence[MerchantCenterFeedFilter] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message=MerchantCenterFeedFilter, + ) + state: State = proto.Field( + proto.ENUM, + number=7, + enum=State, + ) + project_id: str = proto.Field( + proto.STRING, + number=9, + ) + + +class CreateMerchantCenterAccountLinkMetadata(proto.Message): + r"""Common metadata related to the progress of the operations. + + Attributes: + create_time (google.protobuf.timestamp_pb2.Timestamp): + Operation create time. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Operation last update time. If the operation + is done, this is also the finish time. + """ + + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/merchant_center_account_link_service.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/merchant_center_account_link_service.py new file mode 100644 index 000000000000..8cc2ca433a2d --- /dev/null +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/merchant_center_account_link_service.py @@ -0,0 +1,123 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.retail_v2alpha.types import ( + merchant_center_account_link as gcr_merchant_center_account_link, +) + +__protobuf__ = proto.module( + package="google.cloud.retail.v2alpha", + manifest={ + "ListMerchantCenterAccountLinksRequest", + "ListMerchantCenterAccountLinksResponse", + "CreateMerchantCenterAccountLinkRequest", + "DeleteMerchantCenterAccountLinkRequest", + }, +) + + +class ListMerchantCenterAccountLinksRequest(proto.Message): + r"""Request for + [MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks] + method. + + Attributes: + parent (str): + Required. The parent Catalog of the resource. It must match + this format: + projects/{PROJECT_NUMBER}/locations/global/catalogs/{CATALOG_ID} + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListMerchantCenterAccountLinksResponse(proto.Message): + r"""Response for + [MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks] + method. + + Attributes: + merchant_center_account_links (MutableSequence[google.cloud.retail_v2alpha.types.MerchantCenterAccountLink]): + The links. + """ + + merchant_center_account_links: MutableSequence[ + gcr_merchant_center_account_link.MerchantCenterAccountLink + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcr_merchant_center_account_link.MerchantCenterAccountLink, + ) + + +class CreateMerchantCenterAccountLinkRequest(proto.Message): + r"""Request for + [MerchantCenterAccountLinkService.CreateMerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.CreateMerchantCenterAccountLink] + method. + + Attributes: + parent (str): + Required. The branch resource where this + MerchantCenterAccountLink will be created. Format: + projects/{PROJECT_NUMBER}/locations/global/catalogs/{CATALOG_ID}} + merchant_center_account_link (google.cloud.retail_v2alpha.types.MerchantCenterAccountLink): + Required. The + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink] + to create. + + If the caller does not have permission to create the + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink], + regardless of whether or not it exists, a PERMISSION_DENIED + error is returned. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + merchant_center_account_link: gcr_merchant_center_account_link.MerchantCenterAccountLink = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_merchant_center_account_link.MerchantCenterAccountLink, + ) + + +class DeleteMerchantCenterAccountLinkRequest(proto.Message): + r"""Request for + [MerchantCenterAccountLinkService.DeleteMerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.DeleteMerchantCenterAccountLink] + method. + + Attributes: + name (str): + Required. Full resource name. Format: + projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/merchantCenterAccountLinks/{merchant_center_account_link_id} + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/model_service.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/model_service.py index 26eb7e92f241..f26d3631de21 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/model_service.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/model_service.py @@ -27,6 +27,7 @@ manifest={ "CreateModelRequest", "UpdateModelRequest", + "GetModelRequest", "PauseModelRequest", "ResumeModelRequest", "ListModelsRequest", @@ -97,6 +98,22 @@ class UpdateModelRequest(proto.Message): ) +class GetModelRequest(proto.Message): + r"""Request for getting a model. + + Attributes: + name (str): + Required. The resource name of the + [Model][google.cloud.retail.v2alpha.Model] to get. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + class PauseModelRequest(proto.Message): r"""Request for pausing training of a model. diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/prediction_service.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/prediction_service.py index deb5f20756ef..972f88523a2b 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/prediction_service.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/prediction_service.py @@ -119,6 +119,9 @@ class PredictRequest(proto.Message): ANY("Phones")) - (availability: ANY("IN_STOCK")) AND (colors: ANY("Red") OR categories: ANY("Phones")) + + For more information, see `Filter + recommendations `__. validate_only (bool): Use validate only mode for this prediction query. If set to true, a dummy model will be diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/product.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/product.py index 1a1e8f89046a..cfecce928fab 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/product.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/product.py @@ -563,12 +563,11 @@ class Product(proto.Message): Output only. A list of local inventories specific to different places. - This is only available for users who have Retail Search - enabled, and it can be managed by + This field can be managed by [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] and [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] - APIs. + APIs if fine-grained, high-volume updates are necessary. """ class Type(proto.Enum): diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/product_service.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/product_service.py index 1508e6d196a6..d37b06988bc5 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/product_service.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/product_service.py @@ -215,12 +215,26 @@ class DeleteProductRequest(proto.Message): All inventory information for the named [Product][google.cloud.retail.v2alpha.Product] will be deleted. + force (bool): + This value only applies to the case when the + target product is of type PRIMARY. + When deleting a product of VARIANT/COLLECTION + type, this value will be ignored. + When set to true, the subsequent variant + products will be deleted. + When set to false, if the primary product has + active variant products, an error will be + returned. """ name: str = proto.Field( proto.STRING, number=1, ) + force: bool = proto.Field( + proto.BOOL, + number=4, + ) class ListProductsRequest(proto.Message): diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/search_service.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/search_service.py index e666794548ca..a697acff93bf 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/search_service.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/search_service.py @@ -29,6 +29,7 @@ manifest={ "SearchRequest", "SearchResponse", + "ExperimentInfo", }, ) @@ -147,7 +148,7 @@ class SearchRequest(proto.Message): Facet specifications for faceted search. If empty, no facets are returned. - A maximum of 100 values are allowed. Otherwise, an + A maximum of 200 values are allowed. Otherwise, an INVALID_ARGUMENT error is returned. dynamic_facet_spec (google.cloud.retail_v2alpha.types.SearchRequest.DynamicFacetSpec): Deprecated. Refer to @@ -270,9 +271,9 @@ class SearchRequest(proto.Message): If this field is set to an invalid value other than these, an INVALID_ARGUMENT error is returned. page_categories (MutableSequence[str]): - The categories associated with a category page. Required for - category navigation queries to achieve good search quality. - The format should be the same as + The categories associated with a category page. Must be set + for category navigation queries to achieve good search + quality. The format should be the same as [UserEvent.page_categories][google.cloud.retail.v2alpha.UserEvent.page_categories]; To represent full path of category, use '>' sign to separate @@ -326,6 +327,14 @@ class SearchRequest(proto.Message): will take effect. This field is a member of `oneof`_ ``_spell_correction_spec``. + entity (str): + The entity for customers that may run multiple different + entities, domains, sites or regions, for example, + ``Google US``, ``Google Ads``, ``Waymo``, ``google.com``, + ``youtube.com``, etc. If this is set, it should be exactly + matched with + [UserEvent.entity][google.cloud.retail.v2alpha.UserEvent.entity] + to get search results boosted by entity. """ class RelevanceThreshold(proto.Enum): @@ -529,7 +538,19 @@ class FacetKey(proto.Message): Set only if values should be bucketized into intervals. Must be set for facets with numerical values. Must not be set for facet with text - values. Maximum number of intervals is 30. + values. Maximum number of intervals is 40. + + For all numerical facet keys that appear in the + list of products from the catalog, the + percentiles 0, 10, 30, 50, 70, 90 and 100 are + computed from their distribution weekly. If the + model assigns a high score to a numerical facet + key and its intervals are not specified in the + search request, these percentiles will become + the bounds for its intervals and will be + returned in the response. If the facet key + intervals are specified in the request, then the + specified intervals will be returned instead. restricted_values (MutableSequence[str]): Only get facet for the given restricted values. For example, when using "pickupInStore" as key and set restricted values @@ -1021,6 +1042,10 @@ class Mode(proto.Enum): optional=True, message=SpellCorrectionSpec, ) + entity: str = proto.Field( + proto.STRING, + number=38, + ) class SearchResponse(proto.Message): @@ -1073,6 +1098,11 @@ class SearchResponse(proto.Message): The invalid [SearchRequest.BoostSpec.condition_boost_specs][google.cloud.retail.v2alpha.SearchRequest.BoostSpec.condition_boost_specs] that are not applied during serving. + experiment_info (MutableSequence[google.cloud.retail_v2alpha.types.ExperimentInfo]): + Metadata related to A/B testing + [Experiment][google.cloud.retail.v2alpha.Experiment] + associated with this response. Only exists when an + experiment is triggered. """ class SearchResult(proto.Message): @@ -1371,6 +1401,67 @@ def raw_page(self): number=14, message="SearchRequest.BoostSpec.ConditionBoostSpec", ) + experiment_info: MutableSequence["ExperimentInfo"] = proto.RepeatedField( + proto.MESSAGE, + number=17, + message="ExperimentInfo", + ) + + +class ExperimentInfo(proto.Message): + r"""Metadata for active A/B testing [Experiments][]. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + serving_config_experiment (google.cloud.retail_v2alpha.types.ExperimentInfo.ServingConfigExperiment): + A/B test between existing Cloud Retail Search + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig]s. + + This field is a member of `oneof`_ ``experiment_metadata``. + experiment (str): + The fully qualified resource name of the experiment that + provides the serving config under test, should an active + experiment exist. For example: + ``projects/*/locations/global/catalogs/default_catalog/experiments/experiment_id`` + """ + + class ServingConfigExperiment(proto.Message): + r"""Metadata for active serving config A/B tests. + + Attributes: + original_serving_config (str): + The fully qualified resource name of the original + [SearchRequest.placement][google.cloud.retail.v2alpha.SearchRequest.placement] + in the search request prior to reassignment by experiment + API. For example: + ``projects/*/locations/*/catalogs/*/servingConfigs/*``. + experiment_serving_config (str): + The fully qualified resource name of the serving config + [VariantArm.serving_config_id][] responsible for generating + the search response. For example: + ``projects/*/locations/*/catalogs/*/servingConfigs/*``. + """ + + original_serving_config: str = proto.Field( + proto.STRING, + number=1, + ) + experiment_serving_config: str = proto.Field( + proto.STRING, + number=2, + ) + + serving_config_experiment: ServingConfigExperiment = proto.Field( + proto.MESSAGE, + number=2, + oneof="experiment_metadata", + message=ServingConfigExperiment, + ) + experiment: str = proto.Field( + proto.STRING, + number=1, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/serving_config.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/serving_config.py index 9f64a4e5ed3b..5e68369e8e87 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/serving_config.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/serving_config.py @@ -65,7 +65,7 @@ class ServingConfig(proto.Message): click-through and conversion rates. Allowed values are: - ``no-price-reranking`` - - ``low-price-raranking`` + - ``low-price-reranking`` - ``medium-price-reranking`` - ``high-price-reranking`` @@ -212,8 +212,9 @@ class ServingConfig(proto.Message): is [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_RECOMMENDATION]. diversity_type (google.cloud.retail_v2alpha.types.ServingConfig.DiversityType): - What kind of diversity to use - data driven - or rule based. + What kind of diversity to use - data driven or rule based. + If unset, the server behavior defaults to + [RULE_BASED_DIVERSITY][google.cloud.retail.v2alpha.ServingConfig.DiversityType.RULE_BASED_DIVERSITY]. enable_category_filter_level (str): Whether to add additional category filters on the ``similar-items`` model. If not specified, we enable it by @@ -259,7 +260,6 @@ class ServingConfig(proto.Message): class DiversityType(proto.Enum): r"""What type of diversity - data or rule based. - If none is specified, default to rule based. Values: DIVERSITY_TYPE_UNSPECIFIED (0): diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/user_event.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/user_event.py index cc9a29c79198..9158b8278e1a 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/user_event.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/user_event.py @@ -290,6 +290,13 @@ class UserEvent(proto.Message): When using the client side event reporting with JavaScript pixel and Google Tag Manager, this value is filled in automatically. + entity (str): + The entity for customers that may run multiple different + entities, domains, sites or regions, for example, + ``Google US``, ``Google Ads``, ``Waymo``, ``google.com``, + ``youtube.com``, etc. It is recommended to set this field to + get better per-entity search, completion and prediction + results. """ event_type: str = proto.Field( @@ -379,6 +386,10 @@ class UserEvent(proto.Message): proto.STRING, number=15, ) + entity: str = proto.Field( + proto.STRING, + number=23, + ) class ProductDetail(proto.Message): diff --git a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/user_event_service.py b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/user_event_service.py index 5b8acfdaa220..01b95f89694a 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/user_event_service.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2alpha/types/user_event_service.py @@ -74,7 +74,8 @@ class CollectUserEventRequest(proto.Message): Attributes: prebuilt_rule (str): The prebuilt rule name that can convert a specific type of - raw_json. For example: "default_schema/v1.0". + raw_json. For example: "ga4_bq" rule for the GA4 user event + schema. This field is a member of `oneof`_ ``conversion_rule``. parent (str): diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/__init__.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/__init__.py index b91f7f986c41..83b3e6693154 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/__init__.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/__init__.py @@ -126,6 +126,7 @@ CreateModelMetadata, CreateModelRequest, DeleteModelRequest, + GetModelRequest, ListModelsRequest, ListModelsResponse, PauseModelRequest, @@ -166,7 +167,7 @@ PurgeUserEventsRequest, PurgeUserEventsResponse, ) -from .types.search_service import SearchRequest, SearchResponse +from .types.search_service import ExperimentInfo, SearchRequest, SearchResponse from .types.serving_config import ServingConfig from .types.serving_config_service import ( AddControlRequest, @@ -241,6 +242,7 @@ "DeleteModelRequest", "DeleteProductRequest", "DeleteServingConfigRequest", + "ExperimentInfo", "ExportErrorsConfig", "ExportMetadata", "ExportProductsResponse", @@ -253,6 +255,7 @@ "GetControlRequest", "GetDefaultBranchRequest", "GetDefaultBranchResponse", + "GetModelRequest", "GetProductRequest", "GetServingConfigRequest", "Image", diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/gapic_metadata.json b/packages/google-cloud-retail/google/cloud/retail_v2beta/gapic_metadata.json index e0452f244835..657890025fc8 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/gapic_metadata.json +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/gapic_metadata.json @@ -362,6 +362,11 @@ "delete_model" ] }, + "GetModel": { + "methods": [ + "get_model" + ] + }, "ListModels": { "methods": [ "list_models" @@ -402,6 +407,11 @@ "delete_model" ] }, + "GetModel": { + "methods": [ + "get_model" + ] + }, "ListModels": { "methods": [ "list_models" @@ -442,6 +452,11 @@ "delete_model" ] }, + "GetModel": { + "methods": [ + "get_model" + ] + }, "ListModels": { "methods": [ "list_models" diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/completion_service/async_client.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/completion_service/async_client.py index c7224bea8dfc..3fc5d4fffc31 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/completion_service/async_client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/completion_service/async_client.py @@ -55,7 +55,7 @@ class CompletionServiceAsyncClient: - """Auto-completion service for retail. + """Autocomplete service for retail. This feature is only available for users who have Retail Search enabled. Enable Retail Search on Cloud Console before using this feature. @@ -265,7 +265,7 @@ async def sample_complete_query(): Args: request (Optional[Union[google.cloud.retail_v2beta.types.CompleteQueryRequest, dict]]): - The request object. Auto-complete parameters. + The request object. Autocomplete parameters. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -274,7 +274,7 @@ async def sample_complete_query(): Returns: google.cloud.retail_v2beta.types.CompleteQueryResponse: - Response of the auto-complete query. + Response of the autocomplete query. """ # Create or coerce a protobuf request object. request = completion_service.CompleteQueryRequest(request) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/completion_service/client.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/completion_service/client.py index d943dc314588..8a4cde6285cf 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/completion_service/client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/completion_service/client.py @@ -97,7 +97,7 @@ def get_transport_class( class CompletionServiceClient(metaclass=CompletionServiceClientMeta): - """Auto-completion service for retail. + """Autocomplete service for retail. This feature is only available for users who have Retail Search enabled. Enable Retail Search on Cloud Console before using this feature. @@ -494,7 +494,7 @@ def sample_complete_query(): Args: request (Union[google.cloud.retail_v2beta.types.CompleteQueryRequest, dict]): - The request object. Auto-complete parameters. + The request object. Autocomplete parameters. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -503,7 +503,7 @@ def sample_complete_query(): Returns: google.cloud.retail_v2beta.types.CompleteQueryResponse: - Response of the auto-complete query. + Response of the autocomplete query. """ # Create or coerce a protobuf request object. # Minor optimization to avoid making a copy if the user passes diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/completion_service/transports/grpc.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/completion_service/transports/grpc.py index fdddef654720..018b55172502 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/completion_service/transports/grpc.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/completion_service/transports/grpc.py @@ -32,7 +32,7 @@ class CompletionServiceGrpcTransport(CompletionServiceTransport): """gRPC backend transport for CompletionService. - Auto-completion service for retail. + Autocomplete service for retail. This feature is only available for users who have Retail Search enabled. Enable Retail Search on Cloud Console before using this feature. diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/completion_service/transports/grpc_asyncio.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/completion_service/transports/grpc_asyncio.py index cf2c44c59a96..214f67b1af7f 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/completion_service/transports/grpc_asyncio.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/completion_service/transports/grpc_asyncio.py @@ -33,7 +33,7 @@ class CompletionServiceGrpcAsyncIOTransport(CompletionServiceTransport): """gRPC AsyncIO backend transport for CompletionService. - Auto-completion service for retail. + Autocomplete service for retail. This feature is only available for users who have Retail Search enabled. Enable Retail Search on Cloud Console before using this feature. diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/completion_service/transports/rest.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/completion_service/transports/rest.py index 16fd0deb87a5..648c1c22d270 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/completion_service/transports/rest.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/completion_service/transports/rest.py @@ -198,7 +198,7 @@ class CompletionServiceRestStub: class CompletionServiceRestTransport(CompletionServiceTransport): """REST backend transport for CompletionService. - Auto-completion service for retail. + Autocomplete service for retail. This feature is only available for users who have Retail Search enabled. Enable Retail Search on Cloud Console before using this feature. @@ -376,7 +376,7 @@ def __call__( Args: request (~.completion_service.CompleteQueryRequest): - The request object. Auto-complete parameters. + The request object. Autocomplete parameters. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -385,7 +385,7 @@ def __call__( Returns: ~.completion_service.CompleteQueryResponse: - Response of the auto-complete query. + Response of the autocomplete query. """ http_options: List[Dict[str, str]] = [ diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/async_client.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/async_client.py index c7b3867a76c4..98ff5a8898a1 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/async_client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/async_client.py @@ -370,6 +370,113 @@ async def sample_create_model(): # Done; return the response. return response + async def get_model( + self, + request: Optional[Union[model_service.GetModelRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> model.Model: + r"""Gets a model. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2beta + + async def sample_get_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.GetModelRequest( + name="name_value", + ) + + # Make the request + response = await client.get_model(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.GetModelRequest, dict]]): + The request object. Request for getting a model. + name (:class:`str`): + Required. The resource name of the + [Model][google.cloud.retail.v2beta.Model] to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog}/models/{model_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2beta.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2beta.Model]. A + [Model][google.cloud.retail.v2beta.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and then queried through the Predict API. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = model_service.GetModelRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_model, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + async def pause_model( self, request: Optional[Union[model_service.PauseModelRequest, dict]] = None, diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/client.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/client.py index 584be972c17d..fb40447e8a97 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/client.py @@ -623,6 +623,113 @@ def sample_create_model(): # Done; return the response. return response + def get_model( + self, + request: Optional[Union[model_service.GetModelRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> model.Model: + r"""Gets a model. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import retail_v2beta + + def sample_get_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.GetModelRequest( + name="name_value", + ) + + # Make the request + response = client.get_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.GetModelRequest, dict]): + The request object. Request for getting a model. + name (str): + Required. The resource name of the + [Model][google.cloud.retail.v2beta.Model] to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog}/models/{model_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2beta.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2beta.Model]. A + [Model][google.cloud.retail.v2beta.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and then queried through the Predict API. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a model_service.GetModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.GetModelRequest): + request = model_service.GetModelRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_model] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + def pause_model( self, request: Optional[Union[model_service.PauseModelRequest, dict]] = None, diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/transports/base.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/transports/base.py index 0d7b17e86939..44be9f4d5635 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/transports/base.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/transports/base.py @@ -132,6 +132,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.get_model: gapic_v1.method.wrap_method( + self.get_model, + default_timeout=None, + client_info=client_info, + ), self.pause_model: gapic_v1.method.wrap_method( self.pause_model, default_timeout=None, @@ -187,6 +192,14 @@ def create_model( ]: raise NotImplementedError() + @property + def get_model( + self, + ) -> Callable[ + [model_service.GetModelRequest], Union[model.Model, Awaitable[model.Model]] + ]: + raise NotImplementedError() + @property def pause_model( self, diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/transports/grpc.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/transports/grpc.py index 9b06ee53e59c..935de683ed60 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/transports/grpc.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/transports/grpc.py @@ -285,6 +285,30 @@ def create_model( ) return self._stubs["create_model"] + @property + def get_model(self) -> Callable[[model_service.GetModelRequest], model.Model]: + r"""Return a callable for the get model method over gRPC. + + Gets a model. + + Returns: + Callable[[~.GetModelRequest], + ~.Model]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_model" not in self._stubs: + self._stubs["get_model"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2beta.ModelService/GetModel", + request_serializer=model_service.GetModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs["get_model"] + @property def pause_model(self) -> Callable[[model_service.PauseModelRequest], model.Model]: r"""Return a callable for the pause model method over gRPC. diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/transports/grpc_asyncio.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/transports/grpc_asyncio.py index d732d0eb3ebe..b72228493937 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/transports/grpc_asyncio.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/transports/grpc_asyncio.py @@ -292,6 +292,32 @@ def create_model( ) return self._stubs["create_model"] + @property + def get_model( + self, + ) -> Callable[[model_service.GetModelRequest], Awaitable[model.Model]]: + r"""Return a callable for the get model method over gRPC. + + Gets a model. + + Returns: + Callable[[~.GetModelRequest], + Awaitable[~.Model]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_model" not in self._stubs: + self._stubs["get_model"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2beta.ModelService/GetModel", + request_serializer=model_service.GetModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs["get_model"] + @property def pause_model( self, diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/transports/rest.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/transports/rest.py index c6d18a929c36..6910f95de788 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/transports/rest.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/model_service/transports/rest.py @@ -88,6 +88,14 @@ def pre_delete_model(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata + def pre_get_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_model(self, response): + logging.log(f"Received response: {response}") + return response + def pre_list_models(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -169,6 +177,27 @@ def pre_delete_model( """ return request, metadata + def pre_get_model( + self, + request: model_service.GetModelRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[model_service.GetModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_get_model(self, response: model.Model) -> model.Model: + """Post-rpc interceptor for get_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_list_models( self, request: model_service.ListModelsRequest, @@ -663,6 +692,99 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) + class _GetModel(ModelServiceRestStub): + def __hash__(self): + return hash("GetModel") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: model_service.GetModelRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> model.Model: + r"""Call the get model method over HTTP. + + Args: + request (~.model_service.GetModelRequest): + The request object. Request for getting a model. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.model.Model: + Metadata that describes the training and serving + parameters of a + [Model][google.cloud.retail.v2beta.Model]. A + [Model][google.cloud.retail.v2beta.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and then queried through the Predict API. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2beta/{name=projects/*/locations/*/catalogs/*/models/*}", + }, + ] + request, metadata = self._interceptor.pre_get_model(request, metadata) + pb_request = model_service.GetModelRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = model.Model() + pb_resp = model.Model.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_model(resp) + return resp + class _ListModels(ModelServiceRestStub): def __hash__(self): return hash("ListModels") @@ -1174,6 +1296,12 @@ def delete_model( # In C++ this would require a dynamic_cast return self._DeleteModel(self._session, self._host, self._interceptor) # type: ignore + @property + def get_model(self) -> Callable[[model_service.GetModelRequest], model.Model]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetModel(self._session, self._host, self._interceptor) # type: ignore + @property def list_models( self, diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/product_service/async_client.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/product_service/async_client.py index 259344d97749..f7916d29a8e9 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/product_service/async_client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/product_service/async_client.py @@ -1051,10 +1051,6 @@ async def set_inventory( [done][google.longrunning.Operation.done] until they are obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -1257,7 +1253,15 @@ async def add_fulfillment_places( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, str]] = (), ) -> operation_async.AsyncOperation: - r"""Incrementally adds place IDs to + r"""It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally adds place IDs to [Product.fulfillment_info.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids]. This process is asynchronous and does not require the @@ -1281,10 +1285,6 @@ async def add_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -1412,7 +1412,15 @@ async def remove_fulfillment_places( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, str]] = (), ) -> operation_async.AsyncOperation: - r"""Incrementally removes place IDs from a + r"""It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally removes place IDs from a [Product.fulfillment_info.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids]. This process is asynchronous and does not require the @@ -1436,10 +1444,6 @@ async def remove_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -1600,10 +1604,6 @@ async def add_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -1761,10 +1761,6 @@ async def remove_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/product_service/client.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/product_service/client.py index 7e868aa197f6..1dd15a90d688 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/product_service/client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/product_service/client.py @@ -1297,10 +1297,6 @@ def set_inventory( [done][google.longrunning.Operation.done] until they are obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -1503,7 +1499,15 @@ def add_fulfillment_places( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, str]] = (), ) -> operation.Operation: - r"""Incrementally adds place IDs to + r"""It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally adds place IDs to [Product.fulfillment_info.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids]. This process is asynchronous and does not require the @@ -1527,10 +1531,6 @@ def add_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -1658,7 +1658,15 @@ def remove_fulfillment_places( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, str]] = (), ) -> operation.Operation: - r"""Incrementally removes place IDs from a + r"""It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally removes place IDs from a [Product.fulfillment_info.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids]. This process is asynchronous and does not require the @@ -1682,10 +1690,6 @@ def remove_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -1848,10 +1852,6 @@ def add_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a @@ -2009,10 +2009,6 @@ def remove_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - .. code-block:: python # This snippet has been automatically generated and should be regarded as a diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/product_service/transports/grpc.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/product_service/transports/grpc.py index 1c5d250e494b..fcac2bb2019d 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/product_service/transports/grpc.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/product_service/transports/grpc.py @@ -476,10 +476,6 @@ def set_inventory( [done][google.longrunning.Operation.done] until they are obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.SetInventoryRequest], ~.Operation]: @@ -506,6 +502,14 @@ def add_fulfillment_places( ]: r"""Return a callable for the add fulfillment places method over gRPC. + It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + Incrementally adds place IDs to [Product.fulfillment_info.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids]. @@ -530,10 +534,6 @@ def add_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.AddFulfillmentPlacesRequest], ~.Operation]: @@ -560,6 +560,14 @@ def remove_fulfillment_places( ]: r"""Return a callable for the remove fulfillment places method over gRPC. + It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + Incrementally removes place IDs from a [Product.fulfillment_info.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids]. @@ -584,10 +592,6 @@ def remove_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.RemoveFulfillmentPlacesRequest], ~.Operation]: @@ -647,10 +651,6 @@ def add_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.AddLocalInventoriesRequest], ~.Operation]: @@ -707,10 +707,6 @@ def remove_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.RemoveLocalInventoriesRequest], ~.Operation]: diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/product_service/transports/grpc_asyncio.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/product_service/transports/grpc_asyncio.py index 681272392aca..e9d5b9adfd76 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/product_service/transports/grpc_asyncio.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/product_service/transports/grpc_asyncio.py @@ -490,10 +490,6 @@ def set_inventory( [done][google.longrunning.Operation.done] until they are obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.SetInventoryRequest], Awaitable[~.Operation]]: @@ -521,6 +517,14 @@ def add_fulfillment_places( ]: r"""Return a callable for the add fulfillment places method over gRPC. + It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + Incrementally adds place IDs to [Product.fulfillment_info.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids]. @@ -545,10 +549,6 @@ def add_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.AddFulfillmentPlacesRequest], Awaitable[~.Operation]]: @@ -576,6 +576,14 @@ def remove_fulfillment_places( ]: r"""Return a callable for the remove fulfillment places method over gRPC. + It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + Incrementally removes place IDs from a [Product.fulfillment_info.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids]. @@ -600,10 +608,6 @@ def remove_fulfillment_places( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.RemoveFulfillmentPlacesRequest], Awaitable[~.Operation]]: @@ -664,10 +668,6 @@ def add_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.AddLocalInventoriesRequest], Awaitable[~.Operation]]: @@ -725,10 +725,6 @@ def remove_local_inventories( stale updates will not be marked as [done][google.longrunning.Operation.done] until being obsolete. - This feature is only available for users who have Retail Search - enabled. Enable Retail Search on Cloud Console before using this - feature. - Returns: Callable[[~.RemoveLocalInventoriesRequest], Awaitable[~.Operation]]: diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/search_service/async_client.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/search_service/async_client.py index 8e2f9faa7f12..16c4dbd016ec 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/search_service/async_client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/search_service/async_client.py @@ -67,8 +67,14 @@ class SearchServiceAsyncClient: branch_path = staticmethod(SearchServiceClient.branch_path) parse_branch_path = staticmethod(SearchServiceClient.parse_branch_path) + experiment_path = staticmethod(SearchServiceClient.experiment_path) + parse_experiment_path = staticmethod(SearchServiceClient.parse_experiment_path) product_path = staticmethod(SearchServiceClient.product_path) parse_product_path = staticmethod(SearchServiceClient.parse_product_path) + serving_config_path = staticmethod(SearchServiceClient.serving_config_path) + parse_serving_config_path = staticmethod( + SearchServiceClient.parse_serving_config_path + ) common_billing_account_path = staticmethod( SearchServiceClient.common_billing_account_path ) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/search_service/client.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/search_service/client.py index 267dec736e01..4ea443b9d235 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/services/search_service/client.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/services/search_service/client.py @@ -206,6 +206,30 @@ def parse_branch_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def experiment_path( + project: str, + location: str, + catalog: str, + experiment: str, + ) -> str: + """Returns a fully-qualified experiment string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/experiments/{experiment}".format( + project=project, + location=location, + catalog=catalog, + experiment=experiment, + ) + + @staticmethod + def parse_experiment_path(path: str) -> Dict[str, str]: + """Parses a experiment path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/experiments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def product_path( project: str, @@ -232,6 +256,30 @@ def parse_product_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def serving_config_path( + project: str, + location: str, + catalog: str, + serving_config: str, + ) -> str: + """Returns a fully-qualified serving_config string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/servingConfigs/{serving_config}".format( + project=project, + location=location, + catalog=catalog, + serving_config=serving_config, + ) + + @staticmethod + def parse_serving_config_path(path: str) -> Dict[str, str]: + """Parses a serving_config path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/servingConfigs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def common_billing_account_path( billing_account: str, diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/__init__.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/__init__.py index 25c330d49fee..c74ade2eb30c 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/__init__.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/__init__.py @@ -100,6 +100,7 @@ CreateModelMetadata, CreateModelRequest, DeleteModelRequest, + GetModelRequest, ListModelsRequest, ListModelsResponse, PauseModelRequest, @@ -136,7 +137,7 @@ ) from .promotion import Promotion from .purge_config import PurgeMetadata, PurgeUserEventsRequest, PurgeUserEventsResponse -from .search_service import SearchRequest, SearchResponse +from .search_service import ExperimentInfo, SearchRequest, SearchResponse from .serving_config import ServingConfig from .serving_config_service import ( AddControlRequest, @@ -233,6 +234,7 @@ "CreateModelMetadata", "CreateModelRequest", "DeleteModelRequest", + "GetModelRequest", "ListModelsRequest", "ListModelsResponse", "PauseModelRequest", @@ -269,6 +271,7 @@ "PurgeMetadata", "PurgeUserEventsRequest", "PurgeUserEventsResponse", + "ExperimentInfo", "SearchRequest", "SearchResponse", "ServingConfig", diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/catalog.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/catalog.py index 8148f27af9fd..c956e4b7e232 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/catalog.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/catalog.py @@ -122,6 +122,11 @@ class CatalogAttribute(proto.Message): example, an attribute named ``attributes.abc_xyz`` can be indexed, but an attribute named ``attributes.abc-xyz`` cannot be indexed. + + If the attribute key starts with ``attributes.``, then the + attribute is a custom attribute. Attributes such as + ``brands``, ``patterns``, and ``title`` are built-in and + called system attributes. in_use (bool): Output only. Indicates whether this attribute has been used by any products. ``True`` if at least one @@ -198,10 +203,13 @@ class CatalogAttribute(proto.Message): If EXACT_SEARCHABLE_ENABLED, attribute values will be exact searchable. This property only applies to textual custom attributes and requires indexable set to enabled to enable - exact-searchable. + exact-searchable. If unset, the server behavior defaults to + [EXACT_SEARCHABLE_DISABLED][google.cloud.retail.v2beta.CatalogAttribute.ExactSearchableOption.EXACT_SEARCHABLE_DISABLED]. retrievable_option (google.cloud.retail_v2beta.types.CatalogAttribute.RetrievableOption): If RETRIEVABLE_ENABLED, attribute values are retrievable in - the search results. + the search results. If unset, the server behavior defaults + to + [RETRIEVABLE_DISABLED][google.cloud.retail.v2beta.CatalogAttribute.RetrievableOption.RETRIEVABLE_DISABLED]. """ class AttributeType(proto.Enum): @@ -276,8 +284,7 @@ class ExactSearchableOption(proto.Enum): Values: EXACT_SEARCHABLE_OPTION_UNSPECIFIED (0): - Value used when unset. Defaults to - [EXACT_SEARCHABLE_DISABLED][google.cloud.retail.v2beta.CatalogAttribute.ExactSearchableOption.EXACT_SEARCHABLE_DISABLED]. + Value used when unset. EXACT_SEARCHABLE_ENABLED (1): Exact searchable option enabled for an attribute. @@ -294,8 +301,7 @@ class RetrievableOption(proto.Enum): Values: RETRIEVABLE_OPTION_UNSPECIFIED (0): - Value used when unset. Defaults to - [RETRIEVABLE_DISABLED][google.cloud.retail.v2beta.CatalogAttribute.RetrievableOption.RETRIEVABLE_DISABLED]. + Value used when unset. RETRIEVABLE_ENABLED (1): Retrievable option enabled for an attribute. RETRIEVABLE_DISABLED (2): diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/common.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/common.py index 9df28b24bc52..9cec24266b37 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/common.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/common.py @@ -622,7 +622,7 @@ class ColorInfo(proto.Message): only 1 color. May consider using single "Mixed" instead of multiple values. - A maximum of 25 colors are allowed. Each value must be a + A maximum of 75 colors are allowed. Each value must be a UTF-8 encoded string with a length limit of 128 characters. Otherwise, an INVALID_ARGUMENT error is returned. diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/completion_service.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/completion_service.py index 1992206a3c42..fa22bdc9a68f 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/completion_service.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/completion_service.py @@ -31,7 +31,7 @@ class CompleteQueryRequest(proto.Message): - r"""Auto-complete parameters. + r"""Autocomplete parameters. Attributes: catalog (str): @@ -106,6 +106,14 @@ class CompleteQueryRequest(proto.Message): The maximum allowed max suggestions is 20. If it is set higher, it will be capped by 20. + entity (str): + The entity for customers that may run multiple different + entities, domains, sites or regions, for example, + ``Google US``, ``Google Ads``, ``Waymo``, ``google.com``, + ``youtube.com``, etc. If this is set, it should be exactly + matched with + [UserEvent.entity][google.cloud.retail.v2beta.UserEvent.entity] + to get per-entity autocomplete results. """ catalog: str = proto.Field( @@ -136,10 +144,14 @@ class CompleteQueryRequest(proto.Message): proto.INT32, number=5, ) + entity: str = proto.Field( + proto.STRING, + number=10, + ) class CompleteQueryResponse(proto.Message): - r"""Response of the auto-complete query. + r"""Response of the autocomplete query. Attributes: completion_results (MutableSequence[google.cloud.retail_v2beta.types.CompleteQueryResponse.CompletionResult]): diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/import_config.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/import_config.py index d9fc702e38e8..005edf7068ff 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/import_config.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/import_config.py @@ -160,7 +160,7 @@ class BigQuerySource(proto.Message): - ``user_event_ga4``: The schema is available here: https://support.google.com/analytics/answer/7029846. - Supported values for auto-completion imports: + Supported values for autocomplete imports: - ``suggestions`` (default): One JSON completion suggestion per line. diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/model_service.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/model_service.py index f7fe2cae7145..b636b5581c00 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/model_service.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/model_service.py @@ -27,6 +27,7 @@ manifest={ "CreateModelRequest", "UpdateModelRequest", + "GetModelRequest", "PauseModelRequest", "ResumeModelRequest", "ListModelsRequest", @@ -97,6 +98,22 @@ class UpdateModelRequest(proto.Message): ) +class GetModelRequest(proto.Message): + r"""Request for getting a model. + + Attributes: + name (str): + Required. The resource name of the + [Model][google.cloud.retail.v2beta.Model] to get. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + class PauseModelRequest(proto.Message): r"""Request for pausing training of a model. diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/prediction_service.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/prediction_service.py index 5a86f6c68a5d..7e79c1d25b81 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/prediction_service.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/prediction_service.py @@ -119,6 +119,9 @@ class PredictRequest(proto.Message): ANY("Phones")) - (availability: ANY("IN_STOCK")) AND (colors: ANY("Red") OR categories: ANY("Phones")) + + For more information, see `Filter + recommendations `__. validate_only (bool): Use validate only mode for this prediction query. If set to true, a dummy model will be diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/product.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/product.py index 74e2f9edd209..7effba3c66a0 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/product.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/product.py @@ -563,12 +563,11 @@ class Product(proto.Message): Output only. A list of local inventories specific to different places. - This is only available for users who have Retail Search - enabled, and it can be managed by + This field can be managed by [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] and [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] - APIs. + APIs if fine-grained, high-volume updates are necessary. """ class Type(proto.Enum): diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/search_service.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/search_service.py index 1d417657e466..72fdaa63d068 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/search_service.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/search_service.py @@ -29,6 +29,7 @@ manifest={ "SearchRequest", "SearchResponse", + "ExperimentInfo", }, ) @@ -147,7 +148,7 @@ class SearchRequest(proto.Message): Facet specifications for faceted search. If empty, no facets are returned. - A maximum of 100 values are allowed. Otherwise, an + A maximum of 200 values are allowed. Otherwise, an INVALID_ARGUMENT error is returned. dynamic_facet_spec (google.cloud.retail_v2beta.types.SearchRequest.DynamicFacetSpec): Deprecated. Refer to @@ -261,9 +262,9 @@ class SearchRequest(proto.Message): If this field is set to an invalid value other than these, an INVALID_ARGUMENT error is returned. page_categories (MutableSequence[str]): - The categories associated with a category page. Required for - category navigation queries to achieve good search quality. - The format should be the same as + The categories associated with a category page. Must be set + for category navigation queries to achieve good search + quality. The format should be the same as [UserEvent.page_categories][google.cloud.retail.v2beta.UserEvent.page_categories]; To represent full path of category, use '>' sign to separate @@ -317,6 +318,14 @@ class SearchRequest(proto.Message): will take effect. This field is a member of `oneof`_ ``_spell_correction_spec``. + entity (str): + The entity for customers that may run multiple different + entities, domains, sites or regions, for example, + ``Google US``, ``Google Ads``, ``Waymo``, ``google.com``, + ``youtube.com``, etc. If this is set, it should be exactly + matched with + [UserEvent.entity][google.cloud.retail.v2beta.UserEvent.entity] + to get search results boosted by entity. """ class SearchMode(proto.Enum): @@ -496,7 +505,19 @@ class FacetKey(proto.Message): Set only if values should be bucketized into intervals. Must be set for facets with numerical values. Must not be set for facet with text - values. Maximum number of intervals is 30. + values. Maximum number of intervals is 40. + + For all numerical facet keys that appear in the + list of products from the catalog, the + percentiles 0, 10, 30, 50, 70, 90 and 100 are + computed from their distribution weekly. If the + model assigns a high score to a numerical facet + key and its intervals are not specified in the + search request, these percentiles will become + the bounds for its intervals and will be + returned in the response. If the facet key + intervals are specified in the request, then the + specified intervals will be returned instead. restricted_values (MutableSequence[str]): Only get facet for the given restricted values. For example, when using "pickupInStore" as key and set restricted values @@ -983,6 +1004,10 @@ class Mode(proto.Enum): optional=True, message=SpellCorrectionSpec, ) + entity: str = proto.Field( + proto.STRING, + number=38, + ) class SearchResponse(proto.Message): @@ -1035,6 +1060,10 @@ class SearchResponse(proto.Message): The invalid [SearchRequest.BoostSpec.condition_boost_specs][google.cloud.retail.v2beta.SearchRequest.BoostSpec.condition_boost_specs] that are not applied during serving. + experiment_info (MutableSequence[google.cloud.retail_v2beta.types.ExperimentInfo]): + Metadata related to A/B testing [Experiment][] associated + with this response. Only exists when an experiment is + triggered. """ class SearchResult(proto.Message): @@ -1333,6 +1362,67 @@ def raw_page(self): number=14, message="SearchRequest.BoostSpec.ConditionBoostSpec", ) + experiment_info: MutableSequence["ExperimentInfo"] = proto.RepeatedField( + proto.MESSAGE, + number=17, + message="ExperimentInfo", + ) + + +class ExperimentInfo(proto.Message): + r"""Metadata for active A/B testing [Experiments][]. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + serving_config_experiment (google.cloud.retail_v2beta.types.ExperimentInfo.ServingConfigExperiment): + A/B test between existing Cloud Retail Search + [ServingConfig][google.cloud.retail.v2beta.ServingConfig]s. + + This field is a member of `oneof`_ ``experiment_metadata``. + experiment (str): + The fully qualified resource name of the experiment that + provides the serving config under test, should an active + experiment exist. For example: + ``projects/*/locations/global/catalogs/default_catalog/experiments/experiment_id`` + """ + + class ServingConfigExperiment(proto.Message): + r"""Metadata for active serving config A/B tests. + + Attributes: + original_serving_config (str): + The fully qualified resource name of the original + [SearchRequest.placement][google.cloud.retail.v2beta.SearchRequest.placement] + in the search request prior to reassignment by experiment + API. For example: + ``projects/*/locations/*/catalogs/*/servingConfigs/*``. + experiment_serving_config (str): + The fully qualified resource name of the serving config + [VariantArm.serving_config_id][] responsible for generating + the search response. For example: + ``projects/*/locations/*/catalogs/*/servingConfigs/*``. + """ + + original_serving_config: str = proto.Field( + proto.STRING, + number=1, + ) + experiment_serving_config: str = proto.Field( + proto.STRING, + number=2, + ) + + serving_config_experiment: ServingConfigExperiment = proto.Field( + proto.MESSAGE, + number=2, + oneof="experiment_metadata", + message=ServingConfigExperiment, + ) + experiment: str = proto.Field( + proto.STRING, + number=1, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/serving_config.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/serving_config.py index 081dca99e057..1854f08ea66f 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/serving_config.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/serving_config.py @@ -65,7 +65,7 @@ class ServingConfig(proto.Message): click-through and conversion rates. Allowed values are: - ``no-price-reranking`` - - ``low-price-raranking`` + - ``low-price-reranking`` - ``medium-price-reranking`` - ``high-price-reranking`` @@ -212,8 +212,9 @@ class ServingConfig(proto.Message): is [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_RECOMMENDATION]. diversity_type (google.cloud.retail_v2beta.types.ServingConfig.DiversityType): - What kind of diversity to use - data driven - or rule based. + What kind of diversity to use - data driven or rule based. + If unset, the server behavior defaults to + [RULE_BASED_DIVERSITY][google.cloud.retail.v2beta.ServingConfig.DiversityType.RULE_BASED_DIVERSITY]. enable_category_filter_level (str): Whether to add additional category filters on the ``similar-items`` model. If not specified, we enable it by @@ -259,7 +260,6 @@ class ServingConfig(proto.Message): class DiversityType(proto.Enum): r"""What type of diversity - data or rule based. - If none is specified, default to rule based. Values: DIVERSITY_TYPE_UNSPECIFIED (0): diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/user_event.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/user_event.py index fddeb328f3ca..f9161adaeafb 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/user_event.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/user_event.py @@ -290,6 +290,13 @@ class UserEvent(proto.Message): When using the client side event reporting with JavaScript pixel and Google Tag Manager, this value is filled in automatically. + entity (str): + The entity for customers that may run multiple different + entities, domains, sites or regions, for example, + ``Google US``, ``Google Ads``, ``Waymo``, ``google.com``, + ``youtube.com``, etc. It is recommended to set this field to + get better per-entity search, completion and prediction + results. """ event_type: str = proto.Field( @@ -379,6 +386,10 @@ class UserEvent(proto.Message): proto.STRING, number=15, ) + entity: str = proto.Field( + proto.STRING, + number=23, + ) class ProductDetail(proto.Message): diff --git a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/user_event_service.py b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/user_event_service.py index 4e707dcd467b..dbba34112861 100644 --- a/packages/google-cloud-retail/google/cloud/retail_v2beta/types/user_event_service.py +++ b/packages/google-cloud-retail/google/cloud/retail_v2beta/types/user_event_service.py @@ -74,7 +74,8 @@ class CollectUserEventRequest(proto.Message): Attributes: prebuilt_rule (str): The prebuilt rule name that can convert a specific type of - raw_json. For example: "default_schema/v1.0". + raw_json. For example: "ga4_bq" rule for the GA4 user event + schema. This field is a member of `oneof`_ ``conversion_rule``. parent (str): diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_create_model_async.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_create_model_async.py new file mode 100644 index 000000000000..4789c87449df --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_create_model_async.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateModel +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2_generated_ModelService_CreateModel_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2 + + +async def sample_create_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + model = retail_v2.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2.CreateModelRequest( + parent="parent_value", + model=model, + ) + + # Make the request + operation = client.create_model(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_CreateModel_async] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_create_model_sync.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_create_model_sync.py new file mode 100644 index 000000000000..2032fe66c1ad --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_create_model_sync.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateModel +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2_generated_ModelService_CreateModel_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2 + + +def sample_create_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + model = retail_v2.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2.CreateModelRequest( + parent="parent_value", + model=model, + ) + + # Make the request + operation = client.create_model(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_CreateModel_sync] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_delete_model_async.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_delete_model_async.py new file mode 100644 index 000000000000..cb0e1fdda41f --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_delete_model_async.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteModel +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2_generated_ModelService_DeleteModel_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2 + + +async def sample_delete_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.DeleteModelRequest( + name="name_value", + ) + + # Make the request + await client.delete_model(request=request) + + +# [END retail_v2_generated_ModelService_DeleteModel_async] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_delete_model_sync.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_delete_model_sync.py new file mode 100644 index 000000000000..1a2033cc1445 --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_delete_model_sync.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteModel +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2_generated_ModelService_DeleteModel_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2 + + +def sample_delete_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.DeleteModelRequest( + name="name_value", + ) + + # Make the request + client.delete_model(request=request) + + +# [END retail_v2_generated_ModelService_DeleteModel_sync] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_get_model_async.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_get_model_async.py new file mode 100644 index 000000000000..099770227698 --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_get_model_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetModel +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2_generated_ModelService_GetModel_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2 + + +async def sample_get_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.GetModelRequest( + name="name_value", + ) + + # Make the request + response = await client.get_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_GetModel_async] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_get_model_sync.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_get_model_sync.py new file mode 100644 index 000000000000..783b1768243b --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_get_model_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetModel +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2_generated_ModelService_GetModel_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2 + + +def sample_get_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.GetModelRequest( + name="name_value", + ) + + # Make the request + response = client.get_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_GetModel_sync] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_list_models_async.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_list_models_async.py new file mode 100644 index 000000000000..b38c2703ea8f --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_list_models_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListModels +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2_generated_ModelService_ListModels_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2 + + +async def sample_list_models(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.ListModelsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_models(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END retail_v2_generated_ModelService_ListModels_async] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_list_models_sync.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_list_models_sync.py new file mode 100644 index 000000000000..0cde9e192312 --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_list_models_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListModels +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2_generated_ModelService_ListModels_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2 + + +def sample_list_models(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.ListModelsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_models(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END retail_v2_generated_ModelService_ListModels_sync] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_pause_model_async.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_pause_model_async.py new file mode 100644 index 000000000000..dd9d4c71bada --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_pause_model_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for PauseModel +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2_generated_ModelService_PauseModel_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2 + + +async def sample_pause_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.PauseModelRequest( + name="name_value", + ) + + # Make the request + response = await client.pause_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_PauseModel_async] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_pause_model_sync.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_pause_model_sync.py new file mode 100644 index 000000000000..737410c07959 --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_pause_model_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for PauseModel +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2_generated_ModelService_PauseModel_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2 + + +def sample_pause_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.PauseModelRequest( + name="name_value", + ) + + # Make the request + response = client.pause_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_PauseModel_sync] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_resume_model_async.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_resume_model_async.py new file mode 100644 index 000000000000..2966a3385209 --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_resume_model_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ResumeModel +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2_generated_ModelService_ResumeModel_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2 + + +async def sample_resume_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.ResumeModelRequest( + name="name_value", + ) + + # Make the request + response = await client.resume_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_ResumeModel_async] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_resume_model_sync.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_resume_model_sync.py new file mode 100644 index 000000000000..2c39f7409a3b --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_resume_model_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ResumeModel +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2_generated_ModelService_ResumeModel_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2 + + +def sample_resume_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.ResumeModelRequest( + name="name_value", + ) + + # Make the request + response = client.resume_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_ResumeModel_sync] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_tune_model_async.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_tune_model_async.py new file mode 100644 index 000000000000..c7744ed887ad --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_tune_model_async.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for TuneModel +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2_generated_ModelService_TuneModel_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2 + + +async def sample_tune_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.TuneModelRequest( + name="name_value", + ) + + # Make the request + operation = client.tune_model(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_TuneModel_async] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_tune_model_sync.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_tune_model_sync.py new file mode 100644 index 000000000000..b9f180c228bd --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_tune_model_sync.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for TuneModel +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2_generated_ModelService_TuneModel_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2 + + +def sample_tune_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.TuneModelRequest( + name="name_value", + ) + + # Make the request + operation = client.tune_model(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_TuneModel_sync] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_update_model_async.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_update_model_async.py new file mode 100644 index 000000000000..2caeda2d9f4f --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_update_model_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateModel +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2_generated_ModelService_UpdateModel_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2 + + +async def sample_update_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + model = retail_v2.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2.UpdateModelRequest( + model=model, + ) + + # Make the request + response = await client.update_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_UpdateModel_async] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_update_model_sync.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_update_model_sync.py new file mode 100644 index 000000000000..1f5e9d2427ac --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2_generated_model_service_update_model_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateModel +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2_generated_ModelService_UpdateModel_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2 + + +def sample_update_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + model = retail_v2.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2.UpdateModelRequest( + model=model, + ) + + # Make the request + response = client.update_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_UpdateModel_sync] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_async.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_async.py new file mode 100644 index 000000000000..d125b91c2452 --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_async.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateMerchantCenterAccountLink +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2alpha_generated_MerchantCenterAccountLinkService_CreateMerchantCenterAccountLink_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2alpha + + +async def sample_create_merchant_center_account_link(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient() + + # Initialize request argument(s) + merchant_center_account_link = retail_v2alpha.MerchantCenterAccountLink() + merchant_center_account_link.merchant_center_account_id = 2730 + merchant_center_account_link.branch_id = "branch_id_value" + + request = retail_v2alpha.CreateMerchantCenterAccountLinkRequest( + parent="parent_value", + merchant_center_account_link=merchant_center_account_link, + ) + + # Make the request + operation = client.create_merchant_center_account_link(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_MerchantCenterAccountLinkService_CreateMerchantCenterAccountLink_async] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_sync.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_sync.py new file mode 100644 index 000000000000..7ba5645a9ea9 --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_sync.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateMerchantCenterAccountLink +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2alpha_generated_MerchantCenterAccountLinkService_CreateMerchantCenterAccountLink_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2alpha + + +def sample_create_merchant_center_account_link(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceClient() + + # Initialize request argument(s) + merchant_center_account_link = retail_v2alpha.MerchantCenterAccountLink() + merchant_center_account_link.merchant_center_account_id = 2730 + merchant_center_account_link.branch_id = "branch_id_value" + + request = retail_v2alpha.CreateMerchantCenterAccountLinkRequest( + parent="parent_value", + merchant_center_account_link=merchant_center_account_link, + ) + + # Make the request + operation = client.create_merchant_center_account_link(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_MerchantCenterAccountLinkService_CreateMerchantCenterAccountLink_sync] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_async.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_async.py new file mode 100644 index 000000000000..82273ca9bab5 --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_async.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteMerchantCenterAccountLink +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2alpha_generated_MerchantCenterAccountLinkService_DeleteMerchantCenterAccountLink_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2alpha + + +async def sample_delete_merchant_center_account_link(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteMerchantCenterAccountLinkRequest( + name="name_value", + ) + + # Make the request + await client.delete_merchant_center_account_link(request=request) + + +# [END retail_v2alpha_generated_MerchantCenterAccountLinkService_DeleteMerchantCenterAccountLink_async] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_sync.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_sync.py new file mode 100644 index 000000000000..9f6da36fcf64 --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_sync.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteMerchantCenterAccountLink +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2alpha_generated_MerchantCenterAccountLinkService_DeleteMerchantCenterAccountLink_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2alpha + + +def sample_delete_merchant_center_account_link(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteMerchantCenterAccountLinkRequest( + name="name_value", + ) + + # Make the request + client.delete_merchant_center_account_link(request=request) + + +# [END retail_v2alpha_generated_MerchantCenterAccountLinkService_DeleteMerchantCenterAccountLink_sync] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_async.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_async.py new file mode 100644 index 000000000000..90ac018fd67b --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListMerchantCenterAccountLinks +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2alpha_generated_MerchantCenterAccountLinkService_ListMerchantCenterAccountLinks_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2alpha + + +async def sample_list_merchant_center_account_links(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListMerchantCenterAccountLinksRequest( + parent="parent_value", + ) + + # Make the request + response = await client.list_merchant_center_account_links(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_MerchantCenterAccountLinkService_ListMerchantCenterAccountLinks_async] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_sync.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_sync.py new file mode 100644 index 000000000000..204b4d8992e0 --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListMerchantCenterAccountLinks +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2alpha_generated_MerchantCenterAccountLinkService_ListMerchantCenterAccountLinks_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2alpha + + +def sample_list_merchant_center_account_links(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListMerchantCenterAccountLinksRequest( + parent="parent_value", + ) + + # Make the request + response = client.list_merchant_center_account_links(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_MerchantCenterAccountLinkService_ListMerchantCenterAccountLinks_sync] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_model_service_get_model_async.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_model_service_get_model_async.py new file mode 100644 index 000000000000..902a5235ea1d --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_model_service_get_model_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetModel +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2alpha_generated_ModelService_GetModel_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2alpha + + +async def sample_get_model(): + # Create a client + client = retail_v2alpha.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetModelRequest( + name="name_value", + ) + + # Make the request + response = await client.get_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ModelService_GetModel_async] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_model_service_get_model_sync.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_model_service_get_model_sync.py new file mode 100644 index 000000000000..dade4a933a8d --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2alpha_generated_model_service_get_model_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetModel +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2alpha_generated_ModelService_GetModel_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2alpha + + +def sample_get_model(): + # Create a client + client = retail_v2alpha.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetModelRequest( + name="name_value", + ) + + # Make the request + response = client.get_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ModelService_GetModel_sync] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2beta_generated_model_service_get_model_async.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2beta_generated_model_service_get_model_async.py new file mode 100644 index 000000000000..85b118d7334d --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2beta_generated_model_service_get_model_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetModel +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2beta_generated_ModelService_GetModel_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2beta + + +async def sample_get_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.GetModelRequest( + name="name_value", + ) + + # Make the request + response = await client.get_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ModelService_GetModel_async] diff --git a/packages/google-cloud-retail/samples/generated_samples/retail_v2beta_generated_model_service_get_model_sync.py b/packages/google-cloud-retail/samples/generated_samples/retail_v2beta_generated_model_service_get_model_sync.py new file mode 100644 index 000000000000..009befd8cb01 --- /dev/null +++ b/packages/google-cloud-retail/samples/generated_samples/retail_v2beta_generated_model_service_get_model_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetModel +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2beta_generated_ModelService_GetModel_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import retail_v2beta + + +def sample_get_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.GetModelRequest( + name="name_value", + ) + + # Make the request + response = client.get_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ModelService_GetModel_sync] diff --git a/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2.json b/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2.json index 1f010abff4b7..1a31fd9b8913 100644 --- a/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2.json +++ b/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-retail", - "version": "1.15.1" + "version": "0.1.0" }, "snippets": [ { @@ -2905,6 +2905,1304 @@ ], "title": "retail_v2_generated_control_service_update_control_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient.create_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.CreateModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "CreateModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.CreateModelRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "model", + "type": "google.cloud.retail_v2.types.Model" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "create_model" + }, + "description": "Sample for CreateModel", + "file": "retail_v2_generated_model_service_create_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_CreateModel_async", + "segments": [ + { + "end": 61, + "start": 27, + "type": "FULL" + }, + { + "end": 61, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 51, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 58, + "start": 52, + "type": "REQUEST_EXECUTION" + }, + { + "end": 62, + "start": 59, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_model_service_create_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceClient.create_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.CreateModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "CreateModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.CreateModelRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "model", + "type": "google.cloud.retail_v2.types.Model" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "create_model" + }, + "description": "Sample for CreateModel", + "file": "retail_v2_generated_model_service_create_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_CreateModel_sync", + "segments": [ + { + "end": 61, + "start": 27, + "type": "FULL" + }, + { + "end": 61, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 51, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 58, + "start": 52, + "type": "REQUEST_EXECUTION" + }, + { + "end": 62, + "start": 59, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_model_service_create_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient.delete_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.DeleteModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "DeleteModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.DeleteModelRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_model" + }, + "description": "Sample for DeleteModel", + "file": "retail_v2_generated_model_service_delete_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_DeleteModel_async", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_model_service_delete_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceClient.delete_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.DeleteModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "DeleteModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.DeleteModelRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_model" + }, + "description": "Sample for DeleteModel", + "file": "retail_v2_generated_model_service_delete_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_DeleteModel_sync", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_model_service_delete_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient.get_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.GetModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "GetModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.GetModelRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.Model", + "shortName": "get_model" + }, + "description": "Sample for GetModel", + "file": "retail_v2_generated_model_service_get_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_GetModel_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_model_service_get_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceClient.get_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.GetModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "GetModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.GetModelRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.Model", + "shortName": "get_model" + }, + "description": "Sample for GetModel", + "file": "retail_v2_generated_model_service_get_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_GetModel_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_model_service_get_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient.list_models", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.ListModels", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "ListModels" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ListModelsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.services.model_service.pagers.ListModelsAsyncPager", + "shortName": "list_models" + }, + "description": "Sample for ListModels", + "file": "retail_v2_generated_model_service_list_models_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_ListModels_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_model_service_list_models_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceClient.list_models", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.ListModels", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "ListModels" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ListModelsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.services.model_service.pagers.ListModelsPager", + "shortName": "list_models" + }, + "description": "Sample for ListModels", + "file": "retail_v2_generated_model_service_list_models_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_ListModels_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_model_service_list_models_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient.pause_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.PauseModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "PauseModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.PauseModelRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.Model", + "shortName": "pause_model" + }, + "description": "Sample for PauseModel", + "file": "retail_v2_generated_model_service_pause_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_PauseModel_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_model_service_pause_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceClient.pause_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.PauseModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "PauseModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.PauseModelRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.Model", + "shortName": "pause_model" + }, + "description": "Sample for PauseModel", + "file": "retail_v2_generated_model_service_pause_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_PauseModel_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_model_service_pause_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient.resume_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.ResumeModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "ResumeModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ResumeModelRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.Model", + "shortName": "resume_model" + }, + "description": "Sample for ResumeModel", + "file": "retail_v2_generated_model_service_resume_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_ResumeModel_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_model_service_resume_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceClient.resume_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.ResumeModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "ResumeModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ResumeModelRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.Model", + "shortName": "resume_model" + }, + "description": "Sample for ResumeModel", + "file": "retail_v2_generated_model_service_resume_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_ResumeModel_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_model_service_resume_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient.tune_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.TuneModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "TuneModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.TuneModelRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "tune_model" + }, + "description": "Sample for TuneModel", + "file": "retail_v2_generated_model_service_tune_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_TuneModel_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_model_service_tune_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceClient.tune_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.TuneModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "TuneModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.TuneModelRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "tune_model" + }, + "description": "Sample for TuneModel", + "file": "retail_v2_generated_model_service_tune_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_TuneModel_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_model_service_tune_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient.update_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.UpdateModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "UpdateModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.UpdateModelRequest" + }, + { + "name": "model", + "type": "google.cloud.retail_v2.types.Model" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.Model", + "shortName": "update_model" + }, + "description": "Sample for UpdateModel", + "file": "retail_v2_generated_model_service_update_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_UpdateModel_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_model_service_update_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceClient.update_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.UpdateModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "UpdateModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.UpdateModelRequest" + }, + { + "name": "model", + "type": "google.cloud.retail_v2.types.Model" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.Model", + "shortName": "update_model" + }, + "description": "Sample for UpdateModel", + "file": "retail_v2_generated_model_service_update_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_UpdateModel_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_model_service_update_model_sync.py" + }, { "canonical": true, "clientMethod": { diff --git a/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2alpha.json b/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2alpha.json index 34479a5b2c70..55845bb06de3 100644 --- a/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2alpha.json +++ b/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2alpha.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-retail", - "version": "1.15.1" + "version": "0.1.0" }, "snippets": [ { @@ -3058,6 +3058,491 @@ ], "title": "retail_v2alpha_generated_control_service_update_control_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient", + "shortName": "MerchantCenterAccountLinkServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient.create_merchant_center_account_link", + "method": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.CreateMerchantCenterAccountLink", + "service": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService", + "shortName": "MerchantCenterAccountLinkService" + }, + "shortName": "CreateMerchantCenterAccountLink" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.CreateMerchantCenterAccountLinkRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "merchant_center_account_link", + "type": "google.cloud.retail_v2alpha.types.MerchantCenterAccountLink" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "create_merchant_center_account_link" + }, + "description": "Sample for CreateMerchantCenterAccountLink", + "file": "retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_MerchantCenterAccountLinkService_CreateMerchantCenterAccountLink_async", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceClient", + "shortName": "MerchantCenterAccountLinkServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceClient.create_merchant_center_account_link", + "method": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.CreateMerchantCenterAccountLink", + "service": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService", + "shortName": "MerchantCenterAccountLinkService" + }, + "shortName": "CreateMerchantCenterAccountLink" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.CreateMerchantCenterAccountLinkRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "merchant_center_account_link", + "type": "google.cloud.retail_v2alpha.types.MerchantCenterAccountLink" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "create_merchant_center_account_link" + }, + "description": "Sample for CreateMerchantCenterAccountLink", + "file": "retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_MerchantCenterAccountLinkService_CreateMerchantCenterAccountLink_sync", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient", + "shortName": "MerchantCenterAccountLinkServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient.delete_merchant_center_account_link", + "method": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.DeleteMerchantCenterAccountLink", + "service": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService", + "shortName": "MerchantCenterAccountLinkService" + }, + "shortName": "DeleteMerchantCenterAccountLink" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.DeleteMerchantCenterAccountLinkRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_merchant_center_account_link" + }, + "description": "Sample for DeleteMerchantCenterAccountLink", + "file": "retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_MerchantCenterAccountLinkService_DeleteMerchantCenterAccountLink_async", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceClient", + "shortName": "MerchantCenterAccountLinkServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceClient.delete_merchant_center_account_link", + "method": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.DeleteMerchantCenterAccountLink", + "service": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService", + "shortName": "MerchantCenterAccountLinkService" + }, + "shortName": "DeleteMerchantCenterAccountLink" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.DeleteMerchantCenterAccountLinkRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_merchant_center_account_link" + }, + "description": "Sample for DeleteMerchantCenterAccountLink", + "file": "retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_MerchantCenterAccountLinkService_DeleteMerchantCenterAccountLink_sync", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient", + "shortName": "MerchantCenterAccountLinkServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient.list_merchant_center_account_links", + "method": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks", + "service": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService", + "shortName": "MerchantCenterAccountLinkService" + }, + "shortName": "ListMerchantCenterAccountLinks" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ListMerchantCenterAccountLinksRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.ListMerchantCenterAccountLinksResponse", + "shortName": "list_merchant_center_account_links" + }, + "description": "Sample for ListMerchantCenterAccountLinks", + "file": "retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_MerchantCenterAccountLinkService_ListMerchantCenterAccountLinks_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceClient", + "shortName": "MerchantCenterAccountLinkServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceClient.list_merchant_center_account_links", + "method": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks", + "service": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService", + "shortName": "MerchantCenterAccountLinkService" + }, + "shortName": "ListMerchantCenterAccountLinks" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ListMerchantCenterAccountLinksRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.ListMerchantCenterAccountLinksResponse", + "shortName": "list_merchant_center_account_links" + }, + "description": "Sample for ListMerchantCenterAccountLinks", + "file": "retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_MerchantCenterAccountLinkService_ListMerchantCenterAccountLinks_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_sync.py" + }, { "canonical": true, "clientMethod": { @@ -3382,6 +3867,167 @@ ], "title": "retail_v2alpha_generated_model_service_delete_model_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ModelServiceAsyncClient.get_model", + "method": { + "fullName": "google.cloud.retail.v2alpha.ModelService.GetModel", + "service": { + "fullName": "google.cloud.retail.v2alpha.ModelService", + "shortName": "ModelService" + }, + "shortName": "GetModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.GetModelRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.Model", + "shortName": "get_model" + }, + "description": "Sample for GetModel", + "file": "retail_v2alpha_generated_model_service_get_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ModelService_GetModel_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_model_service_get_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ModelServiceClient.get_model", + "method": { + "fullName": "google.cloud.retail.v2alpha.ModelService.GetModel", + "service": { + "fullName": "google.cloud.retail.v2alpha.ModelService", + "shortName": "ModelService" + }, + "shortName": "GetModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.GetModelRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.Model", + "shortName": "get_model" + }, + "description": "Sample for GetModel", + "file": "retail_v2alpha_generated_model_service_get_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ModelService_GetModel_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_model_service_get_model_sync.py" + }, { "canonical": true, "clientMethod": { diff --git a/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2beta.json b/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2beta.json index f33d21cd3cd3..edada0c10b10 100644 --- a/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2beta.json +++ b/packages/google-cloud-retail/samples/generated_samples/snippet_metadata_google.cloud.retail.v2beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-retail", - "version": "1.15.1" + "version": "0.1.0" }, "snippets": [ { @@ -3382,6 +3382,167 @@ ], "title": "retail_v2beta_generated_model_service_delete_model_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient.get_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.GetModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "GetModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.GetModelRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.Model", + "shortName": "get_model" + }, + "description": "Sample for GetModel", + "file": "retail_v2beta_generated_model_service_get_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_GetModel_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_model_service_get_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceClient.get_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.GetModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "GetModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.GetModelRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.Model", + "shortName": "get_model" + }, + "description": "Sample for GetModel", + "file": "retail_v2beta_generated_model_service_get_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_GetModel_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_model_service_get_model_sync.py" + }, { "canonical": true, "clientMethod": { diff --git a/packages/google-cloud-retail/scripts/fixup_retail_v2_keywords.py b/packages/google-cloud-retail/scripts/fixup_retail_v2_keywords.py index 795ed8be6163..a19348461c7a 100644 --- a/packages/google-cloud-retail/scripts/fixup_retail_v2_keywords.py +++ b/packages/google-cloud-retail/scripts/fixup_retail_v2_keywords.py @@ -44,17 +44,20 @@ class retailCallTransformer(cst.CSTTransformer): 'add_fulfillment_places': ('product', 'type_', 'place_ids', 'add_time', 'allow_missing', ), 'add_local_inventories': ('product', 'local_inventories', 'add_mask', 'add_time', 'allow_missing', ), 'collect_user_event': ('parent', 'user_event', 'prebuilt_rule', 'uri', 'ets', 'raw_json', ), - 'complete_query': ('catalog', 'query', 'visitor_id', 'language_codes', 'device_type', 'dataset', 'max_suggestions', ), + 'complete_query': ('catalog', 'query', 'visitor_id', 'language_codes', 'device_type', 'dataset', 'max_suggestions', 'entity', ), 'create_control': ('parent', 'control', 'control_id', ), + 'create_model': ('parent', 'model', 'dry_run', ), 'create_product': ('parent', 'product', 'product_id', ), 'create_serving_config': ('parent', 'serving_config', 'serving_config_id', ), 'delete_control': ('name', ), + 'delete_model': ('name', ), 'delete_product': ('name', ), 'delete_serving_config': ('name', ), 'get_attributes_config': ('name', ), 'get_completion_config': ('name', ), 'get_control': ('name', ), 'get_default_branch': ('catalog', ), + 'get_model': ('name', ), 'get_product': ('name', ), 'get_serving_config': ('name', ), 'import_completion_data': ('parent', 'input_config', 'notification_pubsub_topic', ), @@ -62,8 +65,10 @@ class retailCallTransformer(cst.CSTTransformer): 'import_user_events': ('parent', 'input_config', 'errors_config', ), 'list_catalogs': ('parent', 'page_size', 'page_token', ), 'list_controls': ('parent', 'page_size', 'page_token', 'filter', ), + 'list_models': ('parent', 'page_size', 'page_token', ), 'list_products': ('parent', 'page_size', 'page_token', 'filter', 'read_mask', ), 'list_serving_configs': ('parent', 'page_size', 'page_token', ), + 'pause_model': ('name', ), 'predict': ('placement', 'user_event', 'page_size', 'page_token', 'filter', 'validate_only', 'params', 'labels', ), 'purge_user_events': ('parent', 'filter', 'force', ), 'rejoin_user_events': ('parent', 'user_event_rejoin_scope', ), @@ -72,13 +77,16 @@ class retailCallTransformer(cst.CSTTransformer): 'remove_fulfillment_places': ('product', 'type_', 'place_ids', 'remove_time', 'allow_missing', ), 'remove_local_inventories': ('product', 'place_ids', 'remove_time', 'allow_missing', ), 'replace_catalog_attribute': ('attributes_config', 'catalog_attribute', 'update_mask', ), - 'search': ('placement', 'visitor_id', 'branch', 'query', 'user_info', 'page_size', 'page_token', 'offset', 'filter', 'canonical_filter', 'order_by', 'facet_specs', 'dynamic_facet_spec', 'boost_spec', 'query_expansion_spec', 'variant_rollup_keys', 'page_categories', 'search_mode', 'personalization_spec', 'labels', 'spell_correction_spec', ), + 'resume_model': ('name', ), + 'search': ('placement', 'visitor_id', 'branch', 'query', 'user_info', 'page_size', 'page_token', 'offset', 'filter', 'canonical_filter', 'order_by', 'facet_specs', 'dynamic_facet_spec', 'boost_spec', 'query_expansion_spec', 'variant_rollup_keys', 'page_categories', 'search_mode', 'personalization_spec', 'labels', 'spell_correction_spec', 'entity', ), 'set_default_branch': ('catalog', 'branch_id', 'note', 'force', ), 'set_inventory': ('inventory', 'set_mask', 'set_time', 'allow_missing', ), + 'tune_model': ('name', ), 'update_attributes_config': ('attributes_config', 'update_mask', ), 'update_catalog': ('catalog', 'update_mask', ), 'update_completion_config': ('completion_config', 'update_mask', ), 'update_control': ('control', 'update_mask', ), + 'update_model': ('model', 'update_mask', ), 'update_product': ('product', 'update_mask', 'allow_missing', ), 'update_serving_config': ('serving_config', 'update_mask', ), 'write_user_event': ('parent', 'user_event', 'write_async', ), diff --git a/packages/google-cloud-retail/scripts/fixup_retail_v2alpha_keywords.py b/packages/google-cloud-retail/scripts/fixup_retail_v2alpha_keywords.py index 6290e25eaaea..264a469543dc 100644 --- a/packages/google-cloud-retail/scripts/fixup_retail_v2alpha_keywords.py +++ b/packages/google-cloud-retail/scripts/fixup_retail_v2alpha_keywords.py @@ -45,19 +45,22 @@ class retailCallTransformer(cst.CSTTransformer): 'add_local_inventories': ('product', 'local_inventories', 'add_mask', 'add_time', 'allow_missing', ), 'batch_remove_catalog_attributes': ('attributes_config', 'attribute_keys', ), 'collect_user_event': ('parent', 'user_event', 'prebuilt_rule', 'uri', 'ets', 'raw_json', ), - 'complete_query': ('catalog', 'query', 'visitor_id', 'language_codes', 'device_type', 'dataset', 'max_suggestions', 'enable_attribute_suggestions', ), + 'complete_query': ('catalog', 'query', 'visitor_id', 'language_codes', 'device_type', 'dataset', 'max_suggestions', 'enable_attribute_suggestions', 'entity', ), 'create_control': ('parent', 'control', 'control_id', ), + 'create_merchant_center_account_link': ('parent', 'merchant_center_account_link', ), 'create_model': ('parent', 'model', 'dry_run', ), 'create_product': ('parent', 'product', 'product_id', ), 'create_serving_config': ('parent', 'serving_config', 'serving_config_id', ), 'delete_control': ('name', ), + 'delete_merchant_center_account_link': ('name', ), 'delete_model': ('name', ), - 'delete_product': ('name', ), + 'delete_product': ('name', 'force', ), 'delete_serving_config': ('name', ), 'get_attributes_config': ('name', ), 'get_completion_config': ('name', ), 'get_control': ('name', ), 'get_default_branch': ('catalog', ), + 'get_model': ('name', ), 'get_product': ('name', ), 'get_serving_config': ('name', ), 'import_completion_data': ('parent', 'input_config', 'notification_pubsub_topic', ), @@ -65,6 +68,7 @@ class retailCallTransformer(cst.CSTTransformer): 'import_user_events': ('parent', 'input_config', 'errors_config', ), 'list_catalogs': ('parent', 'page_size', 'page_token', ), 'list_controls': ('parent', 'page_size', 'page_token', 'filter', ), + 'list_merchant_center_account_links': ('parent', ), 'list_models': ('parent', 'page_size', 'page_token', ), 'list_products': ('parent', 'page_size', 'page_token', 'filter', 'read_mask', 'require_total_size', ), 'list_serving_configs': ('parent', 'page_size', 'page_token', ), @@ -79,7 +83,7 @@ class retailCallTransformer(cst.CSTTransformer): 'remove_local_inventories': ('product', 'place_ids', 'remove_time', 'allow_missing', ), 'replace_catalog_attribute': ('attributes_config', 'catalog_attribute', 'update_mask', ), 'resume_model': ('name', ), - 'search': ('placement', 'visitor_id', 'branch', 'query', 'user_info', 'page_size', 'page_token', 'offset', 'filter', 'canonical_filter', 'order_by', 'facet_specs', 'dynamic_facet_spec', 'boost_spec', 'query_expansion_spec', 'relevance_threshold', 'variant_rollup_keys', 'page_categories', 'search_mode', 'personalization_spec', 'labels', 'spell_correction_spec', ), + 'search': ('placement', 'visitor_id', 'branch', 'query', 'user_info', 'page_size', 'page_token', 'offset', 'filter', 'canonical_filter', 'order_by', 'facet_specs', 'dynamic_facet_spec', 'boost_spec', 'query_expansion_spec', 'relevance_threshold', 'variant_rollup_keys', 'page_categories', 'search_mode', 'personalization_spec', 'labels', 'spell_correction_spec', 'entity', ), 'set_default_branch': ('catalog', 'branch_id', 'note', 'force', ), 'set_inventory': ('inventory', 'set_mask', 'set_time', 'allow_missing', ), 'tune_model': ('name', ), diff --git a/packages/google-cloud-retail/scripts/fixup_retail_v2beta_keywords.py b/packages/google-cloud-retail/scripts/fixup_retail_v2beta_keywords.py index 8527abd74a5d..eac83d78cb4e 100644 --- a/packages/google-cloud-retail/scripts/fixup_retail_v2beta_keywords.py +++ b/packages/google-cloud-retail/scripts/fixup_retail_v2beta_keywords.py @@ -45,7 +45,7 @@ class retailCallTransformer(cst.CSTTransformer): 'add_local_inventories': ('product', 'local_inventories', 'add_mask', 'add_time', 'allow_missing', ), 'batch_remove_catalog_attributes': ('attributes_config', 'attribute_keys', ), 'collect_user_event': ('parent', 'user_event', 'prebuilt_rule', 'uri', 'ets', 'raw_json', ), - 'complete_query': ('catalog', 'query', 'visitor_id', 'language_codes', 'device_type', 'dataset', 'max_suggestions', ), + 'complete_query': ('catalog', 'query', 'visitor_id', 'language_codes', 'device_type', 'dataset', 'max_suggestions', 'entity', ), 'create_control': ('parent', 'control', 'control_id', ), 'create_model': ('parent', 'model', 'dry_run', ), 'create_product': ('parent', 'product', 'product_id', ), @@ -58,6 +58,7 @@ class retailCallTransformer(cst.CSTTransformer): 'get_completion_config': ('name', ), 'get_control': ('name', ), 'get_default_branch': ('catalog', ), + 'get_model': ('name', ), 'get_product': ('name', ), 'get_serving_config': ('name', ), 'import_completion_data': ('parent', 'input_config', 'notification_pubsub_topic', ), @@ -78,7 +79,7 @@ class retailCallTransformer(cst.CSTTransformer): 'remove_local_inventories': ('product', 'place_ids', 'remove_time', 'allow_missing', ), 'replace_catalog_attribute': ('attributes_config', 'catalog_attribute', 'update_mask', ), 'resume_model': ('name', ), - 'search': ('placement', 'visitor_id', 'branch', 'query', 'user_info', 'page_size', 'page_token', 'offset', 'filter', 'canonical_filter', 'order_by', 'facet_specs', 'dynamic_facet_spec', 'boost_spec', 'query_expansion_spec', 'variant_rollup_keys', 'page_categories', 'search_mode', 'personalization_spec', 'labels', 'spell_correction_spec', ), + 'search': ('placement', 'visitor_id', 'branch', 'query', 'user_info', 'page_size', 'page_token', 'offset', 'filter', 'canonical_filter', 'order_by', 'facet_specs', 'dynamic_facet_spec', 'boost_spec', 'query_expansion_spec', 'variant_rollup_keys', 'page_categories', 'search_mode', 'personalization_spec', 'labels', 'spell_correction_spec', 'entity', ), 'set_default_branch': ('catalog', 'branch_id', 'note', 'force', ), 'set_inventory': ('inventory', 'set_mask', 'set_time', 'allow_missing', ), 'tune_model': ('name', ), diff --git a/packages/google-cloud-retail/tests/unit/gapic/retail_v2/test_completion_service.py b/packages/google-cloud-retail/tests/unit/gapic/retail_v2/test_completion_service.py index 01c783dd86f8..b9dcf7554393 100644 --- a/packages/google-cloud-retail/tests/unit/gapic/retail_v2/test_completion_service.py +++ b/packages/google-cloud-retail/tests/unit/gapic/retail_v2/test_completion_service.py @@ -1129,6 +1129,7 @@ def test_complete_query_rest_required_fields( ( "dataset", "device_type", + "entity", "language_codes", "max_suggestions", "query", @@ -1200,6 +1201,7 @@ def test_complete_query_rest_unset_required_fields(): ( "dataset", "deviceType", + "entity", "languageCodes", "maxSuggestions", "query", diff --git a/packages/google-cloud-retail/tests/unit/gapic/retail_v2/test_model_service.py b/packages/google-cloud-retail/tests/unit/gapic/retail_v2/test_model_service.py new file mode 100644 index 000000000000..7d4fcac99d30 --- /dev/null +++ b/packages/google-cloud-retail/tests/unit/gapic/retail_v2/test_model_service.py @@ -0,0 +1,6613 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import Iterable +import json +import math + +from google.api_core import ( + future, + gapic_v1, + grpc_helpers, + grpc_helpers_async, + operation, + operations_v1, + path_template, +) +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import operation_async # type: ignore +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.location import locations_pb2 +from google.longrunning import operations_pb2 +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import json_format +from google.protobuf import timestamp_pb2 # type: ignore +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +from google.cloud.retail_v2.services.model_service import ( + ModelServiceAsyncClient, + ModelServiceClient, + pagers, + transports, +) +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import model +from google.cloud.retail_v2.types import model as gcr_model +from google.cloud.retail_v2.types import model_service + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert ModelServiceClient._get_default_mtls_endpoint(None) is None + assert ( + ModelServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + ) + assert ( + ModelServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + ModelServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + ModelServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ModelServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (ModelServiceClient, "grpc"), + (ModelServiceAsyncClient, "grpc_asyncio"), + (ModelServiceClient, "rest"), + ], +) +def test_model_service_client_from_service_account_info(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "retail.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://retail.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.ModelServiceGrpcTransport, "grpc"), + (transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ModelServiceRestTransport, "rest"), + ], +) +def test_model_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (ModelServiceClient, "grpc"), + (ModelServiceAsyncClient, "grpc_asyncio"), + (ModelServiceClient, "rest"), + ], +) +def test_model_service_client_from_service_account_file(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "retail.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://retail.googleapis.com" + ) + + +def test_model_service_client_get_transport_class(): + transport = ModelServiceClient.get_transport_class() + available_transports = [ + transports.ModelServiceGrpcTransport, + transports.ModelServiceRestTransport, + ] + assert transport in available_transports + + transport = ModelServiceClient.get_transport_class("grpc") + assert transport == transports.ModelServiceGrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc"), + ( + ModelServiceAsyncClient, + transports.ModelServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + (ModelServiceClient, transports.ModelServiceRestTransport, "rest"), + ], +) +@mock.patch.object( + ModelServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ModelServiceClient) +) +@mock.patch.object( + ModelServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(ModelServiceAsyncClient), +) +def test_model_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(ModelServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(ModelServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class(transport=transport_name) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError): + client = client_class(transport=transport_name) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc", "true"), + ( + ModelServiceAsyncClient, + transports.ModelServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc", "false"), + ( + ModelServiceAsyncClient, + transports.ModelServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + (ModelServiceClient, transports.ModelServiceRestTransport, "rest", "true"), + (ModelServiceClient, transports.ModelServiceRestTransport, "rest", "false"), + ], +) +@mock.patch.object( + ModelServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ModelServiceClient) +) +@mock.patch.object( + ModelServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(ModelServiceAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_model_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [ModelServiceClient, ModelServiceAsyncClient]) +@mock.patch.object( + ModelServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ModelServiceClient) +) +@mock.patch.object( + ModelServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(ModelServiceAsyncClient), +) +def test_model_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc"), + ( + ModelServiceAsyncClient, + transports.ModelServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + (ModelServiceClient, transports.ModelServiceRestTransport, "rest"), + ], +) +def test_model_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + ModelServiceClient, + transports.ModelServiceGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + ModelServiceAsyncClient, + transports.ModelServiceGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + (ModelServiceClient, transports.ModelServiceRestTransport, "rest", None), + ], +) +def test_model_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_model_service_client_client_options_from_dict(): + with mock.patch( + "google.cloud.retail_v2.services.model_service.transports.ModelServiceGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = ModelServiceClient(client_options={"api_endpoint": "squid.clam.whelk"}) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + ModelServiceClient, + transports.ModelServiceGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + ModelServiceAsyncClient, + transports.ModelServiceGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ], +) +def test_model_service_client_create_channel_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel" + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "request_type", + [ + model_service.CreateModelRequest, + dict, + ], +) +def test_create_model(request_type, transport: str = "grpc"): + client = ModelServiceClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.create_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.CreateModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_create_model_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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_model), "__call__") as call: + client.create_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.CreateModelRequest() + + +@pytest.mark.asyncio +async def test_create_model_async( + transport: str = "grpc_asyncio", request_type=model_service.CreateModelRequest +): + client = ModelServiceAsyncClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.create_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.CreateModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_create_model_async_from_dict(): + await test_create_model_async(request_type=dict) + + +def test_create_model_field_headers(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = model_service.CreateModelRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_model), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_create_model_field_headers_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = model_service.CreateModelRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_model), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.create_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_create_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_model), "__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.create_model( + parent="parent_value", + model=gcr_model.Model(name="name_value"), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].model + mock_val = gcr_model.Model(name="name_value") + assert arg == mock_val + + +def test_create_model_flattened_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_model( + model_service.CreateModelRequest(), + parent="parent_value", + model=gcr_model.Model(name="name_value"), + ) + + +@pytest.mark.asyncio +async def test_create_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_model( + parent="parent_value", + model=gcr_model.Model(name="name_value"), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].model + mock_val = gcr_model.Model(name="name_value") + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_create_model_flattened_error_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_model( + model_service.CreateModelRequest(), + parent="parent_value", + model=gcr_model.Model(name="name_value"), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + model_service.GetModelRequest, + dict, + ], +) +def test_get_model(request_type, transport: str = "grpc"): + client = ModelServiceClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model( + name="name_value", + display_name="display_name_value", + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_="type__value", + optimization_objective="optimization_objective_value", + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation="tuning_operation_value", + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + response = client.get_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.GetModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == "type__value" + assert response.optimization_objective == "optimization_objective_value" + assert ( + response.periodic_tuning_state + == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + ) + assert response.tuning_operation == "tuning_operation_value" + assert response.data_state == model.Model.DataState.DATA_OK + assert ( + response.filtering_option + == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + ) + + +def test_get_model_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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_model), "__call__") as call: + client.get_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.GetModelRequest() + + +@pytest.mark.asyncio +async def test_get_model_async( + transport: str = "grpc_asyncio", request_type=model_service.GetModelRequest +): + client = ModelServiceAsyncClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + model.Model( + name="name_value", + display_name="display_name_value", + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_="type__value", + optimization_objective="optimization_objective_value", + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation="tuning_operation_value", + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + ) + response = await client.get_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.GetModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == "type__value" + assert response.optimization_objective == "optimization_objective_value" + assert ( + response.periodic_tuning_state + == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + ) + assert response.tuning_operation == "tuning_operation_value" + assert response.data_state == model.Model.DataState.DATA_OK + assert ( + response.filtering_option + == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + ) + + +@pytest.mark.asyncio +async def test_get_model_async_from_dict(): + await test_get_model_async(request_type=dict) + + +def test_get_model_field_headers(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = model_service.GetModelRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_model), "__call__") as call: + call.return_value = model.Model() + client.get_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_model_field_headers_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = model_service.GetModelRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_model), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + await client.get_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_get_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_model( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_get_model_flattened_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_model( + model_service.GetModelRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_model( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_get_model_flattened_error_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_model( + model_service.GetModelRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + model_service.PauseModelRequest, + dict, + ], +) +def test_pause_model(request_type, transport: str = "grpc"): + client = ModelServiceClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.pause_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model( + name="name_value", + display_name="display_name_value", + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_="type__value", + optimization_objective="optimization_objective_value", + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation="tuning_operation_value", + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + response = client.pause_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.PauseModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == "type__value" + assert response.optimization_objective == "optimization_objective_value" + assert ( + response.periodic_tuning_state + == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + ) + assert response.tuning_operation == "tuning_operation_value" + assert response.data_state == model.Model.DataState.DATA_OK + assert ( + response.filtering_option + == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + ) + + +def test_pause_model_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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.pause_model), "__call__") as call: + client.pause_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.PauseModelRequest() + + +@pytest.mark.asyncio +async def test_pause_model_async( + transport: str = "grpc_asyncio", request_type=model_service.PauseModelRequest +): + client = ModelServiceAsyncClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.pause_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + model.Model( + name="name_value", + display_name="display_name_value", + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_="type__value", + optimization_objective="optimization_objective_value", + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation="tuning_operation_value", + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + ) + response = await client.pause_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.PauseModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == "type__value" + assert response.optimization_objective == "optimization_objective_value" + assert ( + response.periodic_tuning_state + == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + ) + assert response.tuning_operation == "tuning_operation_value" + assert response.data_state == model.Model.DataState.DATA_OK + assert ( + response.filtering_option + == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + ) + + +@pytest.mark.asyncio +async def test_pause_model_async_from_dict(): + await test_pause_model_async(request_type=dict) + + +def test_pause_model_field_headers(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = model_service.PauseModelRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.pause_model), "__call__") as call: + call.return_value = model.Model() + client.pause_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_pause_model_field_headers_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = model_service.PauseModelRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.pause_model), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + await client.pause_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_pause_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.pause_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.pause_model( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_pause_model_flattened_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.pause_model( + model_service.PauseModelRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_pause_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.pause_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.pause_model( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_pause_model_flattened_error_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.pause_model( + model_service.PauseModelRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + model_service.ResumeModelRequest, + dict, + ], +) +def test_resume_model(request_type, transport: str = "grpc"): + client = ModelServiceClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.resume_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model( + name="name_value", + display_name="display_name_value", + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_="type__value", + optimization_objective="optimization_objective_value", + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation="tuning_operation_value", + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + response = client.resume_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ResumeModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == "type__value" + assert response.optimization_objective == "optimization_objective_value" + assert ( + response.periodic_tuning_state + == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + ) + assert response.tuning_operation == "tuning_operation_value" + assert response.data_state == model.Model.DataState.DATA_OK + assert ( + response.filtering_option + == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + ) + + +def test_resume_model_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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.resume_model), "__call__") as call: + client.resume_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ResumeModelRequest() + + +@pytest.mark.asyncio +async def test_resume_model_async( + transport: str = "grpc_asyncio", request_type=model_service.ResumeModelRequest +): + client = ModelServiceAsyncClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.resume_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + model.Model( + name="name_value", + display_name="display_name_value", + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_="type__value", + optimization_objective="optimization_objective_value", + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation="tuning_operation_value", + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + ) + response = await client.resume_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ResumeModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == "type__value" + assert response.optimization_objective == "optimization_objective_value" + assert ( + response.periodic_tuning_state + == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + ) + assert response.tuning_operation == "tuning_operation_value" + assert response.data_state == model.Model.DataState.DATA_OK + assert ( + response.filtering_option + == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + ) + + +@pytest.mark.asyncio +async def test_resume_model_async_from_dict(): + await test_resume_model_async(request_type=dict) + + +def test_resume_model_field_headers(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = model_service.ResumeModelRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.resume_model), "__call__") as call: + call.return_value = model.Model() + client.resume_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_resume_model_field_headers_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = model_service.ResumeModelRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.resume_model), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + await client.resume_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_resume_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.resume_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.resume_model( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_resume_model_flattened_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.resume_model( + model_service.ResumeModelRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_resume_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.resume_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.resume_model( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_resume_model_flattened_error_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.resume_model( + model_service.ResumeModelRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + model_service.DeleteModelRequest, + dict, + ], +) +def test_delete_model(request_type, transport: str = "grpc"): + client = ModelServiceClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.DeleteModelRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_model_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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_model), "__call__") as call: + client.delete_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.DeleteModelRequest() + + +@pytest.mark.asyncio +async def test_delete_model_async( + transport: str = "grpc_asyncio", request_type=model_service.DeleteModelRequest +): + client = ModelServiceAsyncClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.DeleteModelRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_model_async_from_dict(): + await test_delete_model_async(request_type=dict) + + +def test_delete_model_field_headers(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = model_service.DeleteModelRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_model), "__call__") as call: + call.return_value = None + client.delete_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_delete_model_field_headers_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = model_service.DeleteModelRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_model), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_delete_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_model( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_delete_model_flattened_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_model( + model_service.DeleteModelRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_delete_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_model( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_delete_model_flattened_error_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_model( + model_service.DeleteModelRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + model_service.ListModelsRequest, + dict, + ], +) +def test_list_models(request_type, transport: str = "grpc"): + client = ModelServiceClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_models), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = model_service.ListModelsResponse( + next_page_token="next_page_token_value", + ) + response = client.list_models(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ListModelsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListModelsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_models_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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_models), "__call__") as call: + client.list_models() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ListModelsRequest() + + +@pytest.mark.asyncio +async def test_list_models_async( + transport: str = "grpc_asyncio", request_type=model_service.ListModelsRequest +): + client = ModelServiceAsyncClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_models), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + model_service.ListModelsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_models(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ListModelsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListModelsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_models_async_from_dict(): + await test_list_models_async(request_type=dict) + + +def test_list_models_field_headers(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = model_service.ListModelsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_models), "__call__") as call: + call.return_value = model_service.ListModelsResponse() + client.list_models(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_models_field_headers_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = model_service.ListModelsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_models), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + model_service.ListModelsResponse() + ) + await client.list_models(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_list_models_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_models), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = model_service.ListModelsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_models( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +def test_list_models_flattened_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_models( + model_service.ListModelsRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_models_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_models), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = model_service.ListModelsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + model_service.ListModelsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_models( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_list_models_flattened_error_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_models( + model_service.ListModelsRequest(), + parent="parent_value", + ) + + +def test_list_models_pager(transport_name: str = "grpc"): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_models), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + model.Model(), + ], + next_page_token="abc", + ), + model_service.ListModelsResponse( + models=[], + next_page_token="def", + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + ], + next_page_token="ghi", + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_models(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, model.Model) for i in results) + + +def test_list_models_pages(transport_name: str = "grpc"): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_models), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + model.Model(), + ], + next_page_token="abc", + ), + model_service.ListModelsResponse( + models=[], + next_page_token="def", + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + ], + next_page_token="ghi", + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + ], + ), + RuntimeError, + ) + pages = list(client.list_models(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_models_async_pager(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_models), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + model.Model(), + ], + next_page_token="abc", + ), + model_service.ListModelsResponse( + models=[], + next_page_token="def", + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + ], + next_page_token="ghi", + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_models( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, model.Model) for i in responses) + + +@pytest.mark.asyncio +async def test_list_models_async_pages(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_models), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + model.Model(), + ], + next_page_token="abc", + ), + model_service.ListModelsResponse( + models=[], + next_page_token="def", + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + ], + next_page_token="ghi", + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in ( + await client.list_models(request={}) + ).pages: # pragma: no branch + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + model_service.UpdateModelRequest, + dict, + ], +) +def test_update_model(request_type, transport: str = "grpc"): + client = ModelServiceClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_model.Model( + name="name_value", + display_name="display_name_value", + training_state=gcr_model.Model.TrainingState.PAUSED, + serving_state=gcr_model.Model.ServingState.INACTIVE, + type_="type__value", + optimization_objective="optimization_objective_value", + periodic_tuning_state=gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation="tuning_operation_value", + data_state=gcr_model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + response = client.update_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.UpdateModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_model.Model) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.training_state == gcr_model.Model.TrainingState.PAUSED + assert response.serving_state == gcr_model.Model.ServingState.INACTIVE + assert response.type_ == "type__value" + assert response.optimization_objective == "optimization_objective_value" + assert ( + response.periodic_tuning_state + == gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + ) + assert response.tuning_operation == "tuning_operation_value" + assert response.data_state == gcr_model.Model.DataState.DATA_OK + assert ( + response.filtering_option + == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + ) + + +def test_update_model_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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_model), "__call__") as call: + client.update_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.UpdateModelRequest() + + +@pytest.mark.asyncio +async def test_update_model_async( + transport: str = "grpc_asyncio", request_type=model_service.UpdateModelRequest +): + client = ModelServiceAsyncClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcr_model.Model( + name="name_value", + display_name="display_name_value", + training_state=gcr_model.Model.TrainingState.PAUSED, + serving_state=gcr_model.Model.ServingState.INACTIVE, + type_="type__value", + optimization_objective="optimization_objective_value", + periodic_tuning_state=gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation="tuning_operation_value", + data_state=gcr_model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + ) + response = await client.update_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.UpdateModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_model.Model) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.training_state == gcr_model.Model.TrainingState.PAUSED + assert response.serving_state == gcr_model.Model.ServingState.INACTIVE + assert response.type_ == "type__value" + assert response.optimization_objective == "optimization_objective_value" + assert ( + response.periodic_tuning_state + == gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + ) + assert response.tuning_operation == "tuning_operation_value" + assert response.data_state == gcr_model.Model.DataState.DATA_OK + assert ( + response.filtering_option + == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + ) + + +@pytest.mark.asyncio +async def test_update_model_async_from_dict(): + await test_update_model_async(request_type=dict) + + +def test_update_model_field_headers(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = model_service.UpdateModelRequest() + + request.model.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_model), "__call__") as call: + call.return_value = gcr_model.Model() + client.update_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "model.name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_model_field_headers_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = model_service.UpdateModelRequest() + + request.model.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_model), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_model.Model()) + await client.update_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "model.name=name_value", + ) in kw["metadata"] + + +def test_update_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_model.Model() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_model( + model=gcr_model.Model(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].model + mock_val = gcr_model.Model(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +def test_update_model_flattened_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_model( + model_service.UpdateModelRequest(), + model=gcr_model.Model(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_model.Model() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_model.Model()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_model( + model=gcr_model.Model(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].model + mock_val = gcr_model.Model(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_update_model_flattened_error_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_model( + model_service.UpdateModelRequest(), + model=gcr_model.Model(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + model_service.TuneModelRequest, + dict, + ], +) +def test_tune_model(request_type, transport: str = "grpc"): + client = ModelServiceClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.tune_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.tune_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.TuneModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_tune_model_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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.tune_model), "__call__") as call: + client.tune_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.TuneModelRequest() + + +@pytest.mark.asyncio +async def test_tune_model_async( + transport: str = "grpc_asyncio", request_type=model_service.TuneModelRequest +): + client = ModelServiceAsyncClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.tune_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.tune_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.TuneModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_tune_model_async_from_dict(): + await test_tune_model_async(request_type=dict) + + +def test_tune_model_field_headers(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = model_service.TuneModelRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.tune_model), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.tune_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_tune_model_field_headers_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = model_service.TuneModelRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.tune_model), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.tune_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_tune_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.tune_model), "__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.tune_model( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_tune_model_flattened_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.tune_model( + model_service.TuneModelRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_tune_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.tune_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.tune_model( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_tune_model_flattened_error_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.tune_model( + model_service.TuneModelRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + model_service.CreateModelRequest, + dict, + ], +) +def test_create_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/catalogs/sample3"} + request_init["model"] = { + "name": "name_value", + "display_name": "display_name_value", + "training_state": 1, + "serving_state": 1, + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "type_": "type__value", + "optimization_objective": "optimization_objective_value", + "periodic_tuning_state": 1, + "last_tune_time": {}, + "tuning_operation": "tuning_operation_value", + "data_state": 1, + "filtering_option": 1, + "serving_config_lists": [ + { + "serving_config_ids": [ + "serving_config_ids_value1", + "serving_config_ids_value2", + ] + } + ], + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_model(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_create_model_rest_required_fields( + request_type=model_service.CreateModelRequest, +): + transport_class = transports.ModelServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_model._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_model._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("dry_run",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.create_model(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_model._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("dryRun",)) + & set( + ( + "parent", + "model", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.ModelServiceRestInterceptor, "post_create_model" + ) as post, mock.patch.object( + transports.ModelServiceRestInterceptor, "pre_create_model" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.CreateModelRequest.pb( + model_service.CreateModelRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = model_service.CreateModelRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.create_model( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_model_rest_bad_request( + transport: str = "rest", request_type=model_service.CreateModelRequest +): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/catalogs/sample3"} + request_init["model"] = { + "name": "name_value", + "display_name": "display_name_value", + "training_state": 1, + "serving_state": 1, + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "type_": "type__value", + "optimization_objective": "optimization_objective_value", + "periodic_tuning_state": 1, + "last_tune_time": {}, + "tuning_operation": "tuning_operation_value", + "data_state": 1, + "filtering_option": 1, + "serving_config_lists": [ + { + "serving_config_ids": [ + "serving_config_ids_value1", + "serving_config_ids_value2", + ] + } + ], + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.create_model(request) + + +def test_create_model_rest_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "parent": "projects/sample1/locations/sample2/catalogs/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + model=gcr_model.Model(name="name_value"), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.create_model(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{parent=projects/*/locations/*/catalogs/*}/models" + % client.transport._host, + args[1], + ) + + +def test_create_model_rest_flattened_error(transport: str = "rest"): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_model( + model_service.CreateModelRequest(), + parent="parent_value", + model=gcr_model.Model(name="name_value"), + ) + + +def test_create_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + model_service.GetModelRequest, + dict, + ], +) +def test_get_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = model.Model( + name="name_value", + display_name="display_name_value", + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_="type__value", + optimization_objective="optimization_objective_value", + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation="tuning_operation_value", + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_model(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == "type__value" + assert response.optimization_objective == "optimization_objective_value" + assert ( + response.periodic_tuning_state + == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + ) + assert response.tuning_operation == "tuning_operation_value" + assert response.data_state == model.Model.DataState.DATA_OK + assert ( + response.filtering_option + == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + ) + + +def test_get_model_rest_required_fields(request_type=model_service.GetModelRequest): + transport_class = transports.ModelServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_model._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_model._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = model.Model() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_model(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ModelServiceRestInterceptor, "post_get_model" + ) as post, mock.patch.object( + transports.ModelServiceRestInterceptor, "pre_get_model" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.GetModelRequest.pb(model_service.GetModelRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = model.Model.to_json(model.Model()) + + request = model_service.GetModelRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = model.Model() + + client.get_model( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_model_rest_bad_request( + transport: str = "rest", request_type=model_service.GetModelRequest +): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_model(request) + + +def test_get_model_rest_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = model.Model() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.get_model(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=projects/*/locations/*/catalogs/*/models/*}" + % client.transport._host, + args[1], + ) + + +def test_get_model_rest_flattened_error(transport: str = "rest"): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_model( + model_service.GetModelRequest(), + name="name_value", + ) + + +def test_get_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + model_service.PauseModelRequest, + dict, + ], +) +def test_pause_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = model.Model( + name="name_value", + display_name="display_name_value", + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_="type__value", + optimization_objective="optimization_objective_value", + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation="tuning_operation_value", + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.pause_model(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == "type__value" + assert response.optimization_objective == "optimization_objective_value" + assert ( + response.periodic_tuning_state + == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + ) + assert response.tuning_operation == "tuning_operation_value" + assert response.data_state == model.Model.DataState.DATA_OK + assert ( + response.filtering_option + == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + ) + + +def test_pause_model_rest_required_fields(request_type=model_service.PauseModelRequest): + transport_class = transports.ModelServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).pause_model._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).pause_model._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = model.Model() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.pause_model(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_pause_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.pause_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_pause_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ModelServiceRestInterceptor, "post_pause_model" + ) as post, mock.patch.object( + transports.ModelServiceRestInterceptor, "pre_pause_model" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.PauseModelRequest.pb( + model_service.PauseModelRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = model.Model.to_json(model.Model()) + + request = model_service.PauseModelRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = model.Model() + + client.pause_model( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_pause_model_rest_bad_request( + transport: str = "rest", request_type=model_service.PauseModelRequest +): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.pause_model(request) + + +def test_pause_model_rest_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = model.Model() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.pause_model(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=projects/*/locations/*/catalogs/*/models/*}:pause" + % client.transport._host, + args[1], + ) + + +def test_pause_model_rest_flattened_error(transport: str = "rest"): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.pause_model( + model_service.PauseModelRequest(), + name="name_value", + ) + + +def test_pause_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + model_service.ResumeModelRequest, + dict, + ], +) +def test_resume_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = model.Model( + name="name_value", + display_name="display_name_value", + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_="type__value", + optimization_objective="optimization_objective_value", + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation="tuning_operation_value", + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.resume_model(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == "type__value" + assert response.optimization_objective == "optimization_objective_value" + assert ( + response.periodic_tuning_state + == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + ) + assert response.tuning_operation == "tuning_operation_value" + assert response.data_state == model.Model.DataState.DATA_OK + assert ( + response.filtering_option + == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + ) + + +def test_resume_model_rest_required_fields( + request_type=model_service.ResumeModelRequest, +): + transport_class = transports.ModelServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).resume_model._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).resume_model._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = model.Model() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.resume_model(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_resume_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.resume_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_resume_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ModelServiceRestInterceptor, "post_resume_model" + ) as post, mock.patch.object( + transports.ModelServiceRestInterceptor, "pre_resume_model" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.ResumeModelRequest.pb( + model_service.ResumeModelRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = model.Model.to_json(model.Model()) + + request = model_service.ResumeModelRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = model.Model() + + client.resume_model( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_resume_model_rest_bad_request( + transport: str = "rest", request_type=model_service.ResumeModelRequest +): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.resume_model(request) + + +def test_resume_model_rest_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = model.Model() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.resume_model(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=projects/*/locations/*/catalogs/*/models/*}:resume" + % client.transport._host, + args[1], + ) + + +def test_resume_model_rest_flattened_error(transport: str = "rest"): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.resume_model( + model_service.ResumeModelRequest(), + name="name_value", + ) + + +def test_resume_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + model_service.DeleteModelRequest, + dict, + ], +) +def test_delete_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.delete_model(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_model_rest_required_fields( + request_type=model_service.DeleteModelRequest, +): + transport_class = transports.ModelServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_model._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_model._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.delete_model(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_delete_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ModelServiceRestInterceptor, "pre_delete_model" + ) as pre: + pre.assert_not_called() + pb_message = model_service.DeleteModelRequest.pb( + model_service.DeleteModelRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = model_service.DeleteModelRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_model( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + + +def test_delete_model_rest_bad_request( + transport: str = "rest", request_type=model_service.DeleteModelRequest +): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_model(request) + + +def test_delete_model_rest_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.delete_model(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=projects/*/locations/*/catalogs/*/models/*}" + % client.transport._host, + args[1], + ) + + +def test_delete_model_rest_flattened_error(transport: str = "rest"): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_model( + model_service.DeleteModelRequest(), + name="name_value", + ) + + +def test_delete_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + model_service.ListModelsRequest, + dict, + ], +) +def test_list_models_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/catalogs/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = model_service.ListModelsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model_service.ListModelsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_models(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListModelsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_models_rest_required_fields(request_type=model_service.ListModelsRequest): + transport_class = transports.ModelServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_models._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_models._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = model_service.ListModelsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + pb_return_value = model_service.ListModelsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_models(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_models_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_models._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_models_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ModelServiceRestInterceptor, "post_list_models" + ) as post, mock.patch.object( + transports.ModelServiceRestInterceptor, "pre_list_models" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.ListModelsRequest.pb( + model_service.ListModelsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = model_service.ListModelsResponse.to_json( + model_service.ListModelsResponse() + ) + + request = model_service.ListModelsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = model_service.ListModelsResponse() + + client.list_models( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_models_rest_bad_request( + transport: str = "rest", request_type=model_service.ListModelsRequest +): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/catalogs/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_models(request) + + +def test_list_models_rest_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = model_service.ListModelsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = { + "parent": "projects/sample1/locations/sample2/catalogs/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model_service.ListModelsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_models(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{parent=projects/*/locations/*/catalogs/*}/models" + % client.transport._host, + args[1], + ) + + +def test_list_models_rest_flattened_error(transport: str = "rest"): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_models( + model_service.ListModelsRequest(), + parent="parent_value", + ) + + +def test_list_models_rest_pager(transport: str = "rest"): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + model.Model(), + ], + next_page_token="abc", + ), + model_service.ListModelsResponse( + models=[], + next_page_token="def", + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + ], + next_page_token="ghi", + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(model_service.ListModelsResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = { + "parent": "projects/sample1/locations/sample2/catalogs/sample3" + } + + pager = client.list_models(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, model.Model) for i in results) + + pages = list(client.list_models(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + model_service.UpdateModelRequest, + dict, + ], +) +def test_update_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "model": { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" + } + } + request_init["model"] = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4", + "display_name": "display_name_value", + "training_state": 1, + "serving_state": 1, + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "type_": "type__value", + "optimization_objective": "optimization_objective_value", + "periodic_tuning_state": 1, + "last_tune_time": {}, + "tuning_operation": "tuning_operation_value", + "data_state": 1, + "filtering_option": 1, + "serving_config_lists": [ + { + "serving_config_ids": [ + "serving_config_ids_value1", + "serving_config_ids_value2", + ] + } + ], + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcr_model.Model( + name="name_value", + display_name="display_name_value", + training_state=gcr_model.Model.TrainingState.PAUSED, + serving_state=gcr_model.Model.ServingState.INACTIVE, + type_="type__value", + optimization_objective="optimization_objective_value", + periodic_tuning_state=gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation="tuning_operation_value", + data_state=gcr_model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_model(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_model.Model) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.training_state == gcr_model.Model.TrainingState.PAUSED + assert response.serving_state == gcr_model.Model.ServingState.INACTIVE + assert response.type_ == "type__value" + assert response.optimization_objective == "optimization_objective_value" + assert ( + response.periodic_tuning_state + == gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + ) + assert response.tuning_operation == "tuning_operation_value" + assert response.data_state == gcr_model.Model.DataState.DATA_OK + assert ( + response.filtering_option + == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + ) + + +def test_update_model_rest_required_fields( + request_type=model_service.UpdateModelRequest, +): + transport_class = transports.ModelServiceRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_model._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_model._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_model.Model() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + pb_return_value = gcr_model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.update_model(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("model",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ModelServiceRestInterceptor, "post_update_model" + ) as post, mock.patch.object( + transports.ModelServiceRestInterceptor, "pre_update_model" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.UpdateModelRequest.pb( + model_service.UpdateModelRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = gcr_model.Model.to_json(gcr_model.Model()) + + request = model_service.UpdateModelRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_model.Model() + + client.update_model( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_model_rest_bad_request( + transport: str = "rest", request_type=model_service.UpdateModelRequest +): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "model": { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" + } + } + request_init["model"] = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4", + "display_name": "display_name_value", + "training_state": 1, + "serving_state": 1, + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "type_": "type__value", + "optimization_objective": "optimization_objective_value", + "periodic_tuning_state": 1, + "last_tune_time": {}, + "tuning_operation": "tuning_operation_value", + "data_state": 1, + "filtering_option": 1, + "serving_config_lists": [ + { + "serving_config_ids": [ + "serving_config_ids_value1", + "serving_config_ids_value2", + ] + } + ], + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.update_model(request) + + +def test_update_model_rest_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcr_model.Model() + + # get arguments that satisfy an http rule for this method + sample_request = { + "model": { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" + } + } + + # get truthy value for each flattened field + mock_args = dict( + model=gcr_model.Model(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.update_model(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{model.name=projects/*/locations/*/catalogs/*/models/*}" + % client.transport._host, + args[1], + ) + + +def test_update_model_rest_flattened_error(transport: str = "rest"): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_model( + model_service.UpdateModelRequest(), + model=gcr_model.Model(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_update_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + model_service.TuneModelRequest, + dict, + ], +) +def test_tune_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.tune_model(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_tune_model_rest_required_fields(request_type=model_service.TuneModelRequest): + transport_class = transports.ModelServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).tune_model._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).tune_model._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.tune_model(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_tune_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.tune_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_tune_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.ModelServiceRestInterceptor, "post_tune_model" + ) as post, mock.patch.object( + transports.ModelServiceRestInterceptor, "pre_tune_model" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.TuneModelRequest.pb(model_service.TuneModelRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = model_service.TuneModelRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.tune_model( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_tune_model_rest_bad_request( + transport: str = "rest", request_type=model_service.TuneModelRequest +): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.tune_model(request) + + +def test_tune_model_rest_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.tune_model(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=projects/*/locations/*/catalogs/*/models/*}:tune" + % client.transport._host, + args[1], + ) + + +def test_tune_model_rest_flattened_error(transport: str = "rest"): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.tune_model( + model_service.TuneModelRequest(), + name="name_value", + ) + + +def test_tune_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ModelServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ModelServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ModelServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ModelServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ModelServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ModelServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ModelServiceGrpcTransport, + transports.ModelServiceGrpcAsyncIOTransport, + transports.ModelServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "rest", + ], +) +def test_transport_kind(transport_name): + transport = ModelServiceClient.get_transport_class(transport_name)( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert transport.kind == transport_name + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ModelServiceGrpcTransport, + ) + + +def test_model_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ModelServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_model_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.cloud.retail_v2.services.model_service.transports.ModelServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.ModelServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "create_model", + "get_model", + "pause_model", + "resume_model", + "delete_model", + "list_models", + "update_model", + "tune_model", + "get_operation", + "list_operations", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_model_service_base_transport_with_credentials_file(): + # 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.retail_v2.services.model_service.transports.ModelServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ModelServiceTransport( + 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", + ) + + +def test_model_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.cloud.retail_v2.services.model_service.transports.ModelServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ModelServiceTransport() + adc.assert_called_once() + + +def test_model_service_auth_adc(): + # 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) + ModelServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ModelServiceGrpcTransport, + transports.ModelServiceGrpcAsyncIOTransport, + ], +) +def test_model_service_transport_auth_adc(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", 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.ModelServiceGrpcTransport, + transports.ModelServiceGrpcAsyncIOTransport, + transports.ModelServiceRestTransport, + ], +) +def test_model_service_transport_auth_gdch_credentials(transport_class): + host = "https://language.com" + api_audience_tests = [None, "https://language2.com"] + api_audience_expect = [host, "https://language2.com"] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, "default", autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock( + return_value=gdch_mock + ) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with(e) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.ModelServiceGrpcTransport, grpc_helpers), + (transports.ModelServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +def test_model_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( + "retail.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="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class", + [transports.ModelServiceGrpcTransport, transports.ModelServiceGrpcAsyncIOTransport], +) +def test_model_service_grpc_transport_client_cert_source_for_mtls(transport_class): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds, + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback, + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, private_key=expected_key + ) + + +def test_model_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.ModelServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +def test_model_service_rest_lro_client(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_model_service_host_no_port(transport_name): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="retail.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "retail.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://retail.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_model_service_host_with_port(transport_name): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="retail.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "retail.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://retail.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_model_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ModelServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ModelServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.create_model._session + session2 = client2.transport.create_model._session + assert session1 != session2 + session1 = client1.transport.get_model._session + session2 = client2.transport.get_model._session + assert session1 != session2 + session1 = client1.transport.pause_model._session + session2 = client2.transport.pause_model._session + assert session1 != session2 + session1 = client1.transport.resume_model._session + session2 = client2.transport.resume_model._session + assert session1 != session2 + session1 = client1.transport.delete_model._session + session2 = client2.transport.delete_model._session + assert session1 != session2 + session1 = client1.transport.list_models._session + session2 = client2.transport.list_models._session + assert session1 != session2 + session1 = client1.transport.update_model._session + session2 = client2.transport.update_model._session + assert session1 != session2 + session1 = client1.transport.tune_model._session + session2 = client2.transport.tune_model._session + assert session1 != session2 + + +def test_model_service_grpc_transport_channel(): + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ModelServiceGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_model_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ModelServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize( + "transport_class", + [transports.ModelServiceGrpcTransport, transports.ModelServiceGrpcAsyncIOTransport], +) +def test_model_service_transport_channel_mtls_with_client_cert_source(transport_class): + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel" + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize( + "transport_class", + [transports.ModelServiceGrpcTransport, transports.ModelServiceGrpcAsyncIOTransport], +) +def test_model_service_transport_channel_mtls_with_adc(transport_class): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object( + transport_class, "create_channel" + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_model_service_grpc_lro_client(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_model_service_grpc_lro_async_client(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsAsyncClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_catalog_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format( + project=project, + location=location, + catalog=catalog, + ) + actual = ModelServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = ModelServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_catalog_path(path) + assert expected == actual + + +def test_model_path(): + project = "cuttlefish" + location = "mussel" + catalog = "winkle" + model = "nautilus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/models/{model}".format( + project=project, + location=location, + catalog=catalog, + model=model, + ) + actual = ModelServiceClient.model_path(project, location, catalog, model) + assert expected == actual + + +def test_parse_model_path(): + expected = { + "project": "scallop", + "location": "abalone", + "catalog": "squid", + "model": "clam", + } + path = ModelServiceClient.model_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_model_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "whelk" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = ModelServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "octopus", + } + path = ModelServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "oyster" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = ModelServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nudibranch", + } + path = ModelServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "cuttlefish" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = ModelServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "mussel", + } + path = ModelServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "winkle" + expected = "projects/{project}".format( + project=project, + ) + actual = ModelServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nautilus", + } + path = ModelServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "scallop" + location = "abalone" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = ModelServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "squid", + "location": "clam", + } + path = ModelServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.ModelServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.ModelServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = ModelServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + with mock.patch.object( + type(getattr(client.transport, "grpc_channel")), "close" + ) as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_get_operation_rest_bad_request( + transport: str = "rest", request_type=operations_pb2.GetOperationRequest +): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/locations/sample2/operations/sample3"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "projects/sample1/locations/sample2/operations/sample3"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_list_operations_rest_bad_request( + transport: str = "rest", request_type=operations_pb2.ListOperationsRequest +): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/locations/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_operations(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.ListOperationsRequest, + dict, + ], +) +def test_list_operations_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.ListOperationsResponse() + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = ModelServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = ModelServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_get_operation_field_headers(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_get_operation_from_dict(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = ModelServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = ModelServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_list_operations_field_headers(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_list_operations_from_dict(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + with mock.patch.object( + type(getattr(client.transport, close_name)), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + "grpc", + ] + for transport in transports: + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (ModelServiceClient, transports.ModelServiceGrpcTransport), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-cloud-retail/tests/unit/gapic/retail_v2/test_search_service.py b/packages/google-cloud-retail/tests/unit/gapic/retail_v2/test_search_service.py index bd91898698be..5d20502add34 100644 --- a/packages/google-cloud-retail/tests/unit/gapic/retail_v2/test_search_service.py +++ b/packages/google-cloud-retail/tests/unit/gapic/retail_v2/test_search_service.py @@ -1916,12 +1916,41 @@ def test_parse_branch_path(): assert expected == actual -def test_product_path(): +def test_experiment_path(): project = "winkle" location = "nautilus" catalog = "scallop" - branch = "abalone" - product = "squid" + experiment = "abalone" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/experiments/{experiment}".format( + project=project, + location=location, + catalog=catalog, + experiment=experiment, + ) + actual = SearchServiceClient.experiment_path(project, location, catalog, experiment) + assert expected == actual + + +def test_parse_experiment_path(): + expected = { + "project": "squid", + "location": "clam", + "catalog": "whelk", + "experiment": "octopus", + } + path = SearchServiceClient.experiment_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_experiment_path(path) + assert expected == actual + + +def test_product_path(): + project = "oyster" + location = "nudibranch" + catalog = "cuttlefish" + branch = "mussel" + product = "winkle" expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format( project=project, location=location, @@ -1937,11 +1966,11 @@ def test_product_path(): def test_parse_product_path(): expected = { - "project": "clam", - "location": "whelk", - "catalog": "octopus", - "branch": "oyster", - "product": "nudibranch", + "project": "nautilus", + "location": "scallop", + "catalog": "abalone", + "branch": "squid", + "product": "clam", } path = SearchServiceClient.product_path(**expected) @@ -1950,8 +1979,39 @@ def test_parse_product_path(): assert expected == actual +def test_serving_config_path(): + project = "whelk" + location = "octopus" + catalog = "oyster" + serving_config = "nudibranch" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/servingConfigs/{serving_config}".format( + project=project, + location=location, + catalog=catalog, + serving_config=serving_config, + ) + actual = SearchServiceClient.serving_config_path( + project, location, catalog, serving_config + ) + assert expected == actual + + +def test_parse_serving_config_path(): + expected = { + "project": "cuttlefish", + "location": "mussel", + "catalog": "winkle", + "serving_config": "nautilus", + } + path = SearchServiceClient.serving_config_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_serving_config_path(path) + assert expected == actual + + def test_common_billing_account_path(): - billing_account = "cuttlefish" + billing_account = "scallop" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -1961,7 +2021,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "mussel", + "billing_account": "abalone", } path = SearchServiceClient.common_billing_account_path(**expected) @@ -1971,7 +2031,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "winkle" + folder = "squid" expected = "folders/{folder}".format( folder=folder, ) @@ -1981,7 +2041,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "nautilus", + "folder": "clam", } path = SearchServiceClient.common_folder_path(**expected) @@ -1991,7 +2051,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "scallop" + organization = "whelk" expected = "organizations/{organization}".format( organization=organization, ) @@ -2001,7 +2061,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "abalone", + "organization": "octopus", } path = SearchServiceClient.common_organization_path(**expected) @@ -2011,7 +2071,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "squid" + project = "oyster" expected = "projects/{project}".format( project=project, ) @@ -2021,7 +2081,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "clam", + "project": "nudibranch", } path = SearchServiceClient.common_project_path(**expected) @@ -2031,8 +2091,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "whelk" - location = "octopus" + project = "cuttlefish" + location = "mussel" expected = "projects/{project}/locations/{location}".format( project=project, location=location, @@ -2043,8 +2103,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "oyster", - "location": "nudibranch", + "project": "winkle", + "location": "nautilus", } path = SearchServiceClient.common_location_path(**expected) diff --git a/packages/google-cloud-retail/tests/unit/gapic/retail_v2/test_user_event_service.py b/packages/google-cloud-retail/tests/unit/gapic/retail_v2/test_user_event_service.py index 250719439216..f9563016d9fc 100644 --- a/packages/google-cloud-retail/tests/unit/gapic/retail_v2/test_user_event_service.py +++ b/packages/google-cloud-retail/tests/unit/gapic/retail_v2/test_user_event_service.py @@ -792,6 +792,7 @@ def test_write_user_event(request_type, transport: str = "grpc"): uri="uri_value", referrer_uri="referrer_uri_value", page_view_id="page_view_id_value", + entity="entity_value", ) response = client.write_user_event(request) @@ -816,6 +817,7 @@ def test_write_user_event(request_type, transport: str = "grpc"): assert response.uri == "uri_value" assert response.referrer_uri == "referrer_uri_value" assert response.page_view_id == "page_view_id_value" + assert response.entity == "entity_value" def test_write_user_event_empty_call(): @@ -867,6 +869,7 @@ async def test_write_user_event_async( uri="uri_value", referrer_uri="referrer_uri_value", page_view_id="page_view_id_value", + entity="entity_value", ) ) response = await client.write_user_event(request) @@ -892,6 +895,7 @@ async def test_write_user_event_async( assert response.uri == "uri_value" assert response.referrer_uri == "referrer_uri_value" assert response.page_view_id == "page_view_id_value" + assert response.entity == "entity_value" @pytest.mark.asyncio @@ -1726,6 +1730,7 @@ def test_write_user_event_rest(request_type): "uri": "uri_value", "referrer_uri": "referrer_uri_value", "page_view_id": "page_view_id_value", + "entity": "entity_value", } request = request_type(**request_init) @@ -1747,6 +1752,7 @@ def test_write_user_event_rest(request_type): uri="uri_value", referrer_uri="referrer_uri_value", page_view_id="page_view_id_value", + entity="entity_value", ) # Wrap the value into a proper Response obj @@ -1775,6 +1781,7 @@ def test_write_user_event_rest(request_type): assert response.uri == "uri_value" assert response.referrer_uri == "referrer_uri_value" assert response.page_view_id == "page_view_id_value" + assert response.entity == "entity_value" def test_write_user_event_rest_required_fields( @@ -2062,6 +2069,7 @@ def test_write_user_event_rest_bad_request( "uri": "uri_value", "referrer_uri": "referrer_uri_value", "page_view_id": "page_view_id_value", + "entity": "entity_value", } request = request_type(**request_init) diff --git a/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_completion_service.py b/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_completion_service.py index d29188b937a1..bceb6b25822e 100644 --- a/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_completion_service.py +++ b/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_completion_service.py @@ -1130,6 +1130,7 @@ def test_complete_query_rest_required_fields( "dataset", "device_type", "enable_attribute_suggestions", + "entity", "language_codes", "max_suggestions", "query", @@ -1202,6 +1203,7 @@ def test_complete_query_rest_unset_required_fields(): "dataset", "deviceType", "enableAttributeSuggestions", + "entity", "languageCodes", "maxSuggestions", "query", diff --git a/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_merchant_center_account_link_service.py b/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_merchant_center_account_link_service.py new file mode 100644 index 000000000000..cf357eda6752 --- /dev/null +++ b/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_merchant_center_account_link_service.py @@ -0,0 +1,3779 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import Iterable +import json +import math + +from google.api_core import ( + future, + gapic_v1, + grpc_helpers, + grpc_helpers_async, + operation, + operations_v1, + path_template, +) +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import operation_async # type: ignore +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.location import locations_pb2 +from google.longrunning import operations_pb2 +from google.oauth2 import service_account +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +from google.cloud.retail_v2alpha.services.merchant_center_account_link_service import ( + MerchantCenterAccountLinkServiceAsyncClient, + MerchantCenterAccountLinkServiceClient, + transports, +) +from google.cloud.retail_v2alpha.types import ( + merchant_center_account_link as gcr_merchant_center_account_link, +) +from google.cloud.retail_v2alpha.types import merchant_center_account_link_service +from google.cloud.retail_v2alpha.types import merchant_center_account_link + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert ( + MerchantCenterAccountLinkServiceClient._get_default_mtls_endpoint(None) is None + ) + assert ( + MerchantCenterAccountLinkServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + MerchantCenterAccountLinkServiceClient._get_default_mtls_endpoint( + api_mtls_endpoint + ) + == api_mtls_endpoint + ) + assert ( + MerchantCenterAccountLinkServiceClient._get_default_mtls_endpoint( + sandbox_endpoint + ) + == sandbox_mtls_endpoint + ) + assert ( + MerchantCenterAccountLinkServiceClient._get_default_mtls_endpoint( + sandbox_mtls_endpoint + ) + == sandbox_mtls_endpoint + ) + assert ( + MerchantCenterAccountLinkServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (MerchantCenterAccountLinkServiceClient, "grpc"), + (MerchantCenterAccountLinkServiceAsyncClient, "grpc_asyncio"), + (MerchantCenterAccountLinkServiceClient, "rest"), + ], +) +def test_merchant_center_account_link_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "retail.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://retail.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.MerchantCenterAccountLinkServiceGrpcTransport, "grpc"), + ( + transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + (transports.MerchantCenterAccountLinkServiceRestTransport, "rest"), + ], +) +def test_merchant_center_account_link_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (MerchantCenterAccountLinkServiceClient, "grpc"), + (MerchantCenterAccountLinkServiceAsyncClient, "grpc_asyncio"), + (MerchantCenterAccountLinkServiceClient, "rest"), + ], +) +def test_merchant_center_account_link_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "retail.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://retail.googleapis.com" + ) + + +def test_merchant_center_account_link_service_client_get_transport_class(): + transport = MerchantCenterAccountLinkServiceClient.get_transport_class() + available_transports = [ + transports.MerchantCenterAccountLinkServiceGrpcTransport, + transports.MerchantCenterAccountLinkServiceRestTransport, + ] + assert transport in available_transports + + transport = MerchantCenterAccountLinkServiceClient.get_transport_class("grpc") + assert transport == transports.MerchantCenterAccountLinkServiceGrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + MerchantCenterAccountLinkServiceClient, + transports.MerchantCenterAccountLinkServiceGrpcTransport, + "grpc", + ), + ( + MerchantCenterAccountLinkServiceAsyncClient, + transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ( + MerchantCenterAccountLinkServiceClient, + transports.MerchantCenterAccountLinkServiceRestTransport, + "rest", + ), + ], +) +@mock.patch.object( + MerchantCenterAccountLinkServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(MerchantCenterAccountLinkServiceClient), +) +@mock.patch.object( + MerchantCenterAccountLinkServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(MerchantCenterAccountLinkServiceAsyncClient), +) +def test_merchant_center_account_link_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object( + MerchantCenterAccountLinkServiceClient, "get_transport_class" + ) as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object( + MerchantCenterAccountLinkServiceClient, "get_transport_class" + ) as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class(transport=transport_name) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError): + client = client_class(transport=transport_name) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + MerchantCenterAccountLinkServiceClient, + transports.MerchantCenterAccountLinkServiceGrpcTransport, + "grpc", + "true", + ), + ( + MerchantCenterAccountLinkServiceAsyncClient, + transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + ( + MerchantCenterAccountLinkServiceClient, + transports.MerchantCenterAccountLinkServiceGrpcTransport, + "grpc", + "false", + ), + ( + MerchantCenterAccountLinkServiceAsyncClient, + transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ( + MerchantCenterAccountLinkServiceClient, + transports.MerchantCenterAccountLinkServiceRestTransport, + "rest", + "true", + ), + ( + MerchantCenterAccountLinkServiceClient, + transports.MerchantCenterAccountLinkServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + MerchantCenterAccountLinkServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(MerchantCenterAccountLinkServiceClient), +) +@mock.patch.object( + MerchantCenterAccountLinkServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(MerchantCenterAccountLinkServiceAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_merchant_center_account_link_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class", + [ + MerchantCenterAccountLinkServiceClient, + MerchantCenterAccountLinkServiceAsyncClient, + ], +) +@mock.patch.object( + MerchantCenterAccountLinkServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(MerchantCenterAccountLinkServiceClient), +) +@mock.patch.object( + MerchantCenterAccountLinkServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(MerchantCenterAccountLinkServiceAsyncClient), +) +def test_merchant_center_account_link_service_client_get_mtls_endpoint_and_cert_source( + client_class, +): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + MerchantCenterAccountLinkServiceClient, + transports.MerchantCenterAccountLinkServiceGrpcTransport, + "grpc", + ), + ( + MerchantCenterAccountLinkServiceAsyncClient, + transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ( + MerchantCenterAccountLinkServiceClient, + transports.MerchantCenterAccountLinkServiceRestTransport, + "rest", + ), + ], +) +def test_merchant_center_account_link_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + MerchantCenterAccountLinkServiceClient, + transports.MerchantCenterAccountLinkServiceGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + MerchantCenterAccountLinkServiceAsyncClient, + transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ( + MerchantCenterAccountLinkServiceClient, + transports.MerchantCenterAccountLinkServiceRestTransport, + "rest", + None, + ), + ], +) +def test_merchant_center_account_link_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_merchant_center_account_link_service_client_client_options_from_dict(): + with mock.patch( + "google.cloud.retail_v2alpha.services.merchant_center_account_link_service.transports.MerchantCenterAccountLinkServiceGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = MerchantCenterAccountLinkServiceClient( + client_options={"api_endpoint": "squid.clam.whelk"} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + MerchantCenterAccountLinkServiceClient, + transports.MerchantCenterAccountLinkServiceGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + MerchantCenterAccountLinkServiceAsyncClient, + transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ], +) +def test_merchant_center_account_link_service_client_create_channel_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel" + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "request_type", + [ + merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest, + dict, + ], +) +def test_list_merchant_center_account_links(request_type, transport: str = "grpc"): + client = MerchantCenterAccountLinkServiceClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_merchant_center_account_links), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse() + ) + response = client.list_merchant_center_account_links(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert ( + args[0] + == merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest() + ) + + # Establish that the response is the type that we expect. + assert isinstance( + response, + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse, + ) + + +def test_list_merchant_center_account_links_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 = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_merchant_center_account_links), "__call__" + ) as call: + client.list_merchant_center_account_links() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert ( + args[0] + == merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest() + ) + + +@pytest.mark.asyncio +async def test_list_merchant_center_account_links_async( + transport: str = "grpc_asyncio", + request_type=merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest, +): + client = MerchantCenterAccountLinkServiceAsyncClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_merchant_center_account_links), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse() + ) + response = await client.list_merchant_center_account_links(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert ( + args[0] + == merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest() + ) + + # Establish that the response is the type that we expect. + assert isinstance( + response, + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse, + ) + + +@pytest.mark.asyncio +async def test_list_merchant_center_account_links_async_from_dict(): + await test_list_merchant_center_account_links_async(request_type=dict) + + +def test_list_merchant_center_account_links_field_headers(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = ( + merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest() + ) + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_merchant_center_account_links), "__call__" + ) as call: + call.return_value = ( + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse() + ) + client.list_merchant_center_account_links(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_merchant_center_account_links_field_headers_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = ( + merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest() + ) + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_merchant_center_account_links), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse() + ) + await client.list_merchant_center_account_links(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_list_merchant_center_account_links_flattened(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_merchant_center_account_links), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_merchant_center_account_links( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +def test_list_merchant_center_account_links_flattened_error(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_merchant_center_account_links( + merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_merchant_center_account_links_flattened_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_merchant_center_account_links), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse() + ) + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_merchant_center_account_links( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_list_merchant_center_account_links_flattened_error_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_merchant_center_account_links( + merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest(), + parent="parent_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest, + dict, + ], +) +def test_create_merchant_center_account_link(request_type, transport: str = "grpc"): + client = MerchantCenterAccountLinkServiceClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_merchant_center_account_link), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.create_merchant_center_account_link(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert ( + args[0] + == merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest() + ) + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_create_merchant_center_account_link_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 = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_merchant_center_account_link), "__call__" + ) as call: + client.create_merchant_center_account_link() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert ( + args[0] + == merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest() + ) + + +@pytest.mark.asyncio +async def test_create_merchant_center_account_link_async( + transport: str = "grpc_asyncio", + request_type=merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest, +): + client = MerchantCenterAccountLinkServiceAsyncClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_merchant_center_account_link), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.create_merchant_center_account_link(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert ( + args[0] + == merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest() + ) + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_create_merchant_center_account_link_async_from_dict(): + await test_create_merchant_center_account_link_async(request_type=dict) + + +def test_create_merchant_center_account_link_field_headers(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = ( + merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest() + ) + + request.merchant_center_account_link.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_merchant_center_account_link), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_merchant_center_account_link(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "merchant_center_account_link.name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_create_merchant_center_account_link_field_headers_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = ( + merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest() + ) + + request.merchant_center_account_link.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_merchant_center_account_link), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.create_merchant_center_account_link(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "merchant_center_account_link.name=name_value", + ) in kw["metadata"] + + +def test_create_merchant_center_account_link_flattened(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_merchant_center_account_link), "__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.create_merchant_center_account_link( + parent="parent_value", + merchant_center_account_link=gcr_merchant_center_account_link.MerchantCenterAccountLink( + name="name_value" + ), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].merchant_center_account_link + mock_val = gcr_merchant_center_account_link.MerchantCenterAccountLink( + name="name_value" + ) + assert arg == mock_val + + +def test_create_merchant_center_account_link_flattened_error(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_merchant_center_account_link( + merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest(), + parent="parent_value", + merchant_center_account_link=gcr_merchant_center_account_link.MerchantCenterAccountLink( + name="name_value" + ), + ) + + +@pytest.mark.asyncio +async def test_create_merchant_center_account_link_flattened_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_merchant_center_account_link), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_merchant_center_account_link( + parent="parent_value", + merchant_center_account_link=gcr_merchant_center_account_link.MerchantCenterAccountLink( + name="name_value" + ), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].merchant_center_account_link + mock_val = gcr_merchant_center_account_link.MerchantCenterAccountLink( + name="name_value" + ) + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_create_merchant_center_account_link_flattened_error_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_merchant_center_account_link( + merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest(), + parent="parent_value", + merchant_center_account_link=gcr_merchant_center_account_link.MerchantCenterAccountLink( + name="name_value" + ), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest, + dict, + ], +) +def test_delete_merchant_center_account_link(request_type, transport: str = "grpc"): + client = MerchantCenterAccountLinkServiceClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_merchant_center_account_link), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_merchant_center_account_link(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert ( + args[0] + == merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest() + ) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_merchant_center_account_link_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 = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_merchant_center_account_link), "__call__" + ) as call: + client.delete_merchant_center_account_link() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert ( + args[0] + == merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest() + ) + + +@pytest.mark.asyncio +async def test_delete_merchant_center_account_link_async( + transport: str = "grpc_asyncio", + request_type=merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest, +): + client = MerchantCenterAccountLinkServiceAsyncClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_merchant_center_account_link), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_merchant_center_account_link(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert ( + args[0] + == merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest() + ) + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_merchant_center_account_link_async_from_dict(): + await test_delete_merchant_center_account_link_async(request_type=dict) + + +def test_delete_merchant_center_account_link_field_headers(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = ( + merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest() + ) + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_merchant_center_account_link), "__call__" + ) as call: + call.return_value = None + client.delete_merchant_center_account_link(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_delete_merchant_center_account_link_field_headers_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = ( + merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest() + ) + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_merchant_center_account_link), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_merchant_center_account_link(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_delete_merchant_center_account_link_flattened(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_merchant_center_account_link), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_merchant_center_account_link( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_delete_merchant_center_account_link_flattened_error(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_merchant_center_account_link( + merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_delete_merchant_center_account_link_flattened_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_merchant_center_account_link), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_merchant_center_account_link( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_delete_merchant_center_account_link_flattened_error_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_merchant_center_account_link( + merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest, + dict, + ], +) +def test_list_merchant_center_account_links_rest(request_type): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/catalogs/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = ( + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse() + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_merchant_center_account_links(request) + + # Establish that the response is the type that we expect. + assert isinstance( + response, + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse, + ) + + +def test_list_merchant_center_account_links_rest_required_fields( + request_type=merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest, +): + transport_class = transports.MerchantCenterAccountLinkServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_merchant_center_account_links._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_merchant_center_account_links._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = ( + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse() + ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + pb_return_value = merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_merchant_center_account_links(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_merchant_center_account_links_rest_unset_required_fields(): + transport = transports.MerchantCenterAccountLinkServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.list_merchant_center_account_links._get_unset_required_fields({}) + ) + assert set(unset_fields) == (set(()) & set(("parent",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_merchant_center_account_links_rest_interceptors(null_interceptor): + transport = transports.MerchantCenterAccountLinkServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.MerchantCenterAccountLinkServiceRestInterceptor(), + ) + client = MerchantCenterAccountLinkServiceClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.MerchantCenterAccountLinkServiceRestInterceptor, + "post_list_merchant_center_account_links", + ) as post, mock.patch.object( + transports.MerchantCenterAccountLinkServiceRestInterceptor, + "pre_list_merchant_center_account_links", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest.pb( + merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse.to_json( + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse() + ) + + request = ( + merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest() + ) + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = ( + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse() + ) + + client.list_merchant_center_account_links( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_merchant_center_account_links_rest_bad_request( + transport: str = "rest", + request_type=merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest, +): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/catalogs/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_merchant_center_account_links(request) + + +def test_list_merchant_center_account_links_rest_flattened(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = ( + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse() + ) + + # get arguments that satisfy an http rule for this method + sample_request = { + "parent": "projects/sample1/locations/sample2/catalogs/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_merchant_center_account_links(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2alpha/{parent=projects/*/locations/*/catalogs/*}/merchantCenterAccountLinks" + % client.transport._host, + args[1], + ) + + +def test_list_merchant_center_account_links_rest_flattened_error( + transport: str = "rest", +): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_merchant_center_account_links( + merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest(), + parent="parent_value", + ) + + +def test_list_merchant_center_account_links_rest_error(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest, + dict, + ], +) +def test_create_merchant_center_account_link_rest(request_type): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "merchant_center_account_link": { + "name": "projects/sample1/locations/sample2/catalogs/sample3/merchantCenterAccountLinks/sample4" + } + } + request_init["merchant_center_account_link"] = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/merchantCenterAccountLinks/sample4", + "id": "id_value", + "merchant_center_account_id": 2730, + "branch_id": "branch_id_value", + "feed_label": "feed_label_value", + "language_code": "language_code_value", + "feed_filters": [ + {"primary_feed_id": 1571, "primary_feed_name": "primary_feed_name_value"} + ], + "state": 1, + "project_id": "project_id_value", + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_merchant_center_account_link(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_create_merchant_center_account_link_rest_required_fields( + request_type=merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest, +): + transport_class = transports.MerchantCenterAccountLinkServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + assert "parent" not in jsonified_request + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_merchant_center_account_link._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "parent" in jsonified_request + assert jsonified_request["parent"] == request_init["parent"] + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_merchant_center_account_link._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("parent",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.create_merchant_center_account_link(request) + + expected_params = [ + ( + "parent", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_merchant_center_account_link_rest_unset_required_fields(): + transport = transports.MerchantCenterAccountLinkServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.create_merchant_center_account_link._get_unset_required_fields({}) + ) + assert set(unset_fields) == ( + set(("parent",)) + & set( + ( + "parent", + "merchantCenterAccountLink", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_merchant_center_account_link_rest_interceptors(null_interceptor): + transport = transports.MerchantCenterAccountLinkServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.MerchantCenterAccountLinkServiceRestInterceptor(), + ) + client = MerchantCenterAccountLinkServiceClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.MerchantCenterAccountLinkServiceRestInterceptor, + "post_create_merchant_center_account_link", + ) as post, mock.patch.object( + transports.MerchantCenterAccountLinkServiceRestInterceptor, + "pre_create_merchant_center_account_link", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest.pb( + merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = ( + merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest() + ) + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.create_merchant_center_account_link( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_merchant_center_account_link_rest_bad_request( + transport: str = "rest", + request_type=merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest, +): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "merchant_center_account_link": { + "name": "projects/sample1/locations/sample2/catalogs/sample3/merchantCenterAccountLinks/sample4" + } + } + request_init["merchant_center_account_link"] = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/merchantCenterAccountLinks/sample4", + "id": "id_value", + "merchant_center_account_id": 2730, + "branch_id": "branch_id_value", + "feed_label": "feed_label_value", + "language_code": "language_code_value", + "feed_filters": [ + {"primary_feed_id": 1571, "primary_feed_name": "primary_feed_name_value"} + ], + "state": 1, + "project_id": "project_id_value", + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.create_merchant_center_account_link(request) + + +def test_create_merchant_center_account_link_rest_flattened(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "merchant_center_account_link": { + "name": "projects/sample1/locations/sample2/catalogs/sample3/merchantCenterAccountLinks/sample4" + } + } + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + merchant_center_account_link=gcr_merchant_center_account_link.MerchantCenterAccountLink( + name="name_value" + ), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.create_merchant_center_account_link(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2alpha/{merchant_center_account_link.name=projects/*/locations/*/catalogs/*/merchantCenterAccountLinks/*}" + % client.transport._host, + args[1], + ) + + +def test_create_merchant_center_account_link_rest_flattened_error( + transport: str = "rest", +): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_merchant_center_account_link( + merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest(), + parent="parent_value", + merchant_center_account_link=gcr_merchant_center_account_link.MerchantCenterAccountLink( + name="name_value" + ), + ) + + +def test_create_merchant_center_account_link_rest_error(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest, + dict, + ], +) +def test_delete_merchant_center_account_link_rest(request_type): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/merchantCenterAccountLinks/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.delete_merchant_center_account_link(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_merchant_center_account_link_rest_required_fields( + request_type=merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest, +): + transport_class = transports.MerchantCenterAccountLinkServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_merchant_center_account_link._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_merchant_center_account_link._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.delete_merchant_center_account_link(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_delete_merchant_center_account_link_rest_unset_required_fields(): + transport = transports.MerchantCenterAccountLinkServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.delete_merchant_center_account_link._get_unset_required_fields({}) + ) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_merchant_center_account_link_rest_interceptors(null_interceptor): + transport = transports.MerchantCenterAccountLinkServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.MerchantCenterAccountLinkServiceRestInterceptor(), + ) + client = MerchantCenterAccountLinkServiceClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.MerchantCenterAccountLinkServiceRestInterceptor, + "pre_delete_merchant_center_account_link", + ) as pre: + pre.assert_not_called() + pb_message = merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest.pb( + merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = ( + merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest() + ) + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_merchant_center_account_link( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + + +def test_delete_merchant_center_account_link_rest_bad_request( + transport: str = "rest", + request_type=merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest, +): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/merchantCenterAccountLinks/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_merchant_center_account_link(request) + + +def test_delete_merchant_center_account_link_rest_flattened(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/merchantCenterAccountLinks/sample4" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.delete_merchant_center_account_link(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2alpha/{name=projects/*/locations/*/catalogs/*/merchantCenterAccountLinks/*}" + % client.transport._host, + args[1], + ) + + +def test_delete_merchant_center_account_link_rest_flattened_error( + transport: str = "rest", +): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_merchant_center_account_link( + merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest(), + name="name_value", + ) + + +def test_delete_merchant_center_account_link_rest_error(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.MerchantCenterAccountLinkServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.MerchantCenterAccountLinkServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = MerchantCenterAccountLinkServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.MerchantCenterAccountLinkServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = MerchantCenterAccountLinkServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = MerchantCenterAccountLinkServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.MerchantCenterAccountLinkServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = MerchantCenterAccountLinkServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.MerchantCenterAccountLinkServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = MerchantCenterAccountLinkServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.MerchantCenterAccountLinkServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.MerchantCenterAccountLinkServiceGrpcTransport, + transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, + transports.MerchantCenterAccountLinkServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "rest", + ], +) +def test_transport_kind(transport_name): + transport = MerchantCenterAccountLinkServiceClient.get_transport_class( + transport_name + )( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert transport.kind == transport_name + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.MerchantCenterAccountLinkServiceGrpcTransport, + ) + + +def test_merchant_center_account_link_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.MerchantCenterAccountLinkServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_merchant_center_account_link_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.cloud.retail_v2alpha.services.merchant_center_account_link_service.transports.MerchantCenterAccountLinkServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.MerchantCenterAccountLinkServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "list_merchant_center_account_links", + "create_merchant_center_account_link", + "delete_merchant_center_account_link", + "get_operation", + "list_operations", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_merchant_center_account_link_service_base_transport_with_credentials_file(): + # 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.retail_v2alpha.services.merchant_center_account_link_service.transports.MerchantCenterAccountLinkServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.MerchantCenterAccountLinkServiceTransport( + 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", + ) + + +def test_merchant_center_account_link_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.cloud.retail_v2alpha.services.merchant_center_account_link_service.transports.MerchantCenterAccountLinkServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.MerchantCenterAccountLinkServiceTransport() + adc.assert_called_once() + + +def test_merchant_center_account_link_service_auth_adc(): + # 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) + MerchantCenterAccountLinkServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.MerchantCenterAccountLinkServiceGrpcTransport, + transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, + ], +) +def test_merchant_center_account_link_service_transport_auth_adc(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", 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.MerchantCenterAccountLinkServiceGrpcTransport, + transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, + transports.MerchantCenterAccountLinkServiceRestTransport, + ], +) +def test_merchant_center_account_link_service_transport_auth_gdch_credentials( + transport_class, +): + host = "https://language.com" + api_audience_tests = [None, "https://language2.com"] + api_audience_expect = [host, "https://language2.com"] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, "default", autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock( + return_value=gdch_mock + ) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with(e) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.MerchantCenterAccountLinkServiceGrpcTransport, grpc_helpers), + ( + transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, + grpc_helpers_async, + ), + ], +) +def test_merchant_center_account_link_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( + "retail.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="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.MerchantCenterAccountLinkServiceGrpcTransport, + transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, + ], +) +def test_merchant_center_account_link_service_grpc_transport_client_cert_source_for_mtls( + transport_class, +): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds, + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback, + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, private_key=expected_key + ) + + +def test_merchant_center_account_link_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.MerchantCenterAccountLinkServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +def test_merchant_center_account_link_service_rest_lro_client(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_merchant_center_account_link_service_host_no_port(transport_name): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="retail.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "retail.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://retail.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_merchant_center_account_link_service_host_with_port(transport_name): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="retail.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "retail.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://retail.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_merchant_center_account_link_service_client_transport_session_collision( + transport_name, +): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = MerchantCenterAccountLinkServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = MerchantCenterAccountLinkServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.list_merchant_center_account_links._session + session2 = client2.transport.list_merchant_center_account_links._session + assert session1 != session2 + session1 = client1.transport.create_merchant_center_account_link._session + session2 = client2.transport.create_merchant_center_account_link._session + assert session1 != session2 + session1 = client1.transport.delete_merchant_center_account_link._session + session2 = client2.transport.delete_merchant_center_account_link._session + assert session1 != session2 + + +def test_merchant_center_account_link_service_grpc_transport_channel(): + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.MerchantCenterAccountLinkServiceGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_merchant_center_account_link_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize( + "transport_class", + [ + transports.MerchantCenterAccountLinkServiceGrpcTransport, + transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, + ], +) +def test_merchant_center_account_link_service_transport_channel_mtls_with_client_cert_source( + transport_class, +): + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel" + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize( + "transport_class", + [ + transports.MerchantCenterAccountLinkServiceGrpcTransport, + transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, + ], +) +def test_merchant_center_account_link_service_transport_channel_mtls_with_adc( + transport_class, +): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object( + transport_class, "create_channel" + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_merchant_center_account_link_service_grpc_lro_client(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_merchant_center_account_link_service_grpc_lro_async_client(): + client = MerchantCenterAccountLinkServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsAsyncClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_catalog_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format( + project=project, + location=location, + catalog=catalog, + ) + actual = MerchantCenterAccountLinkServiceClient.catalog_path( + project, location, catalog + ) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = MerchantCenterAccountLinkServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = MerchantCenterAccountLinkServiceClient.parse_catalog_path(path) + assert expected == actual + + +def test_merchant_center_account_link_path(): + project = "cuttlefish" + location = "mussel" + catalog = "winkle" + merchant_center_account_link = "nautilus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/merchantCenterAccountLinks/{merchant_center_account_link}".format( + project=project, + location=location, + catalog=catalog, + merchant_center_account_link=merchant_center_account_link, + ) + actual = MerchantCenterAccountLinkServiceClient.merchant_center_account_link_path( + project, location, catalog, merchant_center_account_link + ) + assert expected == actual + + +def test_parse_merchant_center_account_link_path(): + expected = { + "project": "scallop", + "location": "abalone", + "catalog": "squid", + "merchant_center_account_link": "clam", + } + path = MerchantCenterAccountLinkServiceClient.merchant_center_account_link_path( + **expected + ) + + # Check that the path construction is reversible. + actual = ( + MerchantCenterAccountLinkServiceClient.parse_merchant_center_account_link_path( + path + ) + ) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "whelk" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = MerchantCenterAccountLinkServiceClient.common_billing_account_path( + billing_account + ) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "octopus", + } + path = MerchantCenterAccountLinkServiceClient.common_billing_account_path( + **expected + ) + + # Check that the path construction is reversible. + actual = MerchantCenterAccountLinkServiceClient.parse_common_billing_account_path( + path + ) + assert expected == actual + + +def test_common_folder_path(): + folder = "oyster" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = MerchantCenterAccountLinkServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nudibranch", + } + path = MerchantCenterAccountLinkServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = MerchantCenterAccountLinkServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "cuttlefish" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = MerchantCenterAccountLinkServiceClient.common_organization_path( + organization + ) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "mussel", + } + path = MerchantCenterAccountLinkServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = MerchantCenterAccountLinkServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "winkle" + expected = "projects/{project}".format( + project=project, + ) + actual = MerchantCenterAccountLinkServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nautilus", + } + path = MerchantCenterAccountLinkServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = MerchantCenterAccountLinkServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "scallop" + location = "abalone" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = MerchantCenterAccountLinkServiceClient.common_location_path( + project, location + ) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "squid", + "location": "clam", + } + path = MerchantCenterAccountLinkServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = MerchantCenterAccountLinkServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.MerchantCenterAccountLinkServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.MerchantCenterAccountLinkServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = MerchantCenterAccountLinkServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + with mock.patch.object( + type(getattr(client.transport, "grpc_channel")), "close" + ) as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_get_operation_rest_bad_request( + transport: str = "rest", request_type=operations_pb2.GetOperationRequest +): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict( + { + "name": "projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5" + }, + request, + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5" + } + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_list_operations_rest_bad_request( + transport: str = "rest", request_type=operations_pb2.ListOperationsRequest +): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/locations/sample2/catalogs/sample3"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_operations(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.ListOperationsRequest, + dict, + ], +) +def test_list_operations_rest(request_type): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "projects/sample1/locations/sample2/catalogs/sample3"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.ListOperationsResponse() + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = MerchantCenterAccountLinkServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = MerchantCenterAccountLinkServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_get_operation_field_headers(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_get_operation_from_dict(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = MerchantCenterAccountLinkServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = MerchantCenterAccountLinkServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_list_operations_field_headers(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_list_operations_from_dict(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + with mock.patch.object( + type(getattr(client.transport, close_name)), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + "grpc", + ] + for transport in transports: + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + ( + MerchantCenterAccountLinkServiceClient, + transports.MerchantCenterAccountLinkServiceGrpcTransport, + ), + ( + MerchantCenterAccountLinkServiceAsyncClient, + transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, + ), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_model_service.py b/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_model_service.py index 13ca9335a34b..f5b5116e5bdc 100644 --- a/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_model_service.py +++ b/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_model_service.py @@ -965,6 +965,285 @@ async def test_create_model_flattened_error_async(): ) +@pytest.mark.parametrize( + "request_type", + [ + model_service.GetModelRequest, + dict, + ], +) +def test_get_model(request_type, transport: str = "grpc"): + client = ModelServiceClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model( + name="name_value", + display_name="display_name_value", + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_="type__value", + optimization_objective="optimization_objective_value", + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation="tuning_operation_value", + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + page_optimization_config=model.Model.PageOptimizationConfig( + page_optimization_event_type="page_optimization_event_type_value" + ), + ) + response = client.get_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.GetModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == "type__value" + assert response.optimization_objective == "optimization_objective_value" + assert ( + response.periodic_tuning_state + == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + ) + assert response.tuning_operation == "tuning_operation_value" + assert response.data_state == model.Model.DataState.DATA_OK + assert ( + response.filtering_option + == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + ) + + +def test_get_model_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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_model), "__call__") as call: + client.get_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.GetModelRequest() + + +@pytest.mark.asyncio +async def test_get_model_async( + transport: str = "grpc_asyncio", request_type=model_service.GetModelRequest +): + client = ModelServiceAsyncClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + model.Model( + name="name_value", + display_name="display_name_value", + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_="type__value", + optimization_objective="optimization_objective_value", + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation="tuning_operation_value", + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + ) + response = await client.get_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.GetModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == "type__value" + assert response.optimization_objective == "optimization_objective_value" + assert ( + response.periodic_tuning_state + == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + ) + assert response.tuning_operation == "tuning_operation_value" + assert response.data_state == model.Model.DataState.DATA_OK + assert ( + response.filtering_option + == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + ) + + +@pytest.mark.asyncio +async def test_get_model_async_from_dict(): + await test_get_model_async(request_type=dict) + + +def test_get_model_field_headers(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = model_service.GetModelRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_model), "__call__") as call: + call.return_value = model.Model() + client.get_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_model_field_headers_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = model_service.GetModelRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_model), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + await client.get_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_get_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_model( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_get_model_flattened_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_model( + model_service.GetModelRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_model( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_get_model_flattened_error_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_model( + model_service.GetModelRequest(), + name="name_value", + ) + + @pytest.mark.parametrize( "request_type", [ @@ -2664,120 +2943,471 @@ async def test_tune_model_flattened_async(): credentials=ga_credentials.AnonymousCredentials(), ) - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.tune_model), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation(name="operations/op") + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.tune_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.tune_model( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_tune_model_flattened_error_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.tune_model( + model_service.TuneModelRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + model_service.CreateModelRequest, + dict, + ], +) +def test_create_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/catalogs/sample3"} + request_init["model"] = { + "page_optimization_config": { + "page_optimization_event_type": "page_optimization_event_type_value", + "panels": [ + { + "display_name": "display_name_value", + "candidates": [{"serving_config_id": "serving_config_id_value"}], + "default_candidate": {}, + } + ], + "restriction": 1, + }, + "name": "name_value", + "display_name": "display_name_value", + "training_state": 1, + "serving_state": 1, + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "type_": "type__value", + "optimization_objective": "optimization_objective_value", + "periodic_tuning_state": 1, + "last_tune_time": {}, + "tuning_operation": "tuning_operation_value", + "data_state": 1, + "filtering_option": 1, + "serving_config_lists": [ + { + "serving_config_ids": [ + "serving_config_ids_value1", + "serving_config_ids_value2", + ] + } + ], + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_model(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_create_model_rest_required_fields( + request_type=model_service.CreateModelRequest, +): + transport_class = transports.ModelServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_model._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_model._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("dry_run",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.create_model(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_model._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("dryRun",)) + & set( + ( + "parent", + "model", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.ModelServiceRestInterceptor, "post_create_model" + ) as post, mock.patch.object( + transports.ModelServiceRestInterceptor, "pre_create_model" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.CreateModelRequest.pb( + model_service.CreateModelRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = model_service.CreateModelRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.create_model( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_model_rest_bad_request( + transport: str = "rest", request_type=model_service.CreateModelRequest +): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/catalogs/sample3"} + request_init["model"] = { + "page_optimization_config": { + "page_optimization_event_type": "page_optimization_event_type_value", + "panels": [ + { + "display_name": "display_name_value", + "candidates": [{"serving_config_id": "serving_config_id_value"}], + "default_candidate": {}, + } + ], + "restriction": 1, + }, + "name": "name_value", + "display_name": "display_name_value", + "training_state": 1, + "serving_state": 1, + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "type_": "type__value", + "optimization_objective": "optimization_objective_value", + "periodic_tuning_state": 1, + "last_tune_time": {}, + "tuning_operation": "tuning_operation_value", + "data_state": 1, + "filtering_option": 1, + "serving_config_lists": [ + { + "serving_config_ids": [ + "serving_config_ids_value1", + "serving_config_ids_value2", + ] + } + ], + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.create_model(request) + + +def test_create_model_rest_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "parent": "projects/sample1/locations/sample2/catalogs/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + model=gcr_model.Model( + page_optimization_config=gcr_model.Model.PageOptimizationConfig( + page_optimization_event_type="page_optimization_event_type_value" + ) + ), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.tune_model( - name="name_value", - ) + client.create_model(**mock_args) # Establish that the underlying call was made with the expected # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].name - mock_val = "name_value" - assert arg == mock_val + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2alpha/{parent=projects/*/locations/*/catalogs/*}/models" + % client.transport._host, + args[1], + ) -@pytest.mark.asyncio -async def test_tune_model_flattened_error_async(): - client = ModelServiceAsyncClient( +def test_create_model_rest_flattened_error(transport: str = "rest"): + client = ModelServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - await client.tune_model( - model_service.TuneModelRequest(), - name="name_value", + client.create_model( + model_service.CreateModelRequest(), + parent="parent_value", + model=gcr_model.Model( + page_optimization_config=gcr_model.Model.PageOptimizationConfig( + page_optimization_event_type="page_optimization_event_type_value" + ) + ), ) +def test_create_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + @pytest.mark.parametrize( "request_type", [ - model_service.CreateModelRequest, + model_service.GetModelRequest, dict, ], ) -def test_create_model_rest(request_type): +def test_get_model_rest(request_type): client = ModelServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/catalogs/sample3"} - request_init["model"] = { - "page_optimization_config": { - "page_optimization_event_type": "page_optimization_event_type_value", - "panels": [ - { - "display_name": "display_name_value", - "candidates": [{"serving_config_id": "serving_config_id_value"}], - "default_candidate": {}, - } - ], - "restriction": 1, - }, - "name": "name_value", - "display_name": "display_name_value", - "training_state": 1, - "serving_state": 1, - "create_time": {"seconds": 751, "nanos": 543}, - "update_time": {}, - "type_": "type__value", - "optimization_objective": "optimization_objective_value", - "periodic_tuning_state": 1, - "last_tune_time": {}, - "tuning_operation": "tuning_operation_value", - "data_state": 1, - "filtering_option": 1, - "serving_config_lists": [ - { - "serving_config_ids": [ - "serving_config_ids_value1", - "serving_config_ids_value2", - ] - } - ], + request_init = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = model.Model( + name="name_value", + display_name="display_name_value", + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_="type__value", + optimization_objective="optimization_objective_value", + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation="tuning_operation_value", + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + page_optimization_config=model.Model.PageOptimizationConfig( + page_optimization_event_type="page_optimization_event_type_value" + ), + ) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.create_model(request) + response = client.get_model(request) # Establish that the response is the type that we expect. - assert response.operation.name == "operations/spam" + assert isinstance(response, model.Model) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == "type__value" + assert response.optimization_objective == "optimization_objective_value" + assert ( + response.periodic_tuning_state + == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + ) + assert response.tuning_operation == "tuning_operation_value" + assert response.data_state == model.Model.DataState.DATA_OK + assert ( + response.filtering_option + == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + ) -def test_create_model_rest_required_fields( - request_type=model_service.CreateModelRequest, -): +def test_get_model_rest_required_fields(request_type=model_service.GetModelRequest): transport_class = transports.ModelServiceRestTransport request_init = {} - request_init["parent"] = "" + request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -2792,23 +3422,21 @@ def test_create_model_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_model._get_unset_required_fields(jsonified_request) + ).get_model._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["parent"] = "parent_value" + jsonified_request["name"] = "name_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_model._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("dry_run",)) + ).get_model._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" client = ModelServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -2817,7 +3445,7 @@ def test_create_model_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = model.Model() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -2829,45 +3457,38 @@ def test_create_model_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "post", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) + + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.create_model(request) + response = client.get_model(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert expected_params == actual_params -def test_create_model_rest_unset_required_fields(): +def test_get_model_rest_unset_required_fields(): transport = transports.ModelServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.create_model._get_unset_required_fields({}) - assert set(unset_fields) == ( - set(("dryRun",)) - & set( - ( - "parent", - "model", - ) - ) - ) + unset_fields = transport.get_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_model_rest_interceptors(null_interceptor): +def test_get_model_rest_interceptors(null_interceptor): transport = transports.ModelServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -2880,17 +3501,13 @@ def test_create_model_rest_interceptors(null_interceptor): ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - operation.Operation, "_set_result_from_operation" - ), mock.patch.object( - transports.ModelServiceRestInterceptor, "post_create_model" + transports.ModelServiceRestInterceptor, "post_get_model" ) as post, mock.patch.object( - transports.ModelServiceRestInterceptor, "pre_create_model" + transports.ModelServiceRestInterceptor, "pre_get_model" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = model_service.CreateModelRequest.pb( - model_service.CreateModelRequest() - ) + pb_message = model_service.GetModelRequest.pb(model_service.GetModelRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -2901,19 +3518,17 @@ def test_create_model_rest_interceptors(null_interceptor): req.return_value = Response() req.return_value.status_code = 200 req.return_value.request = PreparedRequest() - req.return_value._content = json_format.MessageToJson( - operations_pb2.Operation() - ) + req.return_value._content = model.Model.to_json(model.Model()) - request = model_service.CreateModelRequest() + request = model_service.GetModelRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() + post.return_value = model.Model() - client.create_model( + client.get_model( request, metadata=[ ("key", "val"), @@ -2925,8 +3540,8 @@ def test_create_model_rest_interceptors(null_interceptor): post.assert_called_once() -def test_create_model_rest_bad_request( - transport: str = "rest", request_type=model_service.CreateModelRequest +def test_get_model_rest_bad_request( + transport: str = "rest", request_type=model_service.GetModelRequest ): client = ModelServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -2934,40 +3549,8 @@ def test_create_model_rest_bad_request( ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/catalogs/sample3"} - request_init["model"] = { - "page_optimization_config": { - "page_optimization_event_type": "page_optimization_event_type_value", - "panels": [ - { - "display_name": "display_name_value", - "candidates": [{"serving_config_id": "serving_config_id_value"}], - "default_candidate": {}, - } - ], - "restriction": 1, - }, - "name": "name_value", - "display_name": "display_name_value", - "training_state": 1, - "serving_state": 1, - "create_time": {"seconds": 751, "nanos": 543}, - "update_time": {}, - "type_": "type__value", - "optimization_objective": "optimization_objective_value", - "periodic_tuning_state": 1, - "last_tune_time": {}, - "tuning_operation": "tuning_operation_value", - "data_state": 1, - "filtering_option": 1, - "serving_config_lists": [ - { - "serving_config_ids": [ - "serving_config_ids_value1", - "serving_config_ids_value2", - ] - } - ], + request_init = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" } request = request_type(**request_init) @@ -2980,10 +3563,10 @@ def test_create_model_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value - client.create_model(request) + client.get_model(request) -def test_create_model_rest_flattened(): +def test_get_model_rest_flattened(): client = ModelServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -2992,45 +3575,41 @@ def test_create_model_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = model.Model() # get arguments that satisfy an http rule for this method sample_request = { - "parent": "projects/sample1/locations/sample2/catalogs/sample3" + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" } # get truthy value for each flattened field mock_args = dict( - parent="parent_value", - model=gcr_model.Model( - page_optimization_config=gcr_model.Model.PageOptimizationConfig( - page_optimization_event_type="page_optimization_event_type_value" - ) - ), + name="name_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - client.create_model(**mock_args) + client.get_model(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v2alpha/{parent=projects/*/locations/*/catalogs/*}/models" + "%s/v2alpha/{name=projects/*/locations/*/catalogs/*/models/*}" % client.transport._host, args[1], ) -def test_create_model_rest_flattened_error(transport: str = "rest"): +def test_get_model_rest_flattened_error(transport: str = "rest"): client = ModelServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -3039,18 +3618,13 @@ def test_create_model_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.create_model( - model_service.CreateModelRequest(), - parent="parent_value", - model=gcr_model.Model( - page_optimization_config=gcr_model.Model.PageOptimizationConfig( - page_optimization_event_type="page_optimization_event_type_value" - ) - ), + client.get_model( + model_service.GetModelRequest(), + name="name_value", ) -def test_create_model_rest_error(): +def test_get_model_rest_error(): client = ModelServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -5040,6 +5614,7 @@ def test_model_service_base_transport(): # raise NotImplementedError. methods = ( "create_model", + "get_model", "pause_model", "resume_model", "delete_model", @@ -5328,6 +5903,9 @@ def test_model_service_client_transport_session_collision(transport_name): session1 = client1.transport.create_model._session session2 = client2.transport.create_model._session assert session1 != session2 + session1 = client1.transport.get_model._session + session2 = client2.transport.get_model._session + assert session1 != session2 session1 = client1.transport.pause_model._session session2 = client2.transport.pause_model._session assert session1 != session2 diff --git a/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_product_service.py b/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_product_service.py index 0179cde96c29..6cb6988174ba 100644 --- a/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_product_service.py +++ b/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_product_service.py @@ -5511,6 +5511,8 @@ def test_delete_product_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() ).delete_product._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("force",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -5561,7 +5563,7 @@ def test_delete_product_rest_unset_required_fields(): ) unset_fields = transport.delete_product._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + assert set(unset_fields) == (set(("force",)) & set(("name",))) @pytest.mark.parametrize("null_interceptor", [True, False]) diff --git a/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_search_service.py b/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_search_service.py index 2d6445c56cc9..2bf2812265d9 100644 --- a/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_search_service.py +++ b/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_search_service.py @@ -1916,12 +1916,41 @@ def test_parse_branch_path(): assert expected == actual -def test_product_path(): +def test_experiment_path(): project = "winkle" location = "nautilus" catalog = "scallop" - branch = "abalone" - product = "squid" + experiment = "abalone" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/experiments/{experiment}".format( + project=project, + location=location, + catalog=catalog, + experiment=experiment, + ) + actual = SearchServiceClient.experiment_path(project, location, catalog, experiment) + assert expected == actual + + +def test_parse_experiment_path(): + expected = { + "project": "squid", + "location": "clam", + "catalog": "whelk", + "experiment": "octopus", + } + path = SearchServiceClient.experiment_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_experiment_path(path) + assert expected == actual + + +def test_product_path(): + project = "oyster" + location = "nudibranch" + catalog = "cuttlefish" + branch = "mussel" + product = "winkle" expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format( project=project, location=location, @@ -1937,11 +1966,11 @@ def test_product_path(): def test_parse_product_path(): expected = { - "project": "clam", - "location": "whelk", - "catalog": "octopus", - "branch": "oyster", - "product": "nudibranch", + "project": "nautilus", + "location": "scallop", + "catalog": "abalone", + "branch": "squid", + "product": "clam", } path = SearchServiceClient.product_path(**expected) @@ -1950,8 +1979,39 @@ def test_parse_product_path(): assert expected == actual +def test_serving_config_path(): + project = "whelk" + location = "octopus" + catalog = "oyster" + serving_config = "nudibranch" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/servingConfigs/{serving_config}".format( + project=project, + location=location, + catalog=catalog, + serving_config=serving_config, + ) + actual = SearchServiceClient.serving_config_path( + project, location, catalog, serving_config + ) + assert expected == actual + + +def test_parse_serving_config_path(): + expected = { + "project": "cuttlefish", + "location": "mussel", + "catalog": "winkle", + "serving_config": "nautilus", + } + path = SearchServiceClient.serving_config_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_serving_config_path(path) + assert expected == actual + + def test_common_billing_account_path(): - billing_account = "cuttlefish" + billing_account = "scallop" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -1961,7 +2021,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "mussel", + "billing_account": "abalone", } path = SearchServiceClient.common_billing_account_path(**expected) @@ -1971,7 +2031,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "winkle" + folder = "squid" expected = "folders/{folder}".format( folder=folder, ) @@ -1981,7 +2041,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "nautilus", + "folder": "clam", } path = SearchServiceClient.common_folder_path(**expected) @@ -1991,7 +2051,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "scallop" + organization = "whelk" expected = "organizations/{organization}".format( organization=organization, ) @@ -2001,7 +2061,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "abalone", + "organization": "octopus", } path = SearchServiceClient.common_organization_path(**expected) @@ -2011,7 +2071,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "squid" + project = "oyster" expected = "projects/{project}".format( project=project, ) @@ -2021,7 +2081,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "clam", + "project": "nudibranch", } path = SearchServiceClient.common_project_path(**expected) @@ -2031,8 +2091,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "whelk" - location = "octopus" + project = "cuttlefish" + location = "mussel" expected = "projects/{project}/locations/{location}".format( project=project, location=location, @@ -2043,8 +2103,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "oyster", - "location": "nudibranch", + "project": "winkle", + "location": "nautilus", } path = SearchServiceClient.common_location_path(**expected) diff --git a/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_user_event_service.py b/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_user_event_service.py index 1adfa9765369..7b4e9db0376c 100644 --- a/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_user_event_service.py +++ b/packages/google-cloud-retail/tests/unit/gapic/retail_v2alpha/test_user_event_service.py @@ -792,6 +792,7 @@ def test_write_user_event(request_type, transport: str = "grpc"): uri="uri_value", referrer_uri="referrer_uri_value", page_view_id="page_view_id_value", + entity="entity_value", ) response = client.write_user_event(request) @@ -816,6 +817,7 @@ def test_write_user_event(request_type, transport: str = "grpc"): assert response.uri == "uri_value" assert response.referrer_uri == "referrer_uri_value" assert response.page_view_id == "page_view_id_value" + assert response.entity == "entity_value" def test_write_user_event_empty_call(): @@ -867,6 +869,7 @@ async def test_write_user_event_async( uri="uri_value", referrer_uri="referrer_uri_value", page_view_id="page_view_id_value", + entity="entity_value", ) ) response = await client.write_user_event(request) @@ -892,6 +895,7 @@ async def test_write_user_event_async( assert response.uri == "uri_value" assert response.referrer_uri == "referrer_uri_value" assert response.page_view_id == "page_view_id_value" + assert response.entity == "entity_value" @pytest.mark.asyncio @@ -1726,6 +1730,7 @@ def test_write_user_event_rest(request_type): "uri": "uri_value", "referrer_uri": "referrer_uri_value", "page_view_id": "page_view_id_value", + "entity": "entity_value", } request = request_type(**request_init) @@ -1747,6 +1752,7 @@ def test_write_user_event_rest(request_type): uri="uri_value", referrer_uri="referrer_uri_value", page_view_id="page_view_id_value", + entity="entity_value", ) # Wrap the value into a proper Response obj @@ -1775,6 +1781,7 @@ def test_write_user_event_rest(request_type): assert response.uri == "uri_value" assert response.referrer_uri == "referrer_uri_value" assert response.page_view_id == "page_view_id_value" + assert response.entity == "entity_value" def test_write_user_event_rest_required_fields( @@ -2062,6 +2069,7 @@ def test_write_user_event_rest_bad_request( "uri": "uri_value", "referrer_uri": "referrer_uri_value", "page_view_id": "page_view_id_value", + "entity": "entity_value", } request = request_type(**request_init) diff --git a/packages/google-cloud-retail/tests/unit/gapic/retail_v2beta/test_completion_service.py b/packages/google-cloud-retail/tests/unit/gapic/retail_v2beta/test_completion_service.py index f160aabd159b..0ba8196f3542 100644 --- a/packages/google-cloud-retail/tests/unit/gapic/retail_v2beta/test_completion_service.py +++ b/packages/google-cloud-retail/tests/unit/gapic/retail_v2beta/test_completion_service.py @@ -1129,6 +1129,7 @@ def test_complete_query_rest_required_fields( ( "dataset", "device_type", + "entity", "language_codes", "max_suggestions", "query", @@ -1200,6 +1201,7 @@ def test_complete_query_rest_unset_required_fields(): ( "dataset", "deviceType", + "entity", "languageCodes", "maxSuggestions", "query", diff --git a/packages/google-cloud-retail/tests/unit/gapic/retail_v2beta/test_model_service.py b/packages/google-cloud-retail/tests/unit/gapic/retail_v2beta/test_model_service.py index aca2aa7f52e0..24b0e9435123 100644 --- a/packages/google-cloud-retail/tests/unit/gapic/retail_v2beta/test_model_service.py +++ b/packages/google-cloud-retail/tests/unit/gapic/retail_v2beta/test_model_service.py @@ -941,6 +941,282 @@ async def test_create_model_flattened_error_async(): ) +@pytest.mark.parametrize( + "request_type", + [ + model_service.GetModelRequest, + dict, + ], +) +def test_get_model(request_type, transport: str = "grpc"): + client = ModelServiceClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model( + name="name_value", + display_name="display_name_value", + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_="type__value", + optimization_objective="optimization_objective_value", + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation="tuning_operation_value", + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + response = client.get_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.GetModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == "type__value" + assert response.optimization_objective == "optimization_objective_value" + assert ( + response.periodic_tuning_state + == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + ) + assert response.tuning_operation == "tuning_operation_value" + assert response.data_state == model.Model.DataState.DATA_OK + assert ( + response.filtering_option + == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + ) + + +def test_get_model_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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_model), "__call__") as call: + client.get_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.GetModelRequest() + + +@pytest.mark.asyncio +async def test_get_model_async( + transport: str = "grpc_asyncio", request_type=model_service.GetModelRequest +): + client = ModelServiceAsyncClient( + 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() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + model.Model( + name="name_value", + display_name="display_name_value", + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_="type__value", + optimization_objective="optimization_objective_value", + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation="tuning_operation_value", + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + ) + response = await client.get_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.GetModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == "type__value" + assert response.optimization_objective == "optimization_objective_value" + assert ( + response.periodic_tuning_state + == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + ) + assert response.tuning_operation == "tuning_operation_value" + assert response.data_state == model.Model.DataState.DATA_OK + assert ( + response.filtering_option + == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + ) + + +@pytest.mark.asyncio +async def test_get_model_async_from_dict(): + await test_get_model_async(request_type=dict) + + +def test_get_model_field_headers(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = model_service.GetModelRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_model), "__call__") as call: + call.return_value = model.Model() + client.get_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_model_field_headers_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = model_service.GetModelRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_model), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + await client.get_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_get_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_model( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_get_model_flattened_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_model( + model_service.GetModelRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_model), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_model( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_get_model_flattened_error_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_model( + model_service.GetModelRequest(), + name="name_value", + ) + + @pytest.mark.parametrize( "request_type", [ @@ -2969,6 +3245,298 @@ def test_create_model_rest_error(): ) +@pytest.mark.parametrize( + "request_type", + [ + model_service.GetModelRequest, + dict, + ], +) +def test_get_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = model.Model( + name="name_value", + display_name="display_name_value", + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_="type__value", + optimization_objective="optimization_objective_value", + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation="tuning_operation_value", + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_model(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == "type__value" + assert response.optimization_objective == "optimization_objective_value" + assert ( + response.periodic_tuning_state + == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + ) + assert response.tuning_operation == "tuning_operation_value" + assert response.data_state == model.Model.DataState.DATA_OK + assert ( + response.filtering_option + == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + ) + + +def test_get_model_rest_required_fields(request_type=model_service.GetModelRequest): + transport_class = transports.ModelServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_model._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_model._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = model.Model() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_model(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ModelServiceRestInterceptor, "post_get_model" + ) as post, mock.patch.object( + transports.ModelServiceRestInterceptor, "pre_get_model" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.GetModelRequest.pb(model_service.GetModelRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = model.Model.to_json(model.Model()) + + request = model_service.GetModelRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = model.Model() + + client.get_model( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_model_rest_bad_request( + transport: str = "rest", request_type=model_service.GetModelRequest +): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_model(request) + + +def test_get_model_rest_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = model.Model() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/catalogs/sample3/models/sample4" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.get_model(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2beta/{name=projects/*/locations/*/catalogs/*/models/*}" + % client.transport._host, + args[1], + ) + + +def test_get_model_rest_flattened_error(transport: str = "rest"): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_model( + model_service.GetModelRequest(), + name="name_value", + ) + + +def test_get_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + @pytest.mark.parametrize( "request_type", [ @@ -4914,6 +5482,7 @@ def test_model_service_base_transport(): # raise NotImplementedError. methods = ( "create_model", + "get_model", "pause_model", "resume_model", "delete_model", @@ -5202,6 +5771,9 @@ def test_model_service_client_transport_session_collision(transport_name): session1 = client1.transport.create_model._session session2 = client2.transport.create_model._session assert session1 != session2 + session1 = client1.transport.get_model._session + session2 = client2.transport.get_model._session + assert session1 != session2 session1 = client1.transport.pause_model._session session2 = client2.transport.pause_model._session assert session1 != session2 diff --git a/packages/google-cloud-retail/tests/unit/gapic/retail_v2beta/test_search_service.py b/packages/google-cloud-retail/tests/unit/gapic/retail_v2beta/test_search_service.py index 525b134571fd..057fd4bb053c 100644 --- a/packages/google-cloud-retail/tests/unit/gapic/retail_v2beta/test_search_service.py +++ b/packages/google-cloud-retail/tests/unit/gapic/retail_v2beta/test_search_service.py @@ -1916,12 +1916,41 @@ def test_parse_branch_path(): assert expected == actual -def test_product_path(): +def test_experiment_path(): project = "winkle" location = "nautilus" catalog = "scallop" - branch = "abalone" - product = "squid" + experiment = "abalone" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/experiments/{experiment}".format( + project=project, + location=location, + catalog=catalog, + experiment=experiment, + ) + actual = SearchServiceClient.experiment_path(project, location, catalog, experiment) + assert expected == actual + + +def test_parse_experiment_path(): + expected = { + "project": "squid", + "location": "clam", + "catalog": "whelk", + "experiment": "octopus", + } + path = SearchServiceClient.experiment_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_experiment_path(path) + assert expected == actual + + +def test_product_path(): + project = "oyster" + location = "nudibranch" + catalog = "cuttlefish" + branch = "mussel" + product = "winkle" expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format( project=project, location=location, @@ -1937,11 +1966,11 @@ def test_product_path(): def test_parse_product_path(): expected = { - "project": "clam", - "location": "whelk", - "catalog": "octopus", - "branch": "oyster", - "product": "nudibranch", + "project": "nautilus", + "location": "scallop", + "catalog": "abalone", + "branch": "squid", + "product": "clam", } path = SearchServiceClient.product_path(**expected) @@ -1950,8 +1979,39 @@ def test_parse_product_path(): assert expected == actual +def test_serving_config_path(): + project = "whelk" + location = "octopus" + catalog = "oyster" + serving_config = "nudibranch" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/servingConfigs/{serving_config}".format( + project=project, + location=location, + catalog=catalog, + serving_config=serving_config, + ) + actual = SearchServiceClient.serving_config_path( + project, location, catalog, serving_config + ) + assert expected == actual + + +def test_parse_serving_config_path(): + expected = { + "project": "cuttlefish", + "location": "mussel", + "catalog": "winkle", + "serving_config": "nautilus", + } + path = SearchServiceClient.serving_config_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_serving_config_path(path) + assert expected == actual + + def test_common_billing_account_path(): - billing_account = "cuttlefish" + billing_account = "scallop" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -1961,7 +2021,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "mussel", + "billing_account": "abalone", } path = SearchServiceClient.common_billing_account_path(**expected) @@ -1971,7 +2031,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "winkle" + folder = "squid" expected = "folders/{folder}".format( folder=folder, ) @@ -1981,7 +2041,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "nautilus", + "folder": "clam", } path = SearchServiceClient.common_folder_path(**expected) @@ -1991,7 +2051,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "scallop" + organization = "whelk" expected = "organizations/{organization}".format( organization=organization, ) @@ -2001,7 +2061,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "abalone", + "organization": "octopus", } path = SearchServiceClient.common_organization_path(**expected) @@ -2011,7 +2071,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "squid" + project = "oyster" expected = "projects/{project}".format( project=project, ) @@ -2021,7 +2081,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "clam", + "project": "nudibranch", } path = SearchServiceClient.common_project_path(**expected) @@ -2031,8 +2091,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "whelk" - location = "octopus" + project = "cuttlefish" + location = "mussel" expected = "projects/{project}/locations/{location}".format( project=project, location=location, @@ -2043,8 +2103,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "oyster", - "location": "nudibranch", + "project": "winkle", + "location": "nautilus", } path = SearchServiceClient.common_location_path(**expected) diff --git a/packages/google-cloud-retail/tests/unit/gapic/retail_v2beta/test_user_event_service.py b/packages/google-cloud-retail/tests/unit/gapic/retail_v2beta/test_user_event_service.py index 90f818977d9d..5d451f082654 100644 --- a/packages/google-cloud-retail/tests/unit/gapic/retail_v2beta/test_user_event_service.py +++ b/packages/google-cloud-retail/tests/unit/gapic/retail_v2beta/test_user_event_service.py @@ -792,6 +792,7 @@ def test_write_user_event(request_type, transport: str = "grpc"): uri="uri_value", referrer_uri="referrer_uri_value", page_view_id="page_view_id_value", + entity="entity_value", ) response = client.write_user_event(request) @@ -816,6 +817,7 @@ def test_write_user_event(request_type, transport: str = "grpc"): assert response.uri == "uri_value" assert response.referrer_uri == "referrer_uri_value" assert response.page_view_id == "page_view_id_value" + assert response.entity == "entity_value" def test_write_user_event_empty_call(): @@ -867,6 +869,7 @@ async def test_write_user_event_async( uri="uri_value", referrer_uri="referrer_uri_value", page_view_id="page_view_id_value", + entity="entity_value", ) ) response = await client.write_user_event(request) @@ -892,6 +895,7 @@ async def test_write_user_event_async( assert response.uri == "uri_value" assert response.referrer_uri == "referrer_uri_value" assert response.page_view_id == "page_view_id_value" + assert response.entity == "entity_value" @pytest.mark.asyncio @@ -1726,6 +1730,7 @@ def test_write_user_event_rest(request_type): "uri": "uri_value", "referrer_uri": "referrer_uri_value", "page_view_id": "page_view_id_value", + "entity": "entity_value", } request = request_type(**request_init) @@ -1747,6 +1752,7 @@ def test_write_user_event_rest(request_type): uri="uri_value", referrer_uri="referrer_uri_value", page_view_id="page_view_id_value", + entity="entity_value", ) # Wrap the value into a proper Response obj @@ -1775,6 +1781,7 @@ def test_write_user_event_rest(request_type): assert response.uri == "uri_value" assert response.referrer_uri == "referrer_uri_value" assert response.page_view_id == "page_view_id_value" + assert response.entity == "entity_value" def test_write_user_event_rest_required_fields( @@ -2062,6 +2069,7 @@ def test_write_user_event_rest_bad_request( "uri": "uri_value", "referrer_uri": "referrer_uri_value", "page_view_id": "page_view_id_value", + "entity": "entity_value", } request = request_type(**request_init)