From ec208343314664cd5e61f67cd8b464d96aac901a Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Fri, 2 Sep 2022 20:36:15 +0000 Subject: [PATCH] feat: release Model Services to v2beta version (#333) - [ ] Regenerate this pull request now. feat: release BatchRemoveCatalogAttributes API to v2beta version feat: release ExactSearchableOption for attribute config to v2beta version feat: release diversity_type for ServingConfig in v2beta version feat: add local inventories info to the Product resource feat: deprecate unused page_token field of PredictionRequest in v2beta version feat: deprecate unused facet_spec field of Control in v2beta version docs: improve documentation of SearchRequest for Search Personalization docs: improve documentation for Fullfillment and Inventory API in ProductService docs: minor documentation fixes and improvements PiperOrigin-RevId: 471846764 Source-Link: https://github.com/googleapis/googleapis/commit/15132940942b0c70083f9c7f6e0bf722fe620a8d Source-Link: https://github.com/googleapis/googleapis-gen/commit/c371ea8df2e34940875d51200cd57e300a2bc0a8 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiYzM3MWVhOGRmMmUzNDk0MDg3NWQ1MTIwMGNkNTdlMzAwYTJiYzBhOCJ9 --- docs/retail_v2beta/model_service.rst | 10 + docs/retail_v2beta/services.rst | 1 + google/cloud/retail_v2beta/__init__.py | 33 + .../cloud/retail_v2beta/gapic_metadata.json | 94 + .../services/catalog_service/async_client.py | 84 +- .../services/catalog_service/client.py | 87 +- .../catalog_service/transports/base.py | 17 + .../catalog_service/transports/grpc.py | 35 + .../transports/grpc_asyncio.py | 35 + .../completion_service/async_client.py | 12 +- .../services/completion_service/client.py | 12 +- .../completion_service/transports/grpc.py | 12 +- .../transports/grpc_asyncio.py | 12 +- .../services/control_service/async_client.py | 31 +- .../services/control_service/client.py | 31 +- .../control_service/transports/grpc.py | 5 +- .../transports/grpc_asyncio.py | 5 +- .../services/model_service/__init__.py | 22 + .../services/model_service/async_client.py | 990 +++++ .../services/model_service/client.py | 1246 ++++++ .../services/model_service/pagers.py | 155 + .../model_service/transports/__init__.py | 32 + .../services/model_service/transports/base.py | 254 ++ .../services/model_service/transports/grpc.py | 449 +++ .../model_service/transports/grpc_asyncio.py | 460 +++ .../services/product_service/async_client.py | 93 +- .../services/product_service/client.py | 93 +- .../product_service/transports/grpc.py | 93 +- .../transports/grpc_asyncio.py | 93 +- .../services/search_service/async_client.py | 8 +- .../services/search_service/client.py | 8 +- .../search_service/transports/grpc.py | 8 +- .../search_service/transports/grpc_asyncio.py | 8 +- .../serving_config_service/async_client.py | 55 +- .../services/serving_config_service/client.py | 55 +- .../user_event_service/async_client.py | 32 +- .../services/user_event_service/client.py | 32 +- .../user_event_service/transports/grpc.py | 32 +- .../transports/grpc_asyncio.py | 32 +- google/cloud/retail_v2beta/types/__init__.py | 30 + google/cloud/retail_v2beta/types/catalog.py | 24 +- .../retail_v2beta/types/catalog_service.py | 57 +- google/cloud/retail_v2beta/types/common.py | 12 +- google/cloud/retail_v2beta/types/control.py | 44 +- .../retail_v2beta/types/control_service.py | 3 +- .../retail_v2beta/types/export_config.py | 4 +- .../retail_v2beta/types/import_config.py | 60 +- google/cloud/retail_v2beta/types/model.py | 265 ++ .../retail_v2beta/types/model_service.py | 251 ++ .../retail_v2beta/types/prediction_service.py | 13 +- google/cloud/retail_v2beta/types/product.py | 19 +- .../retail_v2beta/types/search_service.py | 32 +- .../retail_v2beta/types/serving_config.py | 82 +- .../types/serving_config_service.py | 10 +- .../cloud/retail_v2beta/types/user_event.py | 2 +- .../retail_v2beta/types/user_event_service.py | 14 +- ...e_batch_remove_catalog_attributes_async.py | 46 + ...ce_batch_remove_catalog_attributes_sync.py | 46 + ...erated_model_service_create_model_async.py | 55 + ...nerated_model_service_create_model_sync.py | 55 + ...erated_model_service_delete_model_async.py | 43 + ...nerated_model_service_delete_model_sync.py | 43 + ...nerated_model_service_list_models_async.py | 46 + ...enerated_model_service_list_models_sync.py | 46 + ...nerated_model_service_pause_model_async.py | 45 + ...enerated_model_service_pause_model_sync.py | 45 + ...erated_model_service_resume_model_async.py | 45 + ...nerated_model_service_resume_model_sync.py | 45 + ...enerated_model_service_tune_model_async.py | 49 + ...generated_model_service_tune_model_sync.py | 49 + ...erated_model_service_update_model_async.py | 50 + ...nerated_model_service_update_model_sync.py | 50 + .../snippet_metadata_retail_v2beta.json | 1290 +++++++ scripts/fixup_retail_v2beta_keywords.py | 8 + .../retail_v2beta/test_catalog_service.py | 166 + .../retail_v2beta/test_control_service.py | 36 + .../gapic/retail_v2beta/test_model_service.py | 3397 +++++++++++++++++ .../test_serving_config_service.py | 50 + 78 files changed, 11000 insertions(+), 393 deletions(-) create mode 100644 docs/retail_v2beta/model_service.rst create mode 100644 google/cloud/retail_v2beta/services/model_service/__init__.py create mode 100644 google/cloud/retail_v2beta/services/model_service/async_client.py create mode 100644 google/cloud/retail_v2beta/services/model_service/client.py create mode 100644 google/cloud/retail_v2beta/services/model_service/pagers.py create mode 100644 google/cloud/retail_v2beta/services/model_service/transports/__init__.py create mode 100644 google/cloud/retail_v2beta/services/model_service/transports/base.py create mode 100644 google/cloud/retail_v2beta/services/model_service/transports/grpc.py create mode 100644 google/cloud/retail_v2beta/services/model_service/transports/grpc_asyncio.py create mode 100644 google/cloud/retail_v2beta/types/model.py create mode 100644 google/cloud/retail_v2beta/types/model_service.py create mode 100644 samples/generated_samples/retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_async.py create mode 100644 samples/generated_samples/retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_sync.py create mode 100644 samples/generated_samples/retail_v2beta_generated_model_service_create_model_async.py create mode 100644 samples/generated_samples/retail_v2beta_generated_model_service_create_model_sync.py create mode 100644 samples/generated_samples/retail_v2beta_generated_model_service_delete_model_async.py create mode 100644 samples/generated_samples/retail_v2beta_generated_model_service_delete_model_sync.py create mode 100644 samples/generated_samples/retail_v2beta_generated_model_service_list_models_async.py create mode 100644 samples/generated_samples/retail_v2beta_generated_model_service_list_models_sync.py create mode 100644 samples/generated_samples/retail_v2beta_generated_model_service_pause_model_async.py create mode 100644 samples/generated_samples/retail_v2beta_generated_model_service_pause_model_sync.py create mode 100644 samples/generated_samples/retail_v2beta_generated_model_service_resume_model_async.py create mode 100644 samples/generated_samples/retail_v2beta_generated_model_service_resume_model_sync.py create mode 100644 samples/generated_samples/retail_v2beta_generated_model_service_tune_model_async.py create mode 100644 samples/generated_samples/retail_v2beta_generated_model_service_tune_model_sync.py create mode 100644 samples/generated_samples/retail_v2beta_generated_model_service_update_model_async.py create mode 100644 samples/generated_samples/retail_v2beta_generated_model_service_update_model_sync.py create mode 100644 tests/unit/gapic/retail_v2beta/test_model_service.py diff --git a/docs/retail_v2beta/model_service.rst b/docs/retail_v2beta/model_service.rst new file mode 100644 index 00000000..eaa3b059 --- /dev/null +++ b/docs/retail_v2beta/model_service.rst @@ -0,0 +1,10 @@ +ModelService +------------------------------ + +.. automodule:: google.cloud.retail_v2beta.services.model_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2beta.services.model_service.pagers + :members: + :inherited-members: diff --git a/docs/retail_v2beta/services.rst b/docs/retail_v2beta/services.rst index 04251720..970cae46 100644 --- a/docs/retail_v2beta/services.rst +++ b/docs/retail_v2beta/services.rst @@ -6,6 +6,7 @@ Services for Google Cloud Retail v2beta API catalog_service completion_service control_service + model_service prediction_service product_service search_service diff --git a/google/cloud/retail_v2beta/__init__.py b/google/cloud/retail_v2beta/__init__.py index 7c5e7e9a..192b2de8 100644 --- a/google/cloud/retail_v2beta/__init__.py +++ b/google/cloud/retail_v2beta/__init__.py @@ -20,6 +20,7 @@ CompletionServiceClient, ) from .services.control_service import ControlServiceAsyncClient, ControlServiceClient +from .services.model_service import ModelServiceAsyncClient, ModelServiceClient from .services.prediction_service import ( PredictionServiceAsyncClient, PredictionServiceClient, @@ -45,6 +46,8 @@ ) from .types.catalog_service import ( AddCatalogAttributeRequest, + BatchRemoveCatalogAttributesRequest, + BatchRemoveCatalogAttributesResponse, GetAttributesConfigRequest, GetCompletionConfigRequest, GetDefaultBranchRequest, @@ -112,6 +115,20 @@ UserEventInlineSource, UserEventInputConfig, ) +from .types.model import Model +from .types.model_service import ( + CreateModelMetadata, + CreateModelRequest, + DeleteModelRequest, + 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 ( @@ -173,6 +190,7 @@ "CatalogServiceAsyncClient", "CompletionServiceAsyncClient", "ControlServiceAsyncClient", + "ModelServiceAsyncClient", "PredictionServiceAsyncClient", "ProductServiceAsyncClient", "SearchServiceAsyncClient", @@ -189,6 +207,8 @@ "AttributeConfigLevel", "AttributesConfig", "Audience", + "BatchRemoveCatalogAttributesRequest", + "BatchRemoveCatalogAttributesResponse", "BigQueryOutputResult", "BigQuerySource", "Catalog", @@ -206,10 +226,13 @@ "Control", "ControlServiceClient", "CreateControlRequest", + "CreateModelMetadata", + "CreateModelRequest", "CreateProductRequest", "CreateServingConfigRequest", "CustomAttribute", "DeleteControlRequest", + "DeleteModelRequest", "DeleteProductRequest", "DeleteServingConfigRequest", "ExportErrorsConfig", @@ -239,6 +262,8 @@ "ListCatalogsResponse", "ListControlsRequest", "ListControlsResponse", + "ListModelsRequest", + "ListModelsResponse", "ListProductsRequest", "ListProductsResponse", "ListServingConfigsRequest", @@ -246,7 +271,10 @@ "LocalInventory", "MerchantCenterLink", "MerchantCenterLinkingConfig", + "Model", + "ModelServiceClient", "OutputResult", + "PauseModelRequest", "PredictRequest", "PredictResponse", "PredictionServiceClient", @@ -276,6 +304,7 @@ "RemoveLocalInventoriesRequest", "RemoveLocalInventoriesResponse", "ReplaceCatalogAttributeRequest", + "ResumeModelRequest", "Rule", "SearchRequest", "SearchResponse", @@ -288,10 +317,14 @@ "SetInventoryRequest", "SetInventoryResponse", "SolutionType", + "TuneModelMetadata", + "TuneModelRequest", + "TuneModelResponse", "UpdateAttributesConfigRequest", "UpdateCatalogRequest", "UpdateCompletionConfigRequest", "UpdateControlRequest", + "UpdateModelRequest", "UpdateProductRequest", "UpdateServingConfigRequest", "UserEvent", diff --git a/google/cloud/retail_v2beta/gapic_metadata.json b/google/cloud/retail_v2beta/gapic_metadata.json index bf3205b9..3213e7f4 100644 --- a/google/cloud/retail_v2beta/gapic_metadata.json +++ b/google/cloud/retail_v2beta/gapic_metadata.json @@ -15,6 +15,11 @@ "add_catalog_attribute" ] }, + "BatchRemoveCatalogAttributes": { + "methods": [ + "batch_remove_catalog_attributes" + ] + }, "GetAttributesConfig": { "methods": [ "get_attributes_config" @@ -75,6 +80,11 @@ "add_catalog_attribute" ] }, + "BatchRemoveCatalogAttributes": { + "methods": [ + "batch_remove_catalog_attributes" + ] + }, "GetAttributesConfig": { "methods": [ "get_attributes_config" @@ -227,6 +237,90 @@ } } }, + "ModelService": { + "clients": { + "grpc": { + "libraryClient": "ModelServiceClient", + "rpcs": { + "CreateModel": { + "methods": [ + "create_model" + ] + }, + "DeleteModel": { + "methods": [ + "delete_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" + ] + }, + "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/google/cloud/retail_v2beta/services/catalog_service/async_client.py b/google/cloud/retail_v2beta/services/catalog_service/async_client.py index c6c7720a..8ffcd1f6 100644 --- a/google/cloud/retail_v2beta/services/catalog_service/async_client.py +++ b/google/cloud/retail_v2beta/services/catalog_service/async_client.py @@ -705,7 +705,7 @@ async def sample_get_completion_config(): method. name (:class:`str`): Required. Full CompletionConfig resource name. Format: - projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/completionConfig + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/completionConfig`` This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -1282,6 +1282,88 @@ async def sample_remove_catalog_attribute(): # Done; return the response. return response + async def batch_remove_catalog_attributes( + self, + request: Union[ + catalog_service.BatchRemoveCatalogAttributesRequest, dict + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog_service.BatchRemoveCatalogAttributesResponse: + r"""Removes all specified + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute]s + from the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + .. code-block:: python + + from google.cloud import retail_v2beta + + async def sample_batch_remove_catalog_attributes(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.BatchRemoveCatalogAttributesRequest( + attributes_config="attributes_config_value", + attribute_keys=['attribute_keys_value_1', 'attribute_keys_value_2'], + ) + + # Make the request + response = await client.batch_remove_catalog_attributes(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.BatchRemoveCatalogAttributesRequest, dict]): + The request object. Request for + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2beta.CatalogService.BatchRemoveCatalogAttributes] + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2beta.types.BatchRemoveCatalogAttributesResponse: + Response of the + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2beta.CatalogService.BatchRemoveCatalogAttributes]. + + """ + # Create or coerce a protobuf request object. + request = catalog_service.BatchRemoveCatalogAttributesRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.batch_remove_catalog_attributes, + 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( + (("attributes_config", request.attributes_config),) + ), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + async def replace_catalog_attribute( self, request: Union[catalog_service.ReplaceCatalogAttributeRequest, dict] = None, diff --git a/google/cloud/retail_v2beta/services/catalog_service/client.py b/google/cloud/retail_v2beta/services/catalog_service/client.py index 665eac7a..24025ca3 100644 --- a/google/cloud/retail_v2beta/services/catalog_service/client.py +++ b/google/cloud/retail_v2beta/services/catalog_service/client.py @@ -988,7 +988,7 @@ def sample_get_completion_config(): method. name (str): Required. Full CompletionConfig resource name. Format: - projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/completionConfig + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/completionConfig`` This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -1567,6 +1567,91 @@ def sample_remove_catalog_attribute(): # Done; return the response. return response + def batch_remove_catalog_attributes( + self, + request: Union[ + catalog_service.BatchRemoveCatalogAttributesRequest, dict + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog_service.BatchRemoveCatalogAttributesResponse: + r"""Removes all specified + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute]s + from the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + .. code-block:: python + + from google.cloud import retail_v2beta + + def sample_batch_remove_catalog_attributes(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.BatchRemoveCatalogAttributesRequest( + attributes_config="attributes_config_value", + attribute_keys=['attribute_keys_value_1', 'attribute_keys_value_2'], + ) + + # Make the request + response = client.batch_remove_catalog_attributes(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.BatchRemoveCatalogAttributesRequest, dict]): + The request object. Request for + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2beta.CatalogService.BatchRemoveCatalogAttributes] + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2beta.types.BatchRemoveCatalogAttributesResponse: + Response of the + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2beta.CatalogService.BatchRemoveCatalogAttributes]. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a catalog_service.BatchRemoveCatalogAttributesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.BatchRemoveCatalogAttributesRequest): + request = catalog_service.BatchRemoveCatalogAttributesRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.batch_remove_catalog_attributes + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("attributes_config", request.attributes_config),) + ), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + def replace_catalog_attribute( self, request: Union[catalog_service.ReplaceCatalogAttributeRequest, dict] = None, diff --git a/google/cloud/retail_v2beta/services/catalog_service/transports/base.py b/google/cloud/retail_v2beta/services/catalog_service/transports/base.py index fb3e7748..69de0b69 100644 --- a/google/cloud/retail_v2beta/services/catalog_service/transports/base.py +++ b/google/cloud/retail_v2beta/services/catalog_service/transports/base.py @@ -180,6 +180,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.batch_remove_catalog_attributes: gapic_v1.method.wrap_method( + self.batch_remove_catalog_attributes, + default_timeout=None, + client_info=client_info, + ), self.replace_catalog_attribute: gapic_v1.method.wrap_method( self.replace_catalog_attribute, default_timeout=None, @@ -292,6 +297,18 @@ def remove_catalog_attribute( ]: raise NotImplementedError() + @property + def batch_remove_catalog_attributes( + self, + ) -> Callable[ + [catalog_service.BatchRemoveCatalogAttributesRequest], + Union[ + catalog_service.BatchRemoveCatalogAttributesResponse, + Awaitable[catalog_service.BatchRemoveCatalogAttributesResponse], + ], + ]: + raise NotImplementedError() + @property def replace_catalog_attribute( self, diff --git a/google/cloud/retail_v2beta/services/catalog_service/transports/grpc.py b/google/cloud/retail_v2beta/services/catalog_service/transports/grpc.py index bb8d7233..2940eada 100644 --- a/google/cloud/retail_v2beta/services/catalog_service/transports/grpc.py +++ b/google/cloud/retail_v2beta/services/catalog_service/transports/grpc.py @@ -572,6 +572,41 @@ def remove_catalog_attribute( ) return self._stubs["remove_catalog_attribute"] + @property + def batch_remove_catalog_attributes( + self, + ) -> Callable[ + [catalog_service.BatchRemoveCatalogAttributesRequest], + catalog_service.BatchRemoveCatalogAttributesResponse, + ]: + r"""Return a callable for the batch remove catalog + attributes method over gRPC. + + Removes all specified + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute]s + from the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + Returns: + Callable[[~.BatchRemoveCatalogAttributesRequest], + ~.BatchRemoveCatalogAttributesResponse]: + 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 "batch_remove_catalog_attributes" not in self._stubs: + self._stubs[ + "batch_remove_catalog_attributes" + ] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2beta.CatalogService/BatchRemoveCatalogAttributes", + request_serializer=catalog_service.BatchRemoveCatalogAttributesRequest.serialize, + response_deserializer=catalog_service.BatchRemoveCatalogAttributesResponse.deserialize, + ) + return self._stubs["batch_remove_catalog_attributes"] + @property def replace_catalog_attribute( self, diff --git a/google/cloud/retail_v2beta/services/catalog_service/transports/grpc_asyncio.py b/google/cloud/retail_v2beta/services/catalog_service/transports/grpc_asyncio.py index 80ef39d6..89344801 100644 --- a/google/cloud/retail_v2beta/services/catalog_service/transports/grpc_asyncio.py +++ b/google/cloud/retail_v2beta/services/catalog_service/transports/grpc_asyncio.py @@ -586,6 +586,41 @@ def remove_catalog_attribute( ) return self._stubs["remove_catalog_attribute"] + @property + def batch_remove_catalog_attributes( + self, + ) -> Callable[ + [catalog_service.BatchRemoveCatalogAttributesRequest], + Awaitable[catalog_service.BatchRemoveCatalogAttributesResponse], + ]: + r"""Return a callable for the batch remove catalog + attributes method over gRPC. + + Removes all specified + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute]s + from the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + Returns: + Callable[[~.BatchRemoveCatalogAttributesRequest], + Awaitable[~.BatchRemoveCatalogAttributesResponse]]: + 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 "batch_remove_catalog_attributes" not in self._stubs: + self._stubs[ + "batch_remove_catalog_attributes" + ] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2beta.CatalogService/BatchRemoveCatalogAttributes", + request_serializer=catalog_service.BatchRemoveCatalogAttributesRequest.serialize, + response_deserializer=catalog_service.BatchRemoveCatalogAttributesResponse.deserialize, + ) + return self._stubs["batch_remove_catalog_attributes"] + @property def replace_catalog_attribute( self, diff --git a/google/cloud/retail_v2beta/services/completion_service/async_client.py b/google/cloud/retail_v2beta/services/completion_service/async_client.py index 35008ee7..6be6ec77 100644 --- a/google/cloud/retail_v2beta/services/completion_service/async_client.py +++ b/google/cloud/retail_v2beta/services/completion_service/async_client.py @@ -44,8 +44,8 @@ class CompletionServiceAsyncClient: """Auto-completion service for retail. This feature is only available for users who have Retail Search - enabled. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. """ _client: CompletionServiceClient @@ -220,8 +220,8 @@ async def complete_query( r"""Completes the specified prefix with keyword suggestions. This feature is only available for users who have Retail - Search enabled. Please enable Retail Search on Cloud - Console before using this feature. + Search enabled. Enable Retail Search on Cloud Console + before using this feature. .. code-block:: python @@ -299,8 +299,8 @@ async def import_completion_data( imported suggestions are indexed successfully and ready for serving. The process takes hours. This feature is only available for users who have Retail - Search enabled. Please enable Retail Search on Cloud - Console before using this feature. + Search enabled. Enable Retail Search on Cloud Console + before using this feature. .. code-block:: python diff --git a/google/cloud/retail_v2beta/services/completion_service/client.py b/google/cloud/retail_v2beta/services/completion_service/client.py index 564d7a01..267357f0 100644 --- a/google/cloud/retail_v2beta/services/completion_service/client.py +++ b/google/cloud/retail_v2beta/services/completion_service/client.py @@ -83,8 +83,8 @@ def get_transport_class( class CompletionServiceClient(metaclass=CompletionServiceClientMeta): """Auto-completion service for retail. This feature is only available for users who have Retail Search - enabled. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. """ @staticmethod @@ -445,8 +445,8 @@ def complete_query( r"""Completes the specified prefix with keyword suggestions. This feature is only available for users who have Retail - Search enabled. Please enable Retail Search on Cloud - Console before using this feature. + Search enabled. Enable Retail Search on Cloud Console + before using this feature. .. code-block:: python @@ -525,8 +525,8 @@ def import_completion_data( imported suggestions are indexed successfully and ready for serving. The process takes hours. This feature is only available for users who have Retail - Search enabled. Please enable Retail Search on Cloud - Console before using this feature. + Search enabled. Enable Retail Search on Cloud Console + before using this feature. .. code-block:: python diff --git a/google/cloud/retail_v2beta/services/completion_service/transports/grpc.py b/google/cloud/retail_v2beta/services/completion_service/transports/grpc.py index 1c52e57d..f35229c1 100644 --- a/google/cloud/retail_v2beta/services/completion_service/transports/grpc.py +++ b/google/cloud/retail_v2beta/services/completion_service/transports/grpc.py @@ -33,8 +33,8 @@ class CompletionServiceGrpcTransport(CompletionServiceTransport): Auto-completion service for retail. This feature is only available for users who have Retail Search - enabled. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. This class defines the same methods as the primary client, so the primary client can load the underlying transport implementation @@ -259,8 +259,8 @@ def complete_query( Completes the specified prefix with keyword suggestions. This feature is only available for users who have Retail - Search enabled. Please enable Retail Search on Cloud - Console before using this feature. + Search enabled. Enable Retail Search on Cloud Console + before using this feature. Returns: Callable[[~.CompleteQueryRequest], @@ -295,8 +295,8 @@ def import_completion_data( imported suggestions are indexed successfully and ready for serving. The process takes hours. This feature is only available for users who have Retail - Search enabled. Please enable Retail Search on Cloud - Console before using this feature. + Search enabled. Enable Retail Search on Cloud Console + before using this feature. Returns: Callable[[~.ImportCompletionDataRequest], diff --git a/google/cloud/retail_v2beta/services/completion_service/transports/grpc_asyncio.py b/google/cloud/retail_v2beta/services/completion_service/transports/grpc_asyncio.py index 73b2f5bc..f1837e3b 100644 --- a/google/cloud/retail_v2beta/services/completion_service/transports/grpc_asyncio.py +++ b/google/cloud/retail_v2beta/services/completion_service/transports/grpc_asyncio.py @@ -34,8 +34,8 @@ class CompletionServiceGrpcAsyncIOTransport(CompletionServiceTransport): Auto-completion service for retail. This feature is only available for users who have Retail Search - enabled. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. This class defines the same methods as the primary client, so the primary client can load the underlying transport implementation @@ -264,8 +264,8 @@ def complete_query( Completes the specified prefix with keyword suggestions. This feature is only available for users who have Retail - Search enabled. Please enable Retail Search on Cloud - Console before using this feature. + Search enabled. Enable Retail Search on Cloud Console + before using this feature. Returns: Callable[[~.CompleteQueryRequest], @@ -300,8 +300,8 @@ def import_completion_data( imported suggestions are indexed successfully and ready for serving. The process takes hours. This feature is only available for users who have Retail - Search enabled. Please enable Retail Search on Cloud - Console before using this feature. + Search enabled. Enable Retail Search on Cloud Console + before using this feature. Returns: Callable[[~.ImportCompletionDataRequest], diff --git a/google/cloud/retail_v2beta/services/control_service/async_client.py b/google/cloud/retail_v2beta/services/control_service/async_client.py index dd14ae32..cd09e81a 100644 --- a/google/cloud/retail_v2beta/services/control_service/async_client.py +++ b/google/cloud/retail_v2beta/services/control_service/async_client.py @@ -286,10 +286,10 @@ async def sample_create_control(): Returns: google.cloud.retail_v2beta.types.Control: - Configures dynamic serving time - metadata that is used to pre and post - process search/recommendation model - results. + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and affect search or recommendation results at + serving time. """ # Create or coerce a protobuf request object. @@ -438,7 +438,7 @@ async def update_control( [Control][google.cloud.retail.v2beta.Control] cannot be set to a different oneof field, if so an INVALID_ARGUMENT is returned. If - the [Control][google.cloud.retail.v2beta.Control] to delete does + the [Control][google.cloud.retail.v2beta.Control] to update does not exist, a NOT_FOUND error is returned. .. code-block:: python @@ -493,10 +493,10 @@ async def sample_update_control(): Returns: google.cloud.retail_v2beta.types.Control: - Configures dynamic serving time - metadata that is used to pre and post - process search/recommendation model - results. + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and affect search or recommendation results at + serving time. """ # Create or coerce a protobuf request object. @@ -579,7 +579,7 @@ async def sample_get_control(): request (Union[google.cloud.retail_v2beta.types.GetControlRequest, dict]): The request object. Request for GetControl method. name (:class:`str`): - Required. The resource name of the Control to delete. + Required. The resource name of the Control to get. Format: ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_id}`` @@ -594,10 +594,10 @@ async def sample_get_control(): Returns: google.cloud.retail_v2beta.types.Control: - Configures dynamic serving time - metadata that is used to pre and post - process search/recommendation model - results. + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and affect search or recommendation results at + serving time. """ # Create or coerce a protobuf request object. @@ -651,7 +651,8 @@ async def list_controls( timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> pagers.ListControlsAsyncPager: - r"""Lists all Controls linked to this catalog. + r"""Lists all Controls by their parent + [Catalog][google.cloud.retail.v2beta.Catalog]. .. code-block:: python diff --git a/google/cloud/retail_v2beta/services/control_service/client.py b/google/cloud/retail_v2beta/services/control_service/client.py index e7bb9020..7c169f8a 100644 --- a/google/cloud/retail_v2beta/services/control_service/client.py +++ b/google/cloud/retail_v2beta/services/control_service/client.py @@ -533,10 +533,10 @@ def sample_create_control(): Returns: google.cloud.retail_v2beta.types.Control: - Configures dynamic serving time - metadata that is used to pre and post - process search/recommendation model - results. + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and affect search or recommendation results at + serving time. """ # Create or coerce a protobuf request object. @@ -685,7 +685,7 @@ def update_control( [Control][google.cloud.retail.v2beta.Control] cannot be set to a different oneof field, if so an INVALID_ARGUMENT is returned. If - the [Control][google.cloud.retail.v2beta.Control] to delete does + the [Control][google.cloud.retail.v2beta.Control] to update does not exist, a NOT_FOUND error is returned. .. code-block:: python @@ -740,10 +740,10 @@ def sample_update_control(): Returns: google.cloud.retail_v2beta.types.Control: - Configures dynamic serving time - metadata that is used to pre and post - process search/recommendation model - results. + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and affect search or recommendation results at + serving time. """ # Create or coerce a protobuf request object. @@ -826,7 +826,7 @@ def sample_get_control(): request (Union[google.cloud.retail_v2beta.types.GetControlRequest, dict]): The request object. Request for GetControl method. name (str): - Required. The resource name of the Control to delete. + Required. The resource name of the Control to get. Format: ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_id}`` @@ -841,10 +841,10 @@ def sample_get_control(): Returns: google.cloud.retail_v2beta.types.Control: - Configures dynamic serving time - metadata that is used to pre and post - process search/recommendation model - results. + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and affect search or recommendation results at + serving time. """ # Create or coerce a protobuf request object. @@ -898,7 +898,8 @@ def list_controls( timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> pagers.ListControlsPager: - r"""Lists all Controls linked to this catalog. + r"""Lists all Controls by their parent + [Catalog][google.cloud.retail.v2beta.Catalog]. .. code-block:: python diff --git a/google/cloud/retail_v2beta/services/control_service/transports/grpc.py b/google/cloud/retail_v2beta/services/control_service/transports/grpc.py index e6a99d24..51d69fe1 100644 --- a/google/cloud/retail_v2beta/services/control_service/transports/grpc.py +++ b/google/cloud/retail_v2beta/services/control_service/transports/grpc.py @@ -299,7 +299,7 @@ def update_control( [Control][google.cloud.retail.v2beta.Control] cannot be set to a different oneof field, if so an INVALID_ARGUMENT is returned. If - the [Control][google.cloud.retail.v2beta.Control] to delete does + the [Control][google.cloud.retail.v2beta.Control] to update does not exist, a NOT_FOUND error is returned. Returns: @@ -354,7 +354,8 @@ def list_controls( ]: r"""Return a callable for the list controls method over gRPC. - Lists all Controls linked to this catalog. + Lists all Controls by their parent + [Catalog][google.cloud.retail.v2beta.Catalog]. Returns: Callable[[~.ListControlsRequest], diff --git a/google/cloud/retail_v2beta/services/control_service/transports/grpc_asyncio.py b/google/cloud/retail_v2beta/services/control_service/transports/grpc_asyncio.py index 0433ade3..401e4edf 100644 --- a/google/cloud/retail_v2beta/services/control_service/transports/grpc_asyncio.py +++ b/google/cloud/retail_v2beta/services/control_service/transports/grpc_asyncio.py @@ -306,7 +306,7 @@ def update_control( [Control][google.cloud.retail.v2beta.Control] cannot be set to a different oneof field, if so an INVALID_ARGUMENT is returned. If - the [Control][google.cloud.retail.v2beta.Control] to delete does + the [Control][google.cloud.retail.v2beta.Control] to update does not exist, a NOT_FOUND error is returned. Returns: @@ -362,7 +362,8 @@ def list_controls( ]: r"""Return a callable for the list controls method over gRPC. - Lists all Controls linked to this catalog. + Lists all Controls by their parent + [Catalog][google.cloud.retail.v2beta.Catalog]. Returns: Callable[[~.ListControlsRequest], diff --git a/google/cloud/retail_v2beta/services/model_service/__init__.py b/google/cloud/retail_v2beta/services/model_service/__init__.py new file mode 100644 index 00000000..fa113724 --- /dev/null +++ b/google/cloud/retail_v2beta/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/google/cloud/retail_v2beta/services/model_service/async_client.py b/google/cloud/retail_v2beta/services/model_service/async_client.py new file mode 100644 index 00000000..c68d704a --- /dev/null +++ b/google/cloud/retail_v2beta/services/model_service/async_client.py @@ -0,0 +1,990 @@ +# -*- 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, 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 +import pkg_resources + +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.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + +from google.cloud.retail_v2beta.services.model_service import pagers +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import model +from google.cloud.retail_v2beta.types import model as gcr_model +from google.cloud.retail_v2beta.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 variabel 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: ga_credentials.Credentials = None, + transport: Union[str, ModelServiceTransport] = "grpc_asyncio", + client_options: 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: Union[model_service.CreateModelRequest, dict] = None, + *, + parent: str = None, + model: gcr_model.Model = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Creates a new model. + + .. code-block:: python + + from google.cloud import retail_v2beta + + async def sample_create_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + model = retail_v2beta.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2beta.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 (Union[google.cloud.retail_v2beta.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_v2beta.types.Model`): + Required. The payload of the + [Model][google.cloud.retail.v2beta.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_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([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 pause_model( + self, + request: Union[model_service.PauseModelRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> model.Model: + r"""Pauses the training of an existing model. + + .. code-block:: python + + from google.cloud import retail_v2beta + + async def sample_pause_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.PauseModelRequest( + name="name_value", + ) + + # Make the request + response = await client.pause_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.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_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.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: Union[model_service.ResumeModelRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> model.Model: + r"""Resumes the training of an existing model. + + .. code-block:: python + + from google.cloud import retail_v2beta + + async def sample_resume_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.ResumeModelRequest( + name="name_value", + ) + + # Make the request + response = await client.resume_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.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_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.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: Union[model_service.DeleteModelRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes an existing model. + + .. code-block:: python + + from google.cloud import retail_v2beta + + async def sample_delete_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.DeleteModelRequest( + name="name_value", + ) + + # Make the request + await client.delete_model(request=request) + + Args: + request (Union[google.cloud.retail_v2beta.types.DeleteModelRequest, dict]): + The request object. Request for deleting a model. + name (:class:`str`): + Required. The resource name of the + [Model][google.cloud.retail.v2beta.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: Union[model_service.ListModelsRequest, dict] = None, + *, + parent: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListModelsAsyncPager: + r"""Lists all the models linked to this event store. + + .. code-block:: python + + from google.cloud import retail_v2beta + + async def sample_list_models(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.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 (Union[google.cloud.retail_v2beta.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_v2beta.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: Union[model_service.UpdateModelRequest, dict] = None, + *, + model: gcr_model.Model = None, + update_mask: field_mask_pb2.FieldMask = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + 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 + + from google.cloud import retail_v2beta + + async def sample_update_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + model = retail_v2beta.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2beta.UpdateModelRequest( + model=model, + ) + + # Make the request + response = await client.update_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.UpdateModelRequest, dict]): + The request object. Request for updating an existing + model. + model (:class:`google.cloud.retail_v2beta.types.Model`): + Required. The body of the updated + [Model][google.cloud.retail.v2beta.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_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([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: Union[model_service.TuneModelRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Tunes an existing model. + + .. code-block:: python + + from google.cloud import retail_v2beta + + async def sample_tune_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.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 (Union[google.cloud.retail_v2beta.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_v2beta.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 __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("ModelServiceAsyncClient",) diff --git a/google/cloud/retail_v2beta/services/model_service/client.py b/google/cloud/retail_v2beta/services/model_service/client.py new file mode 100644 index 00000000..b2f422d0 --- /dev/null +++ b/google/cloud/retail_v2beta/services/model_service/client.py @@ -0,0 +1,1246 @@ +# -*- 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, Optional, Sequence, Tuple, Type, Union + +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 +import pkg_resources + +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.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + +from google.cloud.retail_v2beta.services.model_service import pagers +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import model +from google.cloud.retail_v2beta.types import model as gcr_model +from google.cloud.retail_v2beta.types import model_service + +from .transports.base import DEFAULT_CLIENT_INFO, ModelServiceTransport +from .transports.grpc import ModelServiceGrpcTransport +from .transports.grpc_asyncio import ModelServiceGrpcAsyncIOTransport + + +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 + + def get_transport_class( + cls, + label: 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 variabel 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: Union[str, ModelServiceTransport, None] = None, + client_options: Optional[client_options_lib.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 (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + 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: Union[model_service.CreateModelRequest, dict] = None, + *, + parent: str = None, + model: gcr_model.Model = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Creates a new model. + + .. code-block:: python + + from google.cloud import retail_v2beta + + def sample_create_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + model = retail_v2beta.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2beta.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_v2beta.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_v2beta.types.Model): + Required. The payload of the + [Model][google.cloud.retail.v2beta.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_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([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 pause_model( + self, + request: Union[model_service.PauseModelRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> model.Model: + r"""Pauses the training of an existing model. + + .. code-block:: python + + from google.cloud import retail_v2beta + + def sample_pause_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.PauseModelRequest( + name="name_value", + ) + + # Make the request + response = client.pause_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.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_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.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: Union[model_service.ResumeModelRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> model.Model: + r"""Resumes the training of an existing model. + + .. code-block:: python + + from google.cloud import retail_v2beta + + def sample_resume_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.ResumeModelRequest( + name="name_value", + ) + + # Make the request + response = client.resume_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.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_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.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: Union[model_service.DeleteModelRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes an existing model. + + .. code-block:: python + + from google.cloud import retail_v2beta + + def sample_delete_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.DeleteModelRequest( + name="name_value", + ) + + # Make the request + client.delete_model(request=request) + + Args: + request (Union[google.cloud.retail_v2beta.types.DeleteModelRequest, dict]): + The request object. Request for deleting a model. + name (str): + Required. The resource name of the + [Model][google.cloud.retail.v2beta.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: Union[model_service.ListModelsRequest, dict] = None, + *, + parent: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListModelsPager: + r"""Lists all the models linked to this event store. + + .. code-block:: python + + from google.cloud import retail_v2beta + + def sample_list_models(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.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_v2beta.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_v2beta.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: Union[model_service.UpdateModelRequest, dict] = None, + *, + model: gcr_model.Model = None, + update_mask: field_mask_pb2.FieldMask = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + 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 + + from google.cloud import retail_v2beta + + def sample_update_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + model = retail_v2beta.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2beta.UpdateModelRequest( + model=model, + ) + + # Make the request + response = client.update_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.UpdateModelRequest, dict]): + The request object. Request for updating an existing + model. + model (google.cloud.retail_v2beta.types.Model): + Required. The body of the updated + [Model][google.cloud.retail.v2beta.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_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([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: Union[model_service.TuneModelRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Tunes an existing model. + + .. code-block:: python + + from google.cloud import retail_v2beta + + def sample_tune_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.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_v2beta.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_v2beta.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): + 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() + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("ModelServiceClient",) diff --git a/google/cloud/retail_v2beta/services/model_service/pagers.py b/google/cloud/retail_v2beta/services/model_service/pagers.py new file mode 100644 index 00000000..5eb31ee6 --- /dev/null +++ b/google/cloud/retail_v2beta/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_v2beta.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_v2beta.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_v2beta.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_v2beta.types.ListModelsRequest): + The initial request object. + response (google.cloud.retail_v2beta.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_v2beta.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_v2beta.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_v2beta.types.ListModelsRequest): + The initial request object. + response (google.cloud.retail_v2beta.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/google/cloud/retail_v2beta/services/model_service/transports/__init__.py b/google/cloud/retail_v2beta/services/model_service/transports/__init__.py new file mode 100644 index 00000000..a4d289e2 --- /dev/null +++ b/google/cloud/retail_v2beta/services/model_service/transports/__init__.py @@ -0,0 +1,32 @@ +# -*- 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 + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ModelServiceTransport]] +_transport_registry["grpc"] = ModelServiceGrpcTransport +_transport_registry["grpc_asyncio"] = ModelServiceGrpcAsyncIOTransport + +__all__ = ( + "ModelServiceTransport", + "ModelServiceGrpcTransport", + "ModelServiceGrpcAsyncIOTransport", +) diff --git a/google/cloud/retail_v2beta/services/model_service/transports/base.py b/google/cloud/retail_v2beta/services/model_service/transports/base.py new file mode 100644 index 00000000..428f6c94 --- /dev/null +++ b/google/cloud/retail_v2beta/services/model_service/transports/base.py @@ -0,0 +1,254 @@ +# -*- 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.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +from google.protobuf import empty_pb2 # type: ignore +import pkg_resources + +from google.cloud.retail_v2beta.types import model +from google.cloud.retail_v2beta.types import model as gcr_model +from google.cloud.retail_v2beta.types import model_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +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: 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.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 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 kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ModelServiceTransport",) diff --git a/google/cloud/retail_v2beta/services/model_service/transports/grpc.py b/google/cloud/retail_v2beta/services/model_service/transports/grpc.py new file mode 100644 index 00000000..62ce4b48 --- /dev/null +++ b/google/cloud/retail_v2beta/services/model_service/transports/grpc.py @@ -0,0 +1,449 @@ +# -*- 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.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +import grpc # type: ignore + +from google.cloud.retail_v2beta.types import model +from google.cloud.retail_v2beta.types import model as gcr_model +from google.cloud.retail_v2beta.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: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + 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: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + 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.v2beta.ModelService/CreateModel", + request_serializer=model_service.CreateModelRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_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.v2beta.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.v2beta.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.v2beta.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.v2beta.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.v2beta.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.v2beta.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 kind(self) -> str: + return "grpc" + + +__all__ = ("ModelServiceGrpcTransport",) diff --git a/google/cloud/retail_v2beta/services/model_service/transports/grpc_asyncio.py b/google/cloud/retail_v2beta/services/model_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..97b02933 --- /dev/null +++ b/google/cloud/retail_v2beta/services/model_service/transports/grpc_asyncio.py @@ -0,0 +1,460 @@ +# -*- 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.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_v2beta.types import model +from google.cloud.retail_v2beta.types import model as gcr_model +from google.cloud.retail_v2beta.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: 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: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: aio.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id=None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + 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.v2beta.ModelService/CreateModel", + request_serializer=model_service.CreateModelRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_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.v2beta.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.v2beta.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.v2beta.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.v2beta.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.v2beta.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.v2beta.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() + + +__all__ = ("ModelServiceGrpcAsyncIOTransport",) diff --git a/google/cloud/retail_v2beta/services/product_service/async_client.py b/google/cloud/retail_v2beta/services/product_service/async_client.py index baa092bf..9d495a80 100644 --- a/google/cloud/retail_v2beta/services/product_service/async_client.py +++ b/google/cloud/retail_v2beta/services/product_service/async_client.py @@ -949,10 +949,10 @@ async def set_inventory( This process is asynchronous and does not require the [Product][google.cloud.retail.v2beta.Product] to exist before updating fulfillment information. If the request is valid, the - update will be enqueued and processed downstream. As a - consequence, when a response is returned, updates are not - immediately manifested in the - [Product][google.cloud.retail.v2beta.Product] queried by + update is enqueued and processed downstream. As a consequence, + when a response is returned, updates are not immediately + manifested in the [Product][google.cloud.retail.v2beta.Product] + queried by [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] or [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. @@ -961,10 +961,10 @@ async def set_inventory( [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] and [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct], - the specified inventory field value(s) will overwrite any - existing value(s) while ignoring the last update time for this - field. Furthermore, the last update time for the specified - inventory fields will be overwritten to the time of the + the specified inventory field value(s) overwrite any existing + value(s) while ignoring the last update time for this field. + Furthermore, the last update times for the specified inventory + fields are overwritten by the times of the [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] or [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] @@ -972,12 +972,12 @@ async def set_inventory( If no inventory fields are set in [CreateProductRequest.product][google.cloud.retail.v2beta.CreateProductRequest.product], - then any pre-existing inventory information for this product - will be used. + then any pre-existing inventory information for this product is + used. If no inventory fields are set in [SetInventoryRequest.set_mask][google.cloud.retail.v2beta.SetInventoryRequest.set_mask], - then any existing inventory information will be preserved. + then any existing inventory information is preserved. Pre-existing inventory information can only be updated with [ProductService.SetInventory][google.cloud.retail.v2beta.ProductService.SetInventory], @@ -985,9 +985,20 @@ async def set_inventory( and [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces]. + The returned [Operation][google.longrunning.Operation]s is + obsolete after one day, and the + [GetOperation][google.longrunning.Operations.GetOperation] API + returns ``NOT_FOUND`` afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates are not marked as + [done][google.longrunning.Operation.done] until they are + obsolete. + This feature is only available for users who have Retail Search - enabled. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. .. code-block:: python @@ -1196,9 +1207,19 @@ async def add_fulfillment_places( or [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + 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. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. .. code-block:: python @@ -1332,9 +1353,19 @@ async def remove_fulfillment_places( or [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + 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. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. .. code-block:: python @@ -1477,9 +1508,19 @@ async def add_local_inventories( [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] has no effect on local inventories. + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + 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. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. .. code-block:: python @@ -1619,9 +1660,19 @@ async def remove_local_inventories( [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] has no effect on local inventories. + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + 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. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. .. code-block:: python diff --git a/google/cloud/retail_v2beta/services/product_service/client.py b/google/cloud/retail_v2beta/services/product_service/client.py index e32d73a1..0cc0b806 100644 --- a/google/cloud/retail_v2beta/services/product_service/client.py +++ b/google/cloud/retail_v2beta/services/product_service/client.py @@ -1191,10 +1191,10 @@ def set_inventory( This process is asynchronous and does not require the [Product][google.cloud.retail.v2beta.Product] to exist before updating fulfillment information. If the request is valid, the - update will be enqueued and processed downstream. As a - consequence, when a response is returned, updates are not - immediately manifested in the - [Product][google.cloud.retail.v2beta.Product] queried by + update is enqueued and processed downstream. As a consequence, + when a response is returned, updates are not immediately + manifested in the [Product][google.cloud.retail.v2beta.Product] + queried by [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] or [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. @@ -1203,10 +1203,10 @@ def set_inventory( [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] and [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct], - the specified inventory field value(s) will overwrite any - existing value(s) while ignoring the last update time for this - field. Furthermore, the last update time for the specified - inventory fields will be overwritten to the time of the + the specified inventory field value(s) overwrite any existing + value(s) while ignoring the last update time for this field. + Furthermore, the last update times for the specified inventory + fields are overwritten by the times of the [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] or [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] @@ -1214,12 +1214,12 @@ def set_inventory( If no inventory fields are set in [CreateProductRequest.product][google.cloud.retail.v2beta.CreateProductRequest.product], - then any pre-existing inventory information for this product - will be used. + then any pre-existing inventory information for this product is + used. If no inventory fields are set in [SetInventoryRequest.set_mask][google.cloud.retail.v2beta.SetInventoryRequest.set_mask], - then any existing inventory information will be preserved. + then any existing inventory information is preserved. Pre-existing inventory information can only be updated with [ProductService.SetInventory][google.cloud.retail.v2beta.ProductService.SetInventory], @@ -1227,9 +1227,20 @@ def set_inventory( and [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces]. + The returned [Operation][google.longrunning.Operation]s is + obsolete after one day, and the + [GetOperation][google.longrunning.Operations.GetOperation] API + returns ``NOT_FOUND`` afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates are not marked as + [done][google.longrunning.Operation.done] until they are + obsolete. + This feature is only available for users who have Retail Search - enabled. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. .. code-block:: python @@ -1438,9 +1449,19 @@ def add_fulfillment_places( or [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + 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. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. .. code-block:: python @@ -1574,9 +1595,19 @@ def remove_fulfillment_places( or [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + 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. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. .. code-block:: python @@ -1721,9 +1752,19 @@ def add_local_inventories( [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] has no effect on local inventories. + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + 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. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. .. code-block:: python @@ -1863,9 +1904,19 @@ def remove_local_inventories( [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] has no effect on local inventories. + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + 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. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. .. code-block:: python diff --git a/google/cloud/retail_v2beta/services/product_service/transports/grpc.py b/google/cloud/retail_v2beta/services/product_service/transports/grpc.py index 50b507e1..d8fe162a 100644 --- a/google/cloud/retail_v2beta/services/product_service/transports/grpc.py +++ b/google/cloud/retail_v2beta/services/product_service/transports/grpc.py @@ -428,10 +428,10 @@ def set_inventory( This process is asynchronous and does not require the [Product][google.cloud.retail.v2beta.Product] to exist before updating fulfillment information. If the request is valid, the - update will be enqueued and processed downstream. As a - consequence, when a response is returned, updates are not - immediately manifested in the - [Product][google.cloud.retail.v2beta.Product] queried by + update is enqueued and processed downstream. As a consequence, + when a response is returned, updates are not immediately + manifested in the [Product][google.cloud.retail.v2beta.Product] + queried by [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] or [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. @@ -440,10 +440,10 @@ def set_inventory( [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] and [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct], - the specified inventory field value(s) will overwrite any - existing value(s) while ignoring the last update time for this - field. Furthermore, the last update time for the specified - inventory fields will be overwritten to the time of the + the specified inventory field value(s) overwrite any existing + value(s) while ignoring the last update time for this field. + Furthermore, the last update times for the specified inventory + fields are overwritten by the times of the [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] or [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] @@ -451,12 +451,12 @@ def set_inventory( If no inventory fields are set in [CreateProductRequest.product][google.cloud.retail.v2beta.CreateProductRequest.product], - then any pre-existing inventory information for this product - will be used. + then any pre-existing inventory information for this product is + used. If no inventory fields are set in [SetInventoryRequest.set_mask][google.cloud.retail.v2beta.SetInventoryRequest.set_mask], - then any existing inventory information will be preserved. + then any existing inventory information is preserved. Pre-existing inventory information can only be updated with [ProductService.SetInventory][google.cloud.retail.v2beta.ProductService.SetInventory], @@ -464,9 +464,20 @@ def set_inventory( and [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces]. + The returned [Operation][google.longrunning.Operation]s is + obsolete after one day, and the + [GetOperation][google.longrunning.Operations.GetOperation] API + returns ``NOT_FOUND`` afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates are not marked as + [done][google.longrunning.Operation.done] until they are + obsolete. + This feature is only available for users who have Retail Search - enabled. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. Returns: Callable[[~.SetInventoryRequest], @@ -508,9 +519,19 @@ def add_fulfillment_places( or [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + 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. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. Returns: Callable[[~.AddFulfillmentPlacesRequest], @@ -552,9 +573,19 @@ def remove_fulfillment_places( or [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + 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. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. Returns: Callable[[~.RemoveFulfillmentPlacesRequest], @@ -605,9 +636,19 @@ def add_local_inventories( [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] has no effect on local inventories. + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + 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. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. Returns: Callable[[~.AddLocalInventoriesRequest], @@ -655,9 +696,19 @@ def remove_local_inventories( [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] has no effect on local inventories. + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + 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. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. Returns: Callable[[~.RemoveLocalInventoriesRequest], diff --git a/google/cloud/retail_v2beta/services/product_service/transports/grpc_asyncio.py b/google/cloud/retail_v2beta/services/product_service/transports/grpc_asyncio.py index 9d1375c6..820767d3 100644 --- a/google/cloud/retail_v2beta/services/product_service/transports/grpc_asyncio.py +++ b/google/cloud/retail_v2beta/services/product_service/transports/grpc_asyncio.py @@ -442,10 +442,10 @@ def set_inventory( This process is asynchronous and does not require the [Product][google.cloud.retail.v2beta.Product] to exist before updating fulfillment information. If the request is valid, the - update will be enqueued and processed downstream. As a - consequence, when a response is returned, updates are not - immediately manifested in the - [Product][google.cloud.retail.v2beta.Product] queried by + update is enqueued and processed downstream. As a consequence, + when a response is returned, updates are not immediately + manifested in the [Product][google.cloud.retail.v2beta.Product] + queried by [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] or [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. @@ -454,10 +454,10 @@ def set_inventory( [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] and [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct], - the specified inventory field value(s) will overwrite any - existing value(s) while ignoring the last update time for this - field. Furthermore, the last update time for the specified - inventory fields will be overwritten to the time of the + the specified inventory field value(s) overwrite any existing + value(s) while ignoring the last update time for this field. + Furthermore, the last update times for the specified inventory + fields are overwritten by the times of the [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] or [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] @@ -465,12 +465,12 @@ def set_inventory( If no inventory fields are set in [CreateProductRequest.product][google.cloud.retail.v2beta.CreateProductRequest.product], - then any pre-existing inventory information for this product - will be used. + then any pre-existing inventory information for this product is + used. If no inventory fields are set in [SetInventoryRequest.set_mask][google.cloud.retail.v2beta.SetInventoryRequest.set_mask], - then any existing inventory information will be preserved. + then any existing inventory information is preserved. Pre-existing inventory information can only be updated with [ProductService.SetInventory][google.cloud.retail.v2beta.ProductService.SetInventory], @@ -478,9 +478,20 @@ def set_inventory( and [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces]. + The returned [Operation][google.longrunning.Operation]s is + obsolete after one day, and the + [GetOperation][google.longrunning.Operations.GetOperation] API + returns ``NOT_FOUND`` afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates are not marked as + [done][google.longrunning.Operation.done] until they are + obsolete. + This feature is only available for users who have Retail Search - enabled. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. Returns: Callable[[~.SetInventoryRequest], @@ -523,9 +534,19 @@ def add_fulfillment_places( or [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + 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. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. Returns: Callable[[~.AddFulfillmentPlacesRequest], @@ -568,9 +589,19 @@ def remove_fulfillment_places( or [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + 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. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. Returns: Callable[[~.RemoveFulfillmentPlacesRequest], @@ -622,9 +653,19 @@ def add_local_inventories( [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] has no effect on local inventories. + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + 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. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. Returns: Callable[[~.AddLocalInventoriesRequest], @@ -673,9 +714,19 @@ def remove_local_inventories( [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] has no effect on local inventories. + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + 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. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. Returns: Callable[[~.RemoveLocalInventoriesRequest], diff --git a/google/cloud/retail_v2beta/services/search_service/async_client.py b/google/cloud/retail_v2beta/services/search_service/async_client.py index d173a9b3..713b480f 100644 --- a/google/cloud/retail_v2beta/services/search_service/async_client.py +++ b/google/cloud/retail_v2beta/services/search_service/async_client.py @@ -42,8 +42,8 @@ class SearchServiceAsyncClient: """Service for search. This feature is only available for users who have Retail Search - enabled. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. """ _client: SearchServiceClient @@ -219,8 +219,8 @@ async def search( ) -> pagers.SearchAsyncPager: r"""Performs a search. This feature is only available for users who have Retail - Search enabled. Please enable Retail Search on Cloud - Console before using this feature. + Search enabled. Enable Retail Search on Cloud Console + before using this feature. .. code-block:: python diff --git a/google/cloud/retail_v2beta/services/search_service/client.py b/google/cloud/retail_v2beta/services/search_service/client.py index 63de7577..f56173a7 100644 --- a/google/cloud/retail_v2beta/services/search_service/client.py +++ b/google/cloud/retail_v2beta/services/search_service/client.py @@ -79,8 +79,8 @@ def get_transport_class( class SearchServiceClient(metaclass=SearchServiceClientMeta): """Service for search. This feature is only available for users who have Retail Search - enabled. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. """ @staticmethod @@ -468,8 +468,8 @@ def search( ) -> pagers.SearchPager: r"""Performs a search. This feature is only available for users who have Retail - Search enabled. Please enable Retail Search on Cloud - Console before using this feature. + Search enabled. Enable Retail Search on Cloud Console + before using this feature. .. code-block:: python diff --git a/google/cloud/retail_v2beta/services/search_service/transports/grpc.py b/google/cloud/retail_v2beta/services/search_service/transports/grpc.py index ed77783d..644dba7c 100644 --- a/google/cloud/retail_v2beta/services/search_service/transports/grpc.py +++ b/google/cloud/retail_v2beta/services/search_service/transports/grpc.py @@ -32,8 +32,8 @@ class SearchServiceGrpcTransport(SearchServiceTransport): Service for search. This feature is only available for users who have Retail Search - enabled. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. This class defines the same methods as the primary client, so the primary client can load the underlying transport implementation @@ -239,8 +239,8 @@ def search( Performs a search. This feature is only available for users who have Retail - Search enabled. Please enable Retail Search on Cloud - Console before using this feature. + Search enabled. Enable Retail Search on Cloud Console + before using this feature. Returns: Callable[[~.SearchRequest], diff --git a/google/cloud/retail_v2beta/services/search_service/transports/grpc_asyncio.py b/google/cloud/retail_v2beta/services/search_service/transports/grpc_asyncio.py index 6f55904f..74c2f1bd 100644 --- a/google/cloud/retail_v2beta/services/search_service/transports/grpc_asyncio.py +++ b/google/cloud/retail_v2beta/services/search_service/transports/grpc_asyncio.py @@ -33,8 +33,8 @@ class SearchServiceGrpcAsyncIOTransport(SearchServiceTransport): Service for search. This feature is only available for users who have Retail Search - enabled. Please enable Retail Search on Cloud Console before - using this feature. + enabled. Enable Retail Search on Cloud Console before using this + feature. This class defines the same methods as the primary client, so the primary client can load the underlying transport implementation @@ -244,8 +244,8 @@ def search( Performs a search. This feature is only available for users who have Retail - Search enabled. Please enable Retail Search on Cloud - Console before using this feature. + Search enabled. Enable Retail Search on Cloud Console + before using this feature. Returns: Callable[[~.SearchRequest], diff --git a/google/cloud/retail_v2beta/services/serving_config_service/async_client.py b/google/cloud/retail_v2beta/services/serving_config_service/async_client.py index 412f7686..d0448998 100644 --- a/google/cloud/retail_v2beta/services/serving_config_service/async_client.py +++ b/google/cloud/retail_v2beta/services/serving_config_service/async_client.py @@ -293,11 +293,10 @@ async def sample_create_serving_config(): Returns: google.cloud.retail_v2beta.types.ServingConfig: - Configures metadata that is used to generate serving time results (e.g. - search results or recommendation predictions). The - ServingConfig is passed in the search and predict - request and together with the Catalog.default_branch, - generates results. + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). """ # Create or coerce a protobuf request object. @@ -382,7 +381,7 @@ async def sample_delete_serving_config(): name (:class:`str`): Required. The resource name of the ServingConfig to delete. Format: - projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id} + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -498,11 +497,10 @@ async def sample_update_serving_config(): Returns: google.cloud.retail_v2beta.types.ServingConfig: - Configures metadata that is used to generate serving time results (e.g. - search results or recommendation predictions). The - ServingConfig is passed in the search and predict - request and together with the Catalog.default_branch, - generates results. + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). """ # Create or coerce a protobuf request object. @@ -589,7 +587,7 @@ async def sample_get_serving_config(): name (:class:`str`): Required. The resource name of the ServingConfig to get. Format: - projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id} + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -602,11 +600,10 @@ async def sample_get_serving_config(): Returns: google.cloud.retail_v2beta.types.ServingConfig: - Configures metadata that is used to generate serving time results (e.g. - search results or recommendation predictions). The - ServingConfig is passed in the search and predict - request and together with the Catalog.default_branch, - generates results. + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). """ # Create or coerce a protobuf request object. @@ -688,7 +685,7 @@ async def sample_list_serving_configs(): method. parent (:class:`str`): Required. The catalog resource name. Format: - projects/{project_number}/locations/{location_id}/catalogs/{catalog_id} + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -802,7 +799,7 @@ async def sample_add_control(): serving_config (:class:`str`): Required. The source ServingConfig resource name . Format: - projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id} + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` This corresponds to the ``serving_config`` field on the ``request`` instance; if ``request`` is provided, this @@ -815,11 +812,10 @@ async def sample_add_control(): Returns: google.cloud.retail_v2beta.types.ServingConfig: - Configures metadata that is used to generate serving time results (e.g. - search results or recommendation predictions). The - ServingConfig is passed in the search and predict - request and together with the Catalog.default_branch, - generates results. + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). """ # Create or coerce a protobuf request object. @@ -905,7 +901,7 @@ async def sample_remove_control(): serving_config (:class:`str`): Required. The source ServingConfig resource name . Format: - projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id} + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` This corresponds to the ``serving_config`` field on the ``request`` instance; if ``request`` is provided, this @@ -918,11 +914,10 @@ async def sample_remove_control(): Returns: google.cloud.retail_v2beta.types.ServingConfig: - Configures metadata that is used to generate serving time results (e.g. - search results or recommendation predictions). The - ServingConfig is passed in the search and predict - request and together with the Catalog.default_branch, - generates results. + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). """ # Create or coerce a protobuf request object. diff --git a/google/cloud/retail_v2beta/services/serving_config_service/client.py b/google/cloud/retail_v2beta/services/serving_config_service/client.py index 05ab7431..61de39e6 100644 --- a/google/cloud/retail_v2beta/services/serving_config_service/client.py +++ b/google/cloud/retail_v2beta/services/serving_config_service/client.py @@ -537,11 +537,10 @@ def sample_create_serving_config(): Returns: google.cloud.retail_v2beta.types.ServingConfig: - Configures metadata that is used to generate serving time results (e.g. - search results or recommendation predictions). The - ServingConfig is passed in the search and predict - request and together with the Catalog.default_branch, - generates results. + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). """ # Create or coerce a protobuf request object. @@ -626,7 +625,7 @@ def sample_delete_serving_config(): name (str): Required. The resource name of the ServingConfig to delete. Format: - projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id} + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -742,11 +741,10 @@ def sample_update_serving_config(): Returns: google.cloud.retail_v2beta.types.ServingConfig: - Configures metadata that is used to generate serving time results (e.g. - search results or recommendation predictions). The - ServingConfig is passed in the search and predict - request and together with the Catalog.default_branch, - generates results. + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). """ # Create or coerce a protobuf request object. @@ -833,7 +831,7 @@ def sample_get_serving_config(): name (str): Required. The resource name of the ServingConfig to get. Format: - projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id} + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -846,11 +844,10 @@ def sample_get_serving_config(): Returns: google.cloud.retail_v2beta.types.ServingConfig: - Configures metadata that is used to generate serving time results (e.g. - search results or recommendation predictions). The - ServingConfig is passed in the search and predict - request and together with the Catalog.default_branch, - generates results. + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). """ # Create or coerce a protobuf request object. @@ -932,7 +929,7 @@ def sample_list_serving_configs(): method. parent (str): Required. The catalog resource name. Format: - projects/{project_number}/locations/{location_id}/catalogs/{catalog_id} + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -1046,7 +1043,7 @@ def sample_add_control(): serving_config (str): Required. The source ServingConfig resource name . Format: - projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id} + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` This corresponds to the ``serving_config`` field on the ``request`` instance; if ``request`` is provided, this @@ -1059,11 +1056,10 @@ def sample_add_control(): Returns: google.cloud.retail_v2beta.types.ServingConfig: - Configures metadata that is used to generate serving time results (e.g. - search results or recommendation predictions). The - ServingConfig is passed in the search and predict - request and together with the Catalog.default_branch, - generates results. + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). """ # Create or coerce a protobuf request object. @@ -1149,7 +1145,7 @@ def sample_remove_control(): serving_config (str): Required. The source ServingConfig resource name . Format: - projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id} + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` This corresponds to the ``serving_config`` field on the ``request`` instance; if ``request`` is provided, this @@ -1162,11 +1158,10 @@ def sample_remove_control(): Returns: google.cloud.retail_v2beta.types.ServingConfig: - Configures metadata that is used to generate serving time results (e.g. - search results or recommendation predictions). The - ServingConfig is passed in the search and predict - request and together with the Catalog.default_branch, - generates results. + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). """ # Create or coerce a protobuf request object. diff --git a/google/cloud/retail_v2beta/services/user_event_service/async_client.py b/google/cloud/retail_v2beta/services/user_event_service/async_client.py index 4e562d4c..4cd78789 100644 --- a/google/cloud/retail_v2beta/services/user_event_service/async_client.py +++ b/google/cloud/retail_v2beta/services/user_event_service/async_client.py @@ -532,13 +532,13 @@ async def import_user_events( timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> operation_async.AsyncOperation: - r"""Bulk import of User events. Request processing might - be synchronous. Events that already exist are skipped. - Use this method for backfilling historical user events. - Operation.response is of type ImportResponse. Note that - it is possible for a subset of the items to be - successfully inserted. Operation.metadata is of type - ImportMetadata. + r"""Bulk import of User events. Request processing might be + synchronous. Events that already exist are skipped. Use this + method for backfilling historical user events. + + ``Operation.response`` is of type ``ImportResponse``. Note that + it is possible for a subset of the items to be successfully + inserted. ``Operation.metadata`` is of type ``ImportMetadata``. .. code-block:: python @@ -643,15 +643,15 @@ async def rejoin_user_events( timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> operation_async.AsyncOperation: - r"""Starts a user event rejoin operation with latest - product catalog. Events will not be annotated with - detailed product information if product is missing from - the catalog at the time the user event is ingested, and - these events are stored as unjoined events with a - limited usage on training and serving. This method can - be used to start a join operation on specified events - with latest version of product catalog. It can also be - used to correct events joined with the wrong product + r"""Starts a user-event rejoin operation with latest + product catalog. Events are not annotated with detailed + product information for products that are missing from + the catalog when the user event is ingested. These + events are stored as unjoined events with limited usage + on training and serving. You can use this method to + start a join operation on specified events with the + latest version of product catalog. You can also use this + method to correct events joined with the wrong product catalog. A rejoin operation can take hours or days to complete. diff --git a/google/cloud/retail_v2beta/services/user_event_service/client.py b/google/cloud/retail_v2beta/services/user_event_service/client.py index 62799ce6..1bffc38b 100644 --- a/google/cloud/retail_v2beta/services/user_event_service/client.py +++ b/google/cloud/retail_v2beta/services/user_event_service/client.py @@ -774,13 +774,13 @@ def import_user_events( timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> operation.Operation: - r"""Bulk import of User events. Request processing might - be synchronous. Events that already exist are skipped. - Use this method for backfilling historical user events. - Operation.response is of type ImportResponse. Note that - it is possible for a subset of the items to be - successfully inserted. Operation.metadata is of type - ImportMetadata. + r"""Bulk import of User events. Request processing might be + synchronous. Events that already exist are skipped. Use this + method for backfilling historical user events. + + ``Operation.response`` is of type ``ImportResponse``. Note that + it is possible for a subset of the items to be successfully + inserted. ``Operation.metadata`` is of type ``ImportMetadata``. .. code-block:: python @@ -876,15 +876,15 @@ def rejoin_user_events( timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> operation.Operation: - r"""Starts a user event rejoin operation with latest - product catalog. Events will not be annotated with - detailed product information if product is missing from - the catalog at the time the user event is ingested, and - these events are stored as unjoined events with a - limited usage on training and serving. This method can - be used to start a join operation on specified events - with latest version of product catalog. It can also be - used to correct events joined with the wrong product + r"""Starts a user-event rejoin operation with latest + product catalog. Events are not annotated with detailed + product information for products that are missing from + the catalog when the user event is ingested. These + events are stored as unjoined events with limited usage + on training and serving. You can use this method to + start a join operation on specified events with the + latest version of product catalog. You can also use this + method to correct events joined with the wrong product catalog. A rejoin operation can take hours or days to complete. diff --git a/google/cloud/retail_v2beta/services/user_event_service/transports/grpc.py b/google/cloud/retail_v2beta/services/user_event_service/transports/grpc.py index b2a3c32b..a54e0e5e 100644 --- a/google/cloud/retail_v2beta/services/user_event_service/transports/grpc.py +++ b/google/cloud/retail_v2beta/services/user_event_service/transports/grpc.py @@ -344,13 +344,13 @@ def import_user_events( ) -> Callable[[import_config.ImportUserEventsRequest], operations_pb2.Operation]: r"""Return a callable for the import user events method over gRPC. - Bulk import of User events. Request processing might - be synchronous. Events that already exist are skipped. - Use this method for backfilling historical user events. - Operation.response is of type ImportResponse. Note that - it is possible for a subset of the items to be - successfully inserted. Operation.metadata is of type - ImportMetadata. + Bulk import of User events. Request processing might be + synchronous. Events that already exist are skipped. Use this + method for backfilling historical user events. + + ``Operation.response`` is of type ``ImportResponse``. Note that + it is possible for a subset of the items to be successfully + inserted. ``Operation.metadata`` is of type ``ImportMetadata``. Returns: Callable[[~.ImportUserEventsRequest], @@ -378,15 +378,15 @@ def rejoin_user_events( ]: r"""Return a callable for the rejoin user events method over gRPC. - Starts a user event rejoin operation with latest - product catalog. Events will not be annotated with - detailed product information if product is missing from - the catalog at the time the user event is ingested, and - these events are stored as unjoined events with a - limited usage on training and serving. This method can - be used to start a join operation on specified events - with latest version of product catalog. It can also be - used to correct events joined with the wrong product + Starts a user-event rejoin operation with latest + product catalog. Events are not annotated with detailed + product information for products that are missing from + the catalog when the user event is ingested. These + events are stored as unjoined events with limited usage + on training and serving. You can use this method to + start a join operation on specified events with the + latest version of product catalog. You can also use this + method to correct events joined with the wrong product catalog. A rejoin operation can take hours or days to complete. diff --git a/google/cloud/retail_v2beta/services/user_event_service/transports/grpc_asyncio.py b/google/cloud/retail_v2beta/services/user_event_service/transports/grpc_asyncio.py index dff289fc..94cfb9da 100644 --- a/google/cloud/retail_v2beta/services/user_event_service/transports/grpc_asyncio.py +++ b/google/cloud/retail_v2beta/services/user_event_service/transports/grpc_asyncio.py @@ -357,13 +357,13 @@ def import_user_events( ]: r"""Return a callable for the import user events method over gRPC. - Bulk import of User events. Request processing might - be synchronous. Events that already exist are skipped. - Use this method for backfilling historical user events. - Operation.response is of type ImportResponse. Note that - it is possible for a subset of the items to be - successfully inserted. Operation.metadata is of type - ImportMetadata. + Bulk import of User events. Request processing might be + synchronous. Events that already exist are skipped. Use this + method for backfilling historical user events. + + ``Operation.response`` is of type ``ImportResponse``. Note that + it is possible for a subset of the items to be successfully + inserted. ``Operation.metadata`` is of type ``ImportMetadata``. Returns: Callable[[~.ImportUserEventsRequest], @@ -392,15 +392,15 @@ def rejoin_user_events( ]: r"""Return a callable for the rejoin user events method over gRPC. - Starts a user event rejoin operation with latest - product catalog. Events will not be annotated with - detailed product information if product is missing from - the catalog at the time the user event is ingested, and - these events are stored as unjoined events with a - limited usage on training and serving. This method can - be used to start a join operation on specified events - with latest version of product catalog. It can also be - used to correct events joined with the wrong product + Starts a user-event rejoin operation with latest + product catalog. Events are not annotated with detailed + product information for products that are missing from + the catalog when the user event is ingested. These + events are stored as unjoined events with limited usage + on training and serving. You can use this method to + start a join operation on specified events with the + latest version of product catalog. You can also use this + method to correct events joined with the wrong product catalog. A rejoin operation can take hours or days to complete. diff --git a/google/cloud/retail_v2beta/types/__init__.py b/google/cloud/retail_v2beta/types/__init__.py index da95ede5..0dd8ce33 100644 --- a/google/cloud/retail_v2beta/types/__init__.py +++ b/google/cloud/retail_v2beta/types/__init__.py @@ -24,6 +24,8 @@ ) from .catalog_service import ( AddCatalogAttributeRequest, + BatchRemoveCatalogAttributesRequest, + BatchRemoveCatalogAttributesResponse, GetAttributesConfigRequest, GetCompletionConfigRequest, GetDefaultBranchRequest, @@ -91,6 +93,20 @@ UserEventInlineSource, UserEventInputConfig, ) +from .model import Model +from .model_service import ( + CreateModelMetadata, + CreateModelRequest, + DeleteModelRequest, + ListModelsRequest, + ListModelsResponse, + PauseModelRequest, + ResumeModelRequest, + TuneModelMetadata, + TuneModelRequest, + TuneModelResponse, + UpdateModelRequest, +) from .prediction_service import PredictRequest, PredictResponse from .product import Product from .product_service import ( @@ -148,6 +164,8 @@ "MerchantCenterLinkingConfig", "ProductLevelConfig", "AddCatalogAttributeRequest", + "BatchRemoveCatalogAttributesRequest", + "BatchRemoveCatalogAttributesResponse", "GetAttributesConfigRequest", "GetCompletionConfigRequest", "GetDefaultBranchRequest", @@ -207,6 +225,18 @@ "UserEventImportSummary", "UserEventInlineSource", "UserEventInputConfig", + "Model", + "CreateModelMetadata", + "CreateModelRequest", + "DeleteModelRequest", + "ListModelsRequest", + "ListModelsResponse", + "PauseModelRequest", + "ResumeModelRequest", + "TuneModelMetadata", + "TuneModelRequest", + "TuneModelResponse", + "UpdateModelRequest", "PredictRequest", "PredictResponse", "Product", diff --git a/google/cloud/retail_v2beta/types/catalog.py b/google/cloud/retail_v2beta/types/catalog.py index 5ef0563f..08fd8ea5 100644 --- a/google/cloud/retail_v2beta/types/catalog.py +++ b/google/cloud/retail_v2beta/types/catalog.py @@ -182,6 +182,11 @@ class CatalogAttribute(proto.Message): filterable for recommendations. This option works for categorical features only, does not work for numerical features, inventory filtering. + exact_searchable_option (google.cloud.retail_v2beta.types.CatalogAttribute.ExactSearchableOption): + 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. """ class AttributeType(proto.Enum): @@ -210,6 +215,14 @@ class SearchableOption(proto.Enum): SEARCHABLE_ENABLED = 1 SEARCHABLE_DISABLED = 2 + class ExactSearchableOption(proto.Enum): + r"""The status of the exact-searchable option of a catalog + attribute. + """ + EXACT_SEARCHABLE_OPTION_UNSPECIFIED = 0 + EXACT_SEARCHABLE_ENABLED = 1 + EXACT_SEARCHABLE_DISABLED = 2 + key = proto.Field( proto.STRING, number=1, @@ -243,6 +256,11 @@ class SearchableOption(proto.Enum): number=8, enum=common.RecommendationsFilteringOption, ) + exact_searchable_option = proto.Field( + proto.ENUM, + number=11, + enum=ExactSearchableOption, + ) class AttributesConfig(proto.Message): @@ -432,9 +450,9 @@ class MerchantCenterLink(proto.Message): account id. destinations (Sequence[str]): String representing the destination to import for, all if - left empty. List of possible values can be found here. - [https://support.google.com/merchants/answer/7501026] List - of allowed string values: "Shopping_ads", + left empty. List of possible values is given in `Included + destination `__. + List of allowed string values: "Shopping_ads", "Buy_on_google_listings", "Display_ads", "Local_inventory \_ads", "Free_listings", "Free_local_listings" NOTE: The string values are case sensitive. diff --git a/google/cloud/retail_v2beta/types/catalog_service.py b/google/cloud/retail_v2beta/types/catalog_service.py index e41dfb2f..3d046dfe 100644 --- a/google/cloud/retail_v2beta/types/catalog_service.py +++ b/google/cloud/retail_v2beta/types/catalog_service.py @@ -34,6 +34,8 @@ "UpdateAttributesConfigRequest", "AddCatalogAttributeRequest", "RemoveCatalogAttributeRequest", + "BatchRemoveCatalogAttributesRequest", + "BatchRemoveCatalogAttributesResponse", "ReplaceCatalogAttributeRequest", }, ) @@ -259,7 +261,7 @@ class GetCompletionConfigRequest(proto.Message): Attributes: name (str): Required. Full CompletionConfig resource name. Format: - projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/completionConfig + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/completionConfig`` """ name = proto.Field( @@ -411,6 +413,59 @@ class RemoveCatalogAttributeRequest(proto.Message): ) +class BatchRemoveCatalogAttributesRequest(proto.Message): + r"""Request for + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2beta.CatalogService.BatchRemoveCatalogAttributes] + method. + + Attributes: + attributes_config (str): + Required. The attributes config resource shared by all + catalog attributes being deleted. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`` + attribute_keys (Sequence[str]): + Required. The attribute name keys of the + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute]s + to delete. A maximum of 1000 catalog attributes can be + deleted in a batch. + """ + + attributes_config = proto.Field( + proto.STRING, + number=1, + ) + attribute_keys = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class BatchRemoveCatalogAttributesResponse(proto.Message): + r"""Response of the + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2beta.CatalogService.BatchRemoveCatalogAttributes]. + + Attributes: + deleted_catalog_attributes (Sequence[str]): + Catalog attributes that were deleted. Only attributes that + are not [in use][CatalogAttribute.in_use] by products can be + deleted. + reset_catalog_attributes (Sequence[str]): + Catalog attributes that were reset. Attributes that are [in + use][CatalogAttribute.in_use] by products cannot be deleted, + however their configuration properties will reset to default + values upon removal request. + """ + + deleted_catalog_attributes = proto.RepeatedField( + proto.STRING, + number=1, + ) + reset_catalog_attributes = proto.RepeatedField( + proto.STRING, + number=2, + ) + + class ReplaceCatalogAttributeRequest(proto.Message): r"""Request for [CatalogService.ReplaceCatalogAttribute][google.cloud.retail.v2beta.CatalogService.ReplaceCatalogAttribute] diff --git a/google/cloud/retail_v2beta/types/common.py b/google/cloud/retail_v2beta/types/common.py index f4e10e38..14a4284d 100644 --- a/google/cloud/retail_v2beta/types/common.py +++ b/google/cloud/retail_v2beta/types/common.py @@ -98,9 +98,9 @@ class QueryTerm(proto.Message): Value cannot be empty. Value can have at most 3 terms if specified as a partial match. Each space separated string is - considered as one term. Example) "a b c" is 3 - terms and allowed, " a b c d" is 4 terms and not - allowed for partial match. + considered as one term. For example, "a b c" is + 3 terms and allowed, but " a b c d" is 4 terms + and not allowed for a partial match. full_match (bool): Whether this is supposed to be a full or partial match. @@ -153,9 +153,9 @@ class Rule(proto.Message): r"""A rule is a condition-action pair - A condition defines when a rule is to be triggered. - - An action specifies what occurs on that trigger. Currently only - boost rules are supported. Currently only supported by the search - endpoint. + - An action specifies what occurs on that trigger. Currently rules + only work for [controls][google.cloud.retail.v2beta.Control] with + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2beta.SolutionType.SOLUTION_TYPE_SEARCH]. This message has `oneof`_ fields (mutually exclusive fields). For each oneof, at most one member field can be set at the same time. diff --git a/google/cloud/retail_v2beta/types/control.py b/google/cloud/retail_v2beta/types/control.py index c961a212..16b3f1be 100644 --- a/google/cloud/retail_v2beta/types/control.py +++ b/google/cloud/retail_v2beta/types/control.py @@ -26,8 +26,9 @@ class Control(proto.Message): - r"""Configures dynamic serving time metadata that is used to pre - and post process search/recommendation model results. + r"""Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] and affect + search or recommendation results at serving time. This message has `oneof`_ fields (mutually exclusive fields). For each oneof, at most one member field can be set at the same time. @@ -38,8 +39,10 @@ class Control(proto.Message): Attributes: facet_spec (google.cloud.retail_v2beta.types.SearchRequest.FacetSpec): - A facet specification to perform faceted - search. + A facet specification to perform faceted search. + + Note that this field is deprecated and will throw + NOT_IMPLEMENTED if used for creating a control. This field is a member of `oneof`_ ``control``. rule (google.cloud.retail_v2beta.types.Rule): @@ -60,20 +63,30 @@ class Control(proto.Message): limit of 128 characters. Otherwise, an INVALID_ARGUMENT error is thrown. associated_serving_config_ids (Sequence[str]): - Output only. List of serving configuration - ids that that are associated with this control. + Output only. List of [serving + configuration][google.cloud.retail.v2beta.ServingConfig] ids + that are associated with this control in the same + [Catalog][google.cloud.retail.v2beta.Catalog]. + Note the association is managed via the - ServingConfig, this is an output only - denormalizeed view. Assumed to be in the same - catalog. + [ServingConfig][google.cloud.retail.v2beta.ServingConfig], + this is an output only denormalized view. solution_types (Sequence[google.cloud.retail_v2beta.types.SolutionType]): - Required. Immutable. The solution types that the serving - config is used for. Currently we support setting only one - type of solution at creation time. + Required. Immutable. The solution types that the control is + used for. Currently we support setting only one type of + solution at creation time. Only ``SOLUTION_TYPE_SEARCH`` value is supported at the moment. If no solution type is provided at creation time, - will default to SOLUTION_TYPE_SEARCH. + will default to + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2beta.SolutionType.SOLUTION_TYPE_SEARCH]. + search_solution_use_case (Sequence[google.cloud.retail_v2beta.types.SearchSolutionUseCase]): + Specifies the use case for the control. Affects what + condition fields can be set. Only settable by search + controls. Will default to + [SEARCH_SOLUTION_USE_CASE_SEARCH][google.cloud.retail.v2beta.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + if not specified. Currently only allow one + search_solution_use_case per control. """ facet_spec = proto.Field( @@ -105,6 +118,11 @@ class Control(proto.Message): number=6, enum=common.SolutionType, ) + search_solution_use_case = proto.RepeatedField( + proto.ENUM, + number=7, + enum=common.SearchSolutionUseCase, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/retail_v2beta/types/control_service.py b/google/cloud/retail_v2beta/types/control_service.py index 31c48f32..fc041bc7 100644 --- a/google/cloud/retail_v2beta/types/control_service.py +++ b/google/cloud/retail_v2beta/types/control_service.py @@ -112,8 +112,7 @@ class GetControlRequest(proto.Message): Attributes: name (str): - Required. The resource name of the Control to delete. - Format: + Required. The resource name of the Control to get. Format: ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_id}`` """ diff --git a/google/cloud/retail_v2beta/types/export_config.py b/google/cloud/retail_v2beta/types/export_config.py index 3e058fc4..37577d28 100644 --- a/google/cloud/retail_v2beta/types/export_config.py +++ b/google/cloud/retail_v2beta/types/export_config.py @@ -54,8 +54,8 @@ class ExportErrorsConfig(proto.Message): class ExportMetadata(proto.Message): r"""Metadata related to the progress of the Export operation. - This will be returned by the - google.longrunning.Operation.metadata field. + This is returned by the google.longrunning.Operation.metadata + field. Attributes: create_time (google.protobuf.timestamp_pb2.Timestamp): diff --git a/google/cloud/retail_v2beta/types/import_config.py b/google/cloud/retail_v2beta/types/import_config.py index 4a29b72d..36f96e02 100644 --- a/google/cloud/retail_v2beta/types/import_config.py +++ b/google/cloud/retail_v2beta/types/import_config.py @@ -46,7 +46,6 @@ class GcsSource(proto.Message): r"""Google Cloud Storage location for input content. - format. Attributes: input_uris (Sequence[str]): @@ -82,12 +81,12 @@ class GcsSource(proto.Message): Supported values for control imports: - - 'control' (default): One JSON + - ``control`` (default): One JSON [Control][google.cloud.retail.v2beta.Control] per line. Supported values for catalog attribute imports: - - 'catalog_attribute' (default): One CSV + - ``catalog_attribute`` (default): One CSV [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] per line. """ @@ -112,9 +111,8 @@ class BigQuerySource(proto.Message): BigQuery time partitioned table's \_PARTITIONDATE in YYYY-MM-DD format. - Only supported when - [ImportProductsRequest.reconciliation_mode][google.cloud.retail.v2beta.ImportProductsRequest.reconciliation_mode] - is set to ``FULL``. + Only supported in + [ImportProductsRequest][google.cloud.retail.v2beta.ImportProductsRequest]. This field is a member of `oneof`_ ``partition``. project_id (str): @@ -155,9 +153,7 @@ class BigQuerySource(proto.Message): line. - ``user_event_ga360``: The schema is available here: https://support.google.com/analytics/answer/3437719. - - ``user_event_ga4``: This feature is in private preview. - Please contact the support team for importing Google - Analytics 4 events. The schema is available here: + - ``user_event_ga4``: The schema is available here: https://support.google.com/analytics/answer/7029846. Supported values for auto-completion imports: @@ -241,7 +237,7 @@ class ImportErrorsConfig(proto.Message): gcs_prefix (str): Google Cloud Storage prefix for import errors. This must be an empty, existing Cloud Storage directory. Import errors - will be written to sharded files in this directory, one per + are written to sharded files in this directory, one per line, as a JSON-encoded ``google.rpc.Status`` message. This field is a member of `oneof`_ ``destination``. @@ -274,34 +270,26 @@ class ImportProductsRequest(proto.Message): The desired location of errors incurred during the Import. update_mask (google.protobuf.field_mask_pb2.FieldMask): - Indicates which fields in the provided - imported 'products' to update. If not set, will - by default update all fields. + Indicates which fields in the provided imported ``products`` + to update. If not set, all fields are updated. reconciliation_mode (google.cloud.retail_v2beta.types.ImportProductsRequest.ReconciliationMode): The mode of reconciliation between existing products and the products to be imported. Defaults to [ReconciliationMode.INCREMENTAL][google.cloud.retail.v2beta.ImportProductsRequest.ReconciliationMode.INCREMENTAL]. notification_pubsub_topic (str): Full Pub/Sub topic name for receiving notification. If this - field is set, when the import is finished, a notification - will be sent to specified Pub/Sub topic. The message data - will be JSON string of a - [Operation][google.longrunning.Operation]. + field is set, when the import is finished, a notification is + sent to specified Pub/Sub topic. The message data is JSON + string of a [Operation][google.longrunning.Operation]. Format of the Pub/Sub topic is ``projects/{project}/topics/{topic}``. It has to be within the same project as [ImportProductsRequest.parent][google.cloud.retail.v2beta.ImportProductsRequest.parent]. - Make sure that both - ``cloud-retail-customer-data-access@system.gserviceaccount.com`` - and + Make sure that ``service-@gcp-sa-retail.iam.gserviceaccount.com`` - have the ``pubsub.topics.publish`` IAM permission on the + has the ``pubsub.topics.publish`` IAM permission on the topic. - - Only supported when - [ImportProductsRequest.reconciliation_mode][google.cloud.retail.v2beta.ImportProductsRequest.reconciliation_mode] - is set to ``FULL``. """ class ReconciliationMode(proto.Enum): @@ -393,11 +381,10 @@ class ImportCompletionDataRequest(proto.Message): data. notification_pubsub_topic (str): Pub/Sub topic for receiving notification. If this field is - set, when the import is finished, a notification will be - sent to specified Pub/Sub topic. The message data will be - JSON string of a [Operation][google.longrunning.Operation]. - Format of the Pub/Sub topic is - ``projects/{project}/topics/{topic}``. + set, when the import is finished, a notification is sent to + specified Pub/Sub topic. The message data is JSON string of + a [Operation][google.longrunning.Operation]. Format of the + Pub/Sub topic is ``projects/{project}/topics/{topic}``. """ parent = proto.Field( @@ -536,8 +523,8 @@ class CompletionDataInputConfig(proto.Message): class ImportMetadata(proto.Message): r"""Metadata related to the progress of the Import operation. - This will be returned by the - google.longrunning.Operation.metadata field. + This is returned by the google.longrunning.Operation.metadata + field. Attributes: create_time (google.protobuf.timestamp_pb2.Timestamp): @@ -555,11 +542,10 @@ class ImportMetadata(proto.Message): Deprecated. This field is never set. notification_pubsub_topic (str): Pub/Sub topic for receiving notification. If this field is - set, when the import is finished, a notification will be - sent to specified Pub/Sub topic. The message data will be - JSON string of a [Operation][google.longrunning.Operation]. - Format of the Pub/Sub topic is - ``projects/{project}/topics/{topic}``. + set, when the import is finished, a notification is sent to + specified Pub/Sub topic. The message data is JSON string of + a [Operation][google.longrunning.Operation]. Format of the + Pub/Sub topic is ``projects/{project}/topics/{topic}``. """ create_time = proto.Field( diff --git a/google/cloud/retail_v2beta/types/model.py b/google/cloud/retail_v2beta/types/model.py new file mode 100644 index 00000000..4f7a1a28 --- /dev/null +++ b/google/cloud/retail_v2beta/types/model.py @@ -0,0 +1,265 @@ +# -*- 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 google.protobuf import timestamp_pb2 # type: ignore +import proto # type: ignore + +from google.cloud.retail_v2beta.types import common + +__protobuf__ = proto.module( + package="google.cloud.retail.v2beta", + manifest={ + "Model", + }, +) + + +class Model(proto.Message): + r"""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. + + 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_v2beta.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_v2beta.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``, + and ``recently-viewed``\ (readonly value). + + This field together with + [optimization_objective][google.cloud.retail.v2beta.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.v2beta.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_v2beta.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_v2beta.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_v2beta.types.RecommendationsFilteringOption): + Optional. If ``RECOMMENDATIONS_FILTERING_ENABLED``, + recommendation filtering by attributes is enabled for the + model. + serving_config_lists (Sequence[google.cloud.retail_v2beta.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.""" + SERVING_STATE_UNSPECIFIED = 0 + INACTIVE = 1 + ACTIVE = 2 + TUNED = 3 + + class TrainingState(proto.Enum): + r"""The training state of the model.""" + 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. + """ + 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. + """ + 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 (Sequence[str]): + Optional. A set of valid serving configs that may be used + for ``PAGE_OPTIMIZATION``. + """ + + serving_config_ids = proto.RepeatedField( + proto.STRING, + number=1, + ) + + name = proto.Field( + proto.STRING, + number=1, + ) + display_name = proto.Field( + proto.STRING, + number=2, + ) + training_state = proto.Field( + proto.ENUM, + number=3, + enum=TrainingState, + ) + serving_state = proto.Field( + proto.ENUM, + number=4, + enum=ServingState, + ) + create_time = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + update_time = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + type_ = proto.Field( + proto.STRING, + number=7, + ) + optimization_objective = proto.Field( + proto.STRING, + number=8, + ) + periodic_tuning_state = proto.Field( + proto.ENUM, + number=11, + enum=PeriodicTuningState, + ) + last_tune_time = proto.Field( + proto.MESSAGE, + number=12, + message=timestamp_pb2.Timestamp, + ) + tuning_operation = proto.Field( + proto.STRING, + number=15, + ) + data_state = proto.Field( + proto.ENUM, + number=16, + enum=DataState, + ) + filtering_option = proto.Field( + proto.ENUM, + number=18, + enum=common.RecommendationsFilteringOption, + ) + serving_config_lists = proto.RepeatedField( + proto.MESSAGE, + number=19, + message=ServingConfigList, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/retail_v2beta/types/model_service.py b/google/cloud/retail_v2beta/types/model_service.py new file mode 100644 index 00000000..b41b0995 --- /dev/null +++ b/google/cloud/retail_v2beta/types/model_service.py @@ -0,0 +1,251 @@ +# -*- 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 google.protobuf import field_mask_pb2 # type: ignore +import proto # type: ignore + +from google.cloud.retail_v2beta.types import model as gcr_model + +__protobuf__ = proto.module( + package="google.cloud.retail.v2beta", + manifest={ + "CreateModelRequest", + "UpdateModelRequest", + "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_v2beta.types.Model): + Required. The payload of the + [Model][google.cloud.retail.v2beta.Model] to create. + dry_run (bool): + Optional. Whether to run a dry run to + validate the request (without actually creating + the model). + """ + + parent = proto.Field( + proto.STRING, + number=1, + ) + model = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_model.Model, + ) + dry_run = proto.Field( + proto.BOOL, + number=3, + ) + + +class UpdateModelRequest(proto.Message): + r"""Request for updating an existing model. + + Attributes: + model (google.cloud.retail_v2beta.types.Model): + Required. The body of the updated + [Model][google.cloud.retail.v2beta.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 = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_model.Model, + ) + update_mask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +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 = 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 = 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 = proto.Field( + proto.STRING, + number=1, + ) + page_size = proto.Field( + proto.INT32, + number=2, + ) + page_token = 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.v2beta.Model] to delete. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + name = proto.Field( + proto.STRING, + number=1, + ) + + +class ListModelsResponse(proto.Message): + r"""Response to a ListModelRequest. + + Attributes: + models (Sequence[google.cloud.retail_v2beta.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 = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcr_model.Model, + ) + next_page_token = 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 = 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 = 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 = 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/google/cloud/retail_v2beta/types/prediction_service.py b/google/cloud/retail_v2beta/types/prediction_service.py index f80a9138..c85a1a29 100644 --- a/google/cloud/retail_v2beta/types/prediction_service.py +++ b/google/cloud/retail_v2beta/types/prediction_service.py @@ -66,14 +66,13 @@ class PredictRequest(proto.Message): [UserInfo.user_id][google.cloud.retail.v2beta.UserInfo.user_id] unset. page_size (int): - Maximum number of results to return per page. - Set this property to the number of prediction - results needed. If zero, the service will choose - a reasonable default. The maximum allowed value - is 100. Values above 100 will be coerced to 100. + Maximum number of results to return. Set this + property to the number of prediction results + needed. If zero, the service will choose a + reasonable default. The maximum allowed value is + 100. Values above 100 will be coerced to 100. page_token (str): - This field is not used for now; leave it - unset. + This field is not used; leave it unset. filter (str): Filter for restricting prediction results with a length limit of 5,000 characters. Accepts values for tags and the diff --git a/google/cloud/retail_v2beta/types/product.py b/google/cloud/retail_v2beta/types/product.py index 1a4f7438..dd0e061c 100644 --- a/google/cloud/retail_v2beta/types/product.py +++ b/google/cloud/retail_v2beta/types/product.py @@ -148,7 +148,7 @@ class Product(proto.Message): [Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] or [Type.VARIANT][google.cloud.retail.v2beta.Product.Type.VARIANT] - otherwise and INVALID_ARGUMENT error is thrown. Should not + otherwise an INVALID_ARGUMENT error is thrown. Should not set it for other types. A maximum of 1000 values are allowed. Otherwise, an INVALID_ARGUMENT error is return. gtin (str): @@ -180,7 +180,7 @@ class Product(proto.Message): To represent full path of category, use '>' sign to separate different hierarchies. If '>' is part of the category name, - please replace it with other character(s). + replace it with other character(s). For example, if a shoes product belongs to both ["Shoes & Accessories" -> "Shoes"] and ["Sports & Fitness" -> @@ -528,6 +528,16 @@ class Product(proto.Message): Note: This field is OUTPUT_ONLY for [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct]. Do not set this field in API requests. + local_inventories (Sequence[google.cloud.retail_v2beta.types.LocalInventory]): + 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 + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + and + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + APIs. """ class Type(proto.Enum): @@ -699,6 +709,11 @@ class Availability(proto.Enum): number=31, message="Product", ) + local_inventories = proto.RepeatedField( + proto.MESSAGE, + number=35, + message=common.LocalInventory, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/retail_v2beta/types/search_service.py b/google/cloud/retail_v2beta/types/search_service.py index 995045dc..909bc298 100644 --- a/google/cloud/retail_v2beta/types/search_service.py +++ b/google/cloud/retail_v2beta/types/search_service.py @@ -262,7 +262,7 @@ class SearchRequest(proto.Message): To represent full path of category, use '>' sign to separate different hierarchies. If '>' is part of the category name, - please replace it with other character(s). + replace it with other character(s). Category pages include special pages such as sales or promotions. For instance, a special sale page may have the @@ -274,6 +274,15 @@ class SearchRequest(proto.Message): product search and faceted search. personalization_spec (google.cloud.retail_v2beta.types.SearchRequest.PersonalizationSpec): The specification for personalization. + + Notice that if both + [ServingConfig.personalization_spec][google.cloud.retail.v2beta.ServingConfig.personalization_spec] + and + [SearchRequest.personalization_spec][google.cloud.retail.v2beta.SearchRequest.personalization_spec] + are set. + [SearchRequest.personalization_spec][google.cloud.retail.v2beta.SearchRequest.personalization_spec] + will override + [ServingConfig.personalization_spec][google.cloud.retail.v2beta.ServingConfig.personalization_spec]. labels (Mapping[str, str]): The labels applied to a resource must meet the following requirements: @@ -1013,6 +1022,23 @@ class SearchResult(proto.Message): ``{key: "pickupInStore.store1" value { number_value: 10 }}`` means a there are 10 variants in this product are available in the store "store1". + personal_labels (Sequence[str]): + Specifies previous events related to this product for this + user based on + [UserEvent][google.cloud.retail.v2beta.UserEvent] with same + [SearchRequest.visitor_id][google.cloud.retail.v2beta.SearchRequest.visitor_id] + or + [UserInfo.user_id][google.cloud.retail.v2beta.UserInfo.user_id]. + + This is set only when + [SearchRequest.PersonalizationSpec.mode][google.cloud.retail.v2beta.SearchRequest.PersonalizationSpec.mode] + is + [SearchRequest.PersonalizationSpec.Mode.AUTO][google.cloud.retail.v2beta.SearchRequest.PersonalizationSpec.Mode.AUTO]. + + Possible values: + + - ``purchased``: Indicates that this product has been + purchased before. """ id = proto.Field( @@ -1040,6 +1066,10 @@ class SearchResult(proto.Message): number=5, message=struct_pb2.Value, ) + personal_labels = proto.RepeatedField( + proto.STRING, + number=7, + ) class Facet(proto.Message): r"""A facet result. diff --git a/google/cloud/retail_v2beta/types/serving_config.py b/google/cloud/retail_v2beta/types/serving_config.py index 86ea99fe..1ac08920 100644 --- a/google/cloud/retail_v2beta/types/serving_config.py +++ b/google/cloud/retail_v2beta/types/serving_config.py @@ -26,10 +26,8 @@ class ServingConfig(proto.Message): - r"""Configures metadata that is used to generate serving time results - (e.g. search results or recommendation predictions). The - ServingConfig is passed in the search and predict request and - together with the Catalog.default_branch, generates results. + r"""Configures metadata that is used to generate serving time + results (e.g. search results or recommendation predictions). Attributes: name (str): @@ -43,8 +41,10 @@ class ServingConfig(proto.Message): limit of 128 characters. Otherwise, an INVALID_ARGUMENT error is returned. model_id (str): - The id of the model to use at serving time. Currently only - RecommendationModels are supported: + The id of the model in the same + [Catalog][google.cloud.retail.v2beta.Catalog] to use at + serving time. Currently only RecommendationModels are + supported: https://cloud.google.com/retail/recommendations-ai/docs/create-models Can be changed but only to a compatible model (e.g. others-you-may-like CTR to others-you-may-like CVR). @@ -60,13 +60,13 @@ class ServingConfig(proto.Message): items first. This setting could result in a decrease in click-through and conversion rates. Allowed values are: - - 'no-price-reranking' - - 'low-price-raranking' - - 'medium-price-reranking' - - 'high-price-reranking' + - ``no-price-reranking`` + - ``low-price-raranking`` + - ``medium-price-reranking`` + - ``high-price-reranking`` If not specified, we choose default based on model type. - Default value: 'no-price-reranking'. + Default value: ``no-price-reranking``. Can only be set if [solution_types][google.cloud.retail.v2beta.ServingConfig.solution_types] @@ -191,30 +191,34 @@ class ServingConfig(proto.Message): [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. diversity_level (str): How much diversity to use in recommendation model results - e.g. 'medium-diversity' or 'high-diversity'. Currently + e.g. ``medium-diversity`` or ``high-diversity``. Currently supported values: - - 'no-diversity' - - 'low-diversity' - - 'medium-diversity' - - 'high-diversity' - - 'auto-diversity' + - ``no-diversity`` + - ``low-diversity`` + - ``medium-diversity`` + - ``high-diversity`` + - ``auto-diversity`` If not specified, we choose default based on recommendation - model type. Default value: 'no-diversity'. + model type. Default value: ``no-diversity``. Can only be set if [solution_types][google.cloud.retail.v2beta.ServingConfig.solution_types] 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. enable_category_filter_level (str): Whether to add additional category filters on the - 'similar-items' model. If not specified, we enable it by + ``similar-items`` model. If not specified, we enable it by default. Allowed values are: - - 'no-category-match': No additional filtering of original - results from the model and the customer's filters. - - 'relaxed-category-match': Only keep results with + - ``no-category-match``: No additional filtering of + original results from the model and the customer's + filters. + - ``relaxed-category-match``: Only keep results with categories that match at least one item categories in the PredictRequests's context item. @@ -226,6 +230,22 @@ class ServingConfig(proto.Message): [solution_types][google.cloud.retail.v2beta.ServingConfig.solution_types] is [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_RECOMMENDATION]. + personalization_spec (google.cloud.retail_v2beta.types.SearchRequest.PersonalizationSpec): + The specification for personalization spec. + + Can only be set if + [solution_types][google.cloud.retail.v2beta.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + + Notice that if both + [ServingConfig.personalization_spec][google.cloud.retail.v2beta.ServingConfig.personalization_spec] + and + [SearchRequest.personalization_spec][google.cloud.retail.v2beta.SearchRequest.personalization_spec] + are set. + [SearchRequest.personalization_spec][google.cloud.retail.v2beta.SearchRequest.personalization_spec] + will override + [ServingConfig.personalization_spec][google.cloud.retail.v2beta.ServingConfig.personalization_spec]. solution_types (Sequence[google.cloud.retail_v2beta.types.SolutionType]): Required. Immutable. Specifies the solution types that a serving config can be associated @@ -233,6 +253,14 @@ class ServingConfig(proto.Message): of solution. """ + class DiversityType(proto.Enum): + r"""What type of diversity - data or rule based. + If none is specified, default to rule based. + """ + DIVERSITY_TYPE_UNSPECIFIED = 0 + RULE_BASED_DIVERSITY = 2 + DATA_DRIVEN_DIVERSITY = 3 + name = proto.Field( proto.STRING, number=1, @@ -294,10 +322,20 @@ class ServingConfig(proto.Message): proto.STRING, number=8, ) + diversity_type = proto.Field( + proto.ENUM, + number=20, + enum=DiversityType, + ) enable_category_filter_level = proto.Field( proto.STRING, number=16, ) + personalization_spec = proto.Field( + proto.MESSAGE, + number=21, + message=search_service.SearchRequest.PersonalizationSpec, + ) solution_types = proto.RepeatedField( proto.ENUM, number=19, diff --git a/google/cloud/retail_v2beta/types/serving_config_service.py b/google/cloud/retail_v2beta/types/serving_config_service.py index 638ad3bb..817201be 100644 --- a/google/cloud/retail_v2beta/types/serving_config_service.py +++ b/google/cloud/retail_v2beta/types/serving_config_service.py @@ -101,7 +101,7 @@ class DeleteServingConfigRequest(proto.Message): name (str): Required. The resource name of the ServingConfig to delete. Format: - projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id} + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` """ name = proto.Field( @@ -117,7 +117,7 @@ class GetServingConfigRequest(proto.Message): name (str): Required. The resource name of the ServingConfig to get. Format: - projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id} + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` """ name = proto.Field( @@ -132,7 +132,7 @@ class ListServingConfigsRequest(proto.Message): Attributes: parent (str): Required. The catalog resource name. Format: - projects/{project_number}/locations/{location_id}/catalogs/{catalog_id} + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` page_size (int): Optional. Maximum number of results to return. If unspecified, defaults to 100. If a @@ -190,7 +190,7 @@ class AddControlRequest(proto.Message): Attributes: serving_config (str): Required. The source ServingConfig resource name . Format: - projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id} + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` control_id (str): Required. The id of the control to apply. Assumed to be in the same catalog as the serving config - if id is not found @@ -213,7 +213,7 @@ class RemoveControlRequest(proto.Message): Attributes: serving_config (str): Required. The source ServingConfig resource name . Format: - projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id} + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` control_id (str): Required. The id of the control to apply. Assumed to be in the same catalog as the serving diff --git a/google/cloud/retail_v2beta/types/user_event.py b/google/cloud/retail_v2beta/types/user_event.py index 4445a26e..fa2d348f 100644 --- a/google/cloud/retail_v2beta/types/user_event.py +++ b/google/cloud/retail_v2beta/types/user_event.py @@ -245,7 +245,7 @@ class UserEvent(proto.Message): To represent full path of category, use '>' sign to separate different hierarchies. If '>' is part of the category name, - please replace it with other character(s). + replace it with other character(s). Category pages include special pages such as sales or promotions. For instance, a special sale page may have the diff --git a/google/cloud/retail_v2beta/types/user_event_service.py b/google/cloud/retail_v2beta/types/user_event_service.py index 24fa684b..c84110b2 100644 --- a/google/cloud/retail_v2beta/types/user_event_service.py +++ b/google/cloud/retail_v2beta/types/user_event_service.py @@ -103,18 +103,18 @@ class RejoinUserEventsRequest(proto.Message): The type of the user event rejoin to define the scope and range of the user events to be rejoined with the latest product catalog. Defaults to - USER_EVENT_REJOIN_SCOPE_UNSPECIFIED if this field is not + ``USER_EVENT_REJOIN_SCOPE_UNSPECIFIED`` if this field is not set, or set to an invalid integer value. """ class UserEventRejoinScope(proto.Enum): r"""The scope of user events to be rejoined with the latest product catalog. If the rejoining aims at reducing number of unjoined - events, set UserEventRejoinScope to UNJOINED_EVENTS. If the + events, set ``UserEventRejoinScope`` to ``UNJOINED_EVENTS``. If the rejoining aims at correcting product catalog information in joined - events, set UserEventRejoinScope to JOINED_EVENTS. If all events - needs to be rejoined, set UserEventRejoinScope to - USER_EVENT_REJOIN_SCOPE_UNSPECIFIED. + events, set ``UserEventRejoinScope`` to ``JOINED_EVENTS``. If all + events needs to be rejoined, set ``UserEventRejoinScope`` to + ``USER_EVENT_REJOIN_SCOPE_UNSPECIFIED``. """ USER_EVENT_REJOIN_SCOPE_UNSPECIFIED = 0 JOINED_EVENTS = 1 @@ -132,7 +132,7 @@ class UserEventRejoinScope(proto.Enum): class RejoinUserEventsResponse(proto.Message): - r"""Response message for RejoinUserEvents method. + r"""Response message for ``RejoinUserEvents`` method. Attributes: rejoined_user_events_count (int): @@ -147,7 +147,7 @@ class RejoinUserEventsResponse(proto.Message): class RejoinUserEventsMetadata(proto.Message): - r"""Metadata for RejoinUserEvents method.""" + r"""Metadata for ``RejoinUserEvents`` method.""" __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/samples/generated_samples/retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_async.py b/samples/generated_samples/retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_async.py new file mode 100644 index 00000000..d1e8bf3b --- /dev/null +++ b/samples/generated_samples/retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_async.py @@ -0,0 +1,46 @@ +# -*- 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 BatchRemoveCatalogAttributes +# 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_CatalogService_BatchRemoveCatalogAttributes_async] +from google.cloud import retail_v2beta + + +async def sample_batch_remove_catalog_attributes(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.BatchRemoveCatalogAttributesRequest( + attributes_config="attributes_config_value", + attribute_keys=['attribute_keys_value_1', 'attribute_keys_value_2'], + ) + + # Make the request + response = await client.batch_remove_catalog_attributes(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_BatchRemoveCatalogAttributes_async] diff --git a/samples/generated_samples/retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_sync.py b/samples/generated_samples/retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_sync.py new file mode 100644 index 00000000..38d5cfde --- /dev/null +++ b/samples/generated_samples/retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_sync.py @@ -0,0 +1,46 @@ +# -*- 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 BatchRemoveCatalogAttributes +# 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_CatalogService_BatchRemoveCatalogAttributes_sync] +from google.cloud import retail_v2beta + + +def sample_batch_remove_catalog_attributes(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.BatchRemoveCatalogAttributesRequest( + attributes_config="attributes_config_value", + attribute_keys=['attribute_keys_value_1', 'attribute_keys_value_2'], + ) + + # Make the request + response = client.batch_remove_catalog_attributes(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_BatchRemoveCatalogAttributes_sync] diff --git a/samples/generated_samples/retail_v2beta_generated_model_service_create_model_async.py b/samples/generated_samples/retail_v2beta_generated_model_service_create_model_async.py new file mode 100644 index 00000000..82d3752a --- /dev/null +++ b/samples/generated_samples/retail_v2beta_generated_model_service_create_model_async.py @@ -0,0 +1,55 @@ +# -*- 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_v2beta_generated_ModelService_CreateModel_async] +from google.cloud import retail_v2beta + + +async def sample_create_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + model = retail_v2beta.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2beta.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_v2beta_generated_ModelService_CreateModel_async] diff --git a/samples/generated_samples/retail_v2beta_generated_model_service_create_model_sync.py b/samples/generated_samples/retail_v2beta_generated_model_service_create_model_sync.py new file mode 100644 index 00000000..188c9ca3 --- /dev/null +++ b/samples/generated_samples/retail_v2beta_generated_model_service_create_model_sync.py @@ -0,0 +1,55 @@ +# -*- 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_v2beta_generated_ModelService_CreateModel_sync] +from google.cloud import retail_v2beta + + +def sample_create_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + model = retail_v2beta.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2beta.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_v2beta_generated_ModelService_CreateModel_sync] diff --git a/samples/generated_samples/retail_v2beta_generated_model_service_delete_model_async.py b/samples/generated_samples/retail_v2beta_generated_model_service_delete_model_async.py new file mode 100644 index 00000000..2d007314 --- /dev/null +++ b/samples/generated_samples/retail_v2beta_generated_model_service_delete_model_async.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. +# +# 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_v2beta_generated_ModelService_DeleteModel_async] +from google.cloud import retail_v2beta + + +async def sample_delete_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.DeleteModelRequest( + name="name_value", + ) + + # Make the request + await client.delete_model(request=request) + + +# [END retail_v2beta_generated_ModelService_DeleteModel_async] diff --git a/samples/generated_samples/retail_v2beta_generated_model_service_delete_model_sync.py b/samples/generated_samples/retail_v2beta_generated_model_service_delete_model_sync.py new file mode 100644 index 00000000..a54498ed --- /dev/null +++ b/samples/generated_samples/retail_v2beta_generated_model_service_delete_model_sync.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. +# +# 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_v2beta_generated_ModelService_DeleteModel_sync] +from google.cloud import retail_v2beta + + +def sample_delete_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.DeleteModelRequest( + name="name_value", + ) + + # Make the request + client.delete_model(request=request) + + +# [END retail_v2beta_generated_ModelService_DeleteModel_sync] diff --git a/samples/generated_samples/retail_v2beta_generated_model_service_list_models_async.py b/samples/generated_samples/retail_v2beta_generated_model_service_list_models_async.py new file mode 100644 index 00000000..7cd92dc3 --- /dev/null +++ b/samples/generated_samples/retail_v2beta_generated_model_service_list_models_async.py @@ -0,0 +1,46 @@ +# -*- 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_v2beta_generated_ModelService_ListModels_async] +from google.cloud import retail_v2beta + + +async def sample_list_models(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.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_v2beta_generated_ModelService_ListModels_async] diff --git a/samples/generated_samples/retail_v2beta_generated_model_service_list_models_sync.py b/samples/generated_samples/retail_v2beta_generated_model_service_list_models_sync.py new file mode 100644 index 00000000..ea3e610b --- /dev/null +++ b/samples/generated_samples/retail_v2beta_generated_model_service_list_models_sync.py @@ -0,0 +1,46 @@ +# -*- 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_v2beta_generated_ModelService_ListModels_sync] +from google.cloud import retail_v2beta + + +def sample_list_models(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.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_v2beta_generated_ModelService_ListModels_sync] diff --git a/samples/generated_samples/retail_v2beta_generated_model_service_pause_model_async.py b/samples/generated_samples/retail_v2beta_generated_model_service_pause_model_async.py new file mode 100644 index 00000000..946dcd55 --- /dev/null +++ b/samples/generated_samples/retail_v2beta_generated_model_service_pause_model_async.py @@ -0,0 +1,45 @@ +# -*- 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_v2beta_generated_ModelService_PauseModel_async] +from google.cloud import retail_v2beta + + +async def sample_pause_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.PauseModelRequest( + name="name_value", + ) + + # Make the request + response = await client.pause_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ModelService_PauseModel_async] diff --git a/samples/generated_samples/retail_v2beta_generated_model_service_pause_model_sync.py b/samples/generated_samples/retail_v2beta_generated_model_service_pause_model_sync.py new file mode 100644 index 00000000..fcbad7c4 --- /dev/null +++ b/samples/generated_samples/retail_v2beta_generated_model_service_pause_model_sync.py @@ -0,0 +1,45 @@ +# -*- 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_v2beta_generated_ModelService_PauseModel_sync] +from google.cloud import retail_v2beta + + +def sample_pause_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.PauseModelRequest( + name="name_value", + ) + + # Make the request + response = client.pause_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ModelService_PauseModel_sync] diff --git a/samples/generated_samples/retail_v2beta_generated_model_service_resume_model_async.py b/samples/generated_samples/retail_v2beta_generated_model_service_resume_model_async.py new file mode 100644 index 00000000..5976ea10 --- /dev/null +++ b/samples/generated_samples/retail_v2beta_generated_model_service_resume_model_async.py @@ -0,0 +1,45 @@ +# -*- 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_v2beta_generated_ModelService_ResumeModel_async] +from google.cloud import retail_v2beta + + +async def sample_resume_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.ResumeModelRequest( + name="name_value", + ) + + # Make the request + response = await client.resume_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ModelService_ResumeModel_async] diff --git a/samples/generated_samples/retail_v2beta_generated_model_service_resume_model_sync.py b/samples/generated_samples/retail_v2beta_generated_model_service_resume_model_sync.py new file mode 100644 index 00000000..a6d23a2d --- /dev/null +++ b/samples/generated_samples/retail_v2beta_generated_model_service_resume_model_sync.py @@ -0,0 +1,45 @@ +# -*- 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_v2beta_generated_ModelService_ResumeModel_sync] +from google.cloud import retail_v2beta + + +def sample_resume_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.ResumeModelRequest( + name="name_value", + ) + + # Make the request + response = client.resume_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ModelService_ResumeModel_sync] diff --git a/samples/generated_samples/retail_v2beta_generated_model_service_tune_model_async.py b/samples/generated_samples/retail_v2beta_generated_model_service_tune_model_async.py new file mode 100644 index 00000000..bc095369 --- /dev/null +++ b/samples/generated_samples/retail_v2beta_generated_model_service_tune_model_async.py @@ -0,0 +1,49 @@ +# -*- 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_v2beta_generated_ModelService_TuneModel_async] +from google.cloud import retail_v2beta + + +async def sample_tune_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.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_v2beta_generated_ModelService_TuneModel_async] diff --git a/samples/generated_samples/retail_v2beta_generated_model_service_tune_model_sync.py b/samples/generated_samples/retail_v2beta_generated_model_service_tune_model_sync.py new file mode 100644 index 00000000..370ffc6e --- /dev/null +++ b/samples/generated_samples/retail_v2beta_generated_model_service_tune_model_sync.py @@ -0,0 +1,49 @@ +# -*- 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_v2beta_generated_ModelService_TuneModel_sync] +from google.cloud import retail_v2beta + + +def sample_tune_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.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_v2beta_generated_ModelService_TuneModel_sync] diff --git a/samples/generated_samples/retail_v2beta_generated_model_service_update_model_async.py b/samples/generated_samples/retail_v2beta_generated_model_service_update_model_async.py new file mode 100644 index 00000000..769e7979 --- /dev/null +++ b/samples/generated_samples/retail_v2beta_generated_model_service_update_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 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_v2beta_generated_ModelService_UpdateModel_async] +from google.cloud import retail_v2beta + + +async def sample_update_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + model = retail_v2beta.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2beta.UpdateModelRequest( + model=model, + ) + + # Make the request + response = await client.update_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ModelService_UpdateModel_async] diff --git a/samples/generated_samples/retail_v2beta_generated_model_service_update_model_sync.py b/samples/generated_samples/retail_v2beta_generated_model_service_update_model_sync.py new file mode 100644 index 00000000..b8255320 --- /dev/null +++ b/samples/generated_samples/retail_v2beta_generated_model_service_update_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 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_v2beta_generated_ModelService_UpdateModel_sync] +from google.cloud import retail_v2beta + + +def sample_update_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + model = retail_v2beta.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2beta.UpdateModelRequest( + model=model, + ) + + # Make the request + response = client.update_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ModelService_UpdateModel_sync] diff --git a/samples/generated_samples/snippet_metadata_retail_v2beta.json b/samples/generated_samples/snippet_metadata_retail_v2beta.json index 591f20ca..5daba306 100644 --- a/samples/generated_samples/snippet_metadata_retail_v2beta.json +++ b/samples/generated_samples/snippet_metadata_retail_v2beta.json @@ -163,6 +163,159 @@ ], "title": "retail_v2beta_generated_catalog_service_add_catalog_attribute_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient.batch_remove_catalog_attributes", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.BatchRemoveCatalogAttributes", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "BatchRemoveCatalogAttributes" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.BatchRemoveCatalogAttributesRequest" + }, + { + "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.BatchRemoveCatalogAttributesResponse", + "shortName": "batch_remove_catalog_attributes" + }, + "description": "Sample for BatchRemoveCatalogAttributes", + "file": "retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_BatchRemoveCatalogAttributes_async", + "segments": [ + { + "end": 45, + "start": 27, + "type": "FULL" + }, + { + "end": 45, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 39, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 42, + "start": 40, + "type": "REQUEST_EXECUTION" + }, + { + "end": 46, + "start": 43, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient.batch_remove_catalog_attributes", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.BatchRemoveCatalogAttributes", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "BatchRemoveCatalogAttributes" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.BatchRemoveCatalogAttributesRequest" + }, + { + "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.BatchRemoveCatalogAttributesResponse", + "shortName": "batch_remove_catalog_attributes" + }, + "description": "Sample for BatchRemoveCatalogAttributes", + "file": "retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_BatchRemoveCatalogAttributes_sync", + "segments": [ + { + "end": 45, + "start": 27, + "type": "FULL" + }, + { + "end": 45, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 39, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 42, + "start": 40, + "type": "REQUEST_EXECUTION" + }, + { + "end": 46, + "start": 43, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_sync.py" + }, { "canonical": true, "clientMethod": { @@ -2904,6 +3057,1143 @@ ], "title": "retail_v2beta_generated_control_service_update_control_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient.create_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.CreateModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "CreateModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.CreateModelRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "model", + "type": "google.cloud.retail_v2beta.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_v2beta_generated_model_service_create_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_CreateModel_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_model_service_create_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceClient.create_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.CreateModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "CreateModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.CreateModelRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "model", + "type": "google.cloud.retail_v2beta.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_v2beta_generated_model_service_create_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_CreateModel_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_model_service_create_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient.delete_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.DeleteModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "DeleteModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.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_v2beta_generated_model_service_delete_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_DeleteModel_async", + "segments": [ + { + "end": 42, + "start": 27, + "type": "FULL" + }, + { + "end": 42, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 43, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_model_service_delete_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceClient.delete_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.DeleteModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "DeleteModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.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_v2beta_generated_model_service_delete_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_DeleteModel_sync", + "segments": [ + { + "end": 42, + "start": 27, + "type": "FULL" + }, + { + "end": 42, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 43, + "type": "RESPONSE_HANDLING" + } + ], + "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.list_models", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.ListModels", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "ListModels" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.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_v2beta.services.model_service.pagers.ListModelsAsyncPager", + "shortName": "list_models" + }, + "description": "Sample for ListModels", + "file": "retail_v2beta_generated_model_service_list_models_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_ListModels_async", + "segments": [ + { + "end": 45, + "start": 27, + "type": "FULL" + }, + { + "end": 45, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 46, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_model_service_list_models_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceClient.list_models", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.ListModels", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "ListModels" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.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_v2beta.services.model_service.pagers.ListModelsPager", + "shortName": "list_models" + }, + "description": "Sample for ListModels", + "file": "retail_v2beta_generated_model_service_list_models_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_ListModels_sync", + "segments": [ + { + "end": 45, + "start": 27, + "type": "FULL" + }, + { + "end": 45, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 46, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_model_service_list_models_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient.pause_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.PauseModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "PauseModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.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_v2beta.types.Model", + "shortName": "pause_model" + }, + "description": "Sample for PauseModel", + "file": "retail_v2beta_generated_model_service_pause_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_PauseModel_async", + "segments": [ + { + "end": 44, + "start": 27, + "type": "FULL" + }, + { + "end": 44, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 45, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_model_service_pause_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceClient.pause_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.PauseModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "PauseModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.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_v2beta.types.Model", + "shortName": "pause_model" + }, + "description": "Sample for PauseModel", + "file": "retail_v2beta_generated_model_service_pause_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_PauseModel_sync", + "segments": [ + { + "end": 44, + "start": 27, + "type": "FULL" + }, + { + "end": 44, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 45, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_model_service_pause_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient.resume_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.ResumeModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "ResumeModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.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_v2beta.types.Model", + "shortName": "resume_model" + }, + "description": "Sample for ResumeModel", + "file": "retail_v2beta_generated_model_service_resume_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_ResumeModel_async", + "segments": [ + { + "end": 44, + "start": 27, + "type": "FULL" + }, + { + "end": 44, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 45, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_model_service_resume_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceClient.resume_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.ResumeModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "ResumeModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.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_v2beta.types.Model", + "shortName": "resume_model" + }, + "description": "Sample for ResumeModel", + "file": "retail_v2beta_generated_model_service_resume_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_ResumeModel_sync", + "segments": [ + { + "end": 44, + "start": 27, + "type": "FULL" + }, + { + "end": 44, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 45, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_model_service_resume_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient.tune_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.TuneModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "TuneModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.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_v2beta_generated_model_service_tune_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_TuneModel_async", + "segments": [ + { + "end": 48, + "start": 27, + "type": "FULL" + }, + { + "end": 48, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 45, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 49, + "start": 46, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_model_service_tune_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceClient.tune_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.TuneModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "TuneModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.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_v2beta_generated_model_service_tune_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_TuneModel_sync", + "segments": [ + { + "end": 48, + "start": 27, + "type": "FULL" + }, + { + "end": 48, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 45, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 49, + "start": 46, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_model_service_tune_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient.update_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.UpdateModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "UpdateModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.UpdateModelRequest" + }, + { + "name": "model", + "type": "google.cloud.retail_v2beta.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_v2beta.types.Model", + "shortName": "update_model" + }, + "description": "Sample for UpdateModel", + "file": "retail_v2beta_generated_model_service_update_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_UpdateModel_async", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 43, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 46, + "start": 44, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "start": 47, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_model_service_update_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceClient.update_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.UpdateModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "UpdateModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.UpdateModelRequest" + }, + { + "name": "model", + "type": "google.cloud.retail_v2beta.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_v2beta.types.Model", + "shortName": "update_model" + }, + "description": "Sample for UpdateModel", + "file": "retail_v2beta_generated_model_service_update_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_UpdateModel_sync", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 43, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 46, + "start": 44, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "start": 47, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_model_service_update_model_sync.py" + }, { "canonical": true, "clientMethod": { diff --git a/scripts/fixup_retail_v2beta_keywords.py b/scripts/fixup_retail_v2beta_keywords.py index 9e4ba4f4..9b128c2f 100644 --- a/scripts/fixup_retail_v2beta_keywords.py +++ b/scripts/fixup_retail_v2beta_keywords.py @@ -43,12 +43,15 @@ class retailCallTransformer(cst.CSTTransformer): 'add_control': ('serving_config', 'control_id', ), 'add_fulfillment_places': ('product', 'type_', 'place_ids', 'add_time', 'allow_missing', ), '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', 'uri', 'ets', ), 'complete_query': ('catalog', 'query', 'visitor_id', 'language_codes', 'device_type', 'dataset', 'max_suggestions', ), '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', ), @@ -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', ), + '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', ), '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', ), diff --git a/tests/unit/gapic/retail_v2beta/test_catalog_service.py b/tests/unit/gapic/retail_v2beta/test_catalog_service.py index 216eebf6..9d3e53e1 100644 --- a/tests/unit/gapic/retail_v2beta/test_catalog_service.py +++ b/tests/unit/gapic/retail_v2beta/test_catalog_service.py @@ -3294,6 +3294,171 @@ async def test_remove_catalog_attribute_field_headers_async(): ) in kw["metadata"] +@pytest.mark.parametrize( + "request_type", + [ + catalog_service.BatchRemoveCatalogAttributesRequest, + dict, + ], +) +def test_batch_remove_catalog_attributes(request_type, transport: str = "grpc"): + client = CatalogServiceClient( + 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.batch_remove_catalog_attributes), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.BatchRemoveCatalogAttributesResponse( + deleted_catalog_attributes=["deleted_catalog_attributes_value"], + reset_catalog_attributes=["reset_catalog_attributes_value"], + ) + response = client.batch_remove_catalog_attributes(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.BatchRemoveCatalogAttributesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog_service.BatchRemoveCatalogAttributesResponse) + assert response.deleted_catalog_attributes == ["deleted_catalog_attributes_value"] + assert response.reset_catalog_attributes == ["reset_catalog_attributes_value"] + + +def test_batch_remove_catalog_attributes_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 = CatalogServiceClient( + 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.batch_remove_catalog_attributes), "__call__" + ) as call: + client.batch_remove_catalog_attributes() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.BatchRemoveCatalogAttributesRequest() + + +@pytest.mark.asyncio +async def test_batch_remove_catalog_attributes_async( + transport: str = "grpc_asyncio", + request_type=catalog_service.BatchRemoveCatalogAttributesRequest, +): + client = CatalogServiceAsyncClient( + 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.batch_remove_catalog_attributes), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + catalog_service.BatchRemoveCatalogAttributesResponse( + deleted_catalog_attributes=["deleted_catalog_attributes_value"], + reset_catalog_attributes=["reset_catalog_attributes_value"], + ) + ) + response = await client.batch_remove_catalog_attributes(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.BatchRemoveCatalogAttributesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog_service.BatchRemoveCatalogAttributesResponse) + assert response.deleted_catalog_attributes == ["deleted_catalog_attributes_value"] + assert response.reset_catalog_attributes == ["reset_catalog_attributes_value"] + + +@pytest.mark.asyncio +async def test_batch_remove_catalog_attributes_async_from_dict(): + await test_batch_remove_catalog_attributes_async(request_type=dict) + + +def test_batch_remove_catalog_attributes_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.BatchRemoveCatalogAttributesRequest() + + request.attributes_config = "attributes_config_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_remove_catalog_attributes), "__call__" + ) as call: + call.return_value = catalog_service.BatchRemoveCatalogAttributesResponse() + client.batch_remove_catalog_attributes(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", + "attributes_config=attributes_config_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_batch_remove_catalog_attributes_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.BatchRemoveCatalogAttributesRequest() + + request.attributes_config = "attributes_config_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_remove_catalog_attributes), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + catalog_service.BatchRemoveCatalogAttributesResponse() + ) + await client.batch_remove_catalog_attributes(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", + "attributes_config=attributes_config_value", + ) in kw["metadata"] + + @pytest.mark.parametrize( "request_type", [ @@ -3612,6 +3777,7 @@ def test_catalog_service_base_transport(): "update_attributes_config", "add_catalog_attribute", "remove_catalog_attribute", + "batch_remove_catalog_attributes", "replace_catalog_attribute", ) for method in methods: diff --git a/tests/unit/gapic/retail_v2beta/test_control_service.py b/tests/unit/gapic/retail_v2beta/test_control_service.py index 38a5a4b5..23d4fcbd 100644 --- a/tests/unit/gapic/retail_v2beta/test_control_service.py +++ b/tests/unit/gapic/retail_v2beta/test_control_service.py @@ -709,6 +709,9 @@ def test_create_control(request_type, transport: str = "grpc"): display_name="display_name_value", associated_serving_config_ids=["associated_serving_config_ids_value"], solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[ + common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH + ], facet_spec=search_service.SearchRequest.FacetSpec( facet_key=search_service.SearchRequest.FacetSpec.FacetKey( key="key_value" @@ -730,6 +733,9 @@ def test_create_control(request_type, transport: str = "grpc"): "associated_serving_config_ids_value" ] assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [ + common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH + ] def test_create_control_empty_call(): @@ -770,6 +776,9 @@ async def test_create_control_async( display_name="display_name_value", associated_serving_config_ids=["associated_serving_config_ids_value"], solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[ + common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH + ], ) ) response = await client.create_control(request) @@ -787,6 +796,9 @@ async def test_create_control_async( "associated_serving_config_ids_value" ] assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [ + common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH + ] @pytest.mark.asyncio @@ -1234,6 +1246,9 @@ def test_update_control(request_type, transport: str = "grpc"): display_name="display_name_value", associated_serving_config_ids=["associated_serving_config_ids_value"], solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[ + common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH + ], facet_spec=search_service.SearchRequest.FacetSpec( facet_key=search_service.SearchRequest.FacetSpec.FacetKey( key="key_value" @@ -1255,6 +1270,9 @@ def test_update_control(request_type, transport: str = "grpc"): "associated_serving_config_ids_value" ] assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [ + common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH + ] def test_update_control_empty_call(): @@ -1295,6 +1313,9 @@ async def test_update_control_async( display_name="display_name_value", associated_serving_config_ids=["associated_serving_config_ids_value"], solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[ + common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH + ], ) ) response = await client.update_control(request) @@ -1312,6 +1333,9 @@ async def test_update_control_async( "associated_serving_config_ids_value" ] assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [ + common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH + ] @pytest.mark.asyncio @@ -1529,6 +1553,9 @@ def test_get_control(request_type, transport: str = "grpc"): display_name="display_name_value", associated_serving_config_ids=["associated_serving_config_ids_value"], solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[ + common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH + ], facet_spec=search_service.SearchRequest.FacetSpec( facet_key=search_service.SearchRequest.FacetSpec.FacetKey( key="key_value" @@ -1550,6 +1577,9 @@ def test_get_control(request_type, transport: str = "grpc"): "associated_serving_config_ids_value" ] assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [ + common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH + ] def test_get_control_empty_call(): @@ -1590,6 +1620,9 @@ async def test_get_control_async( display_name="display_name_value", associated_serving_config_ids=["associated_serving_config_ids_value"], solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[ + common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH + ], ) ) response = await client.get_control(request) @@ -1607,6 +1640,9 @@ async def test_get_control_async( "associated_serving_config_ids_value" ] assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [ + common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH + ] @pytest.mark.asyncio diff --git a/tests/unit/gapic/retail_v2beta/test_model_service.py b/tests/unit/gapic/retail_v2beta/test_model_service.py new file mode 100644 index 00000000..1d0db485 --- /dev/null +++ b/tests/unit/gapic/retail_v2beta/test_model_service.py @@ -0,0 +1,3397 @@ +# -*- 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 +except ImportError: + import mock + +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.longrunning import operations_pb2 +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +import grpc +from grpc.experimental import aio +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest + +from google.cloud.retail_v2beta.services.model_service import ( + ModelServiceAsyncClient, + ModelServiceClient, + pagers, + transports, +) +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import model +from google.cloud.retail_v2beta.types import model as gcr_model +from google.cloud.retail_v2beta.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"), + ], +) +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") + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.ModelServiceGrpcTransport, "grpc"), + (transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio"), + ], +) +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"), + ], +) +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") + + +def test_model_service_client_get_transport_class(): + transport = ModelServiceClient.get_transport_class() + available_transports = [ + transports.ModelServiceGrpcTransport, + ] + 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", + ), + ], +) +@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", + ), + ], +) +@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", + ), + ], +) +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, + ), + ], +) +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_v2beta.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.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", + ) + + +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, + ], +) +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", + ], +) +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_v2beta.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", + "pause_model", + "resume_model", + "delete_model", + "list_models", + "update_model", + "tune_model", + ) + 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_v2beta.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_v2beta.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, + ], +) +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 + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + ], +) +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") + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + ], +) +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") + + +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_transport_close(): + transports = { + "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 = [ + "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/tests/unit/gapic/retail_v2beta/test_serving_config_service.py b/tests/unit/gapic/retail_v2beta/test_serving_config_service.py index f2d68dbe..9a28b9f6 100644 --- a/tests/unit/gapic/retail_v2beta/test_serving_config_service.py +++ b/tests/unit/gapic/retail_v2beta/test_serving_config_service.py @@ -743,6 +743,7 @@ def test_create_serving_config(request_type, transport: str = "grpc"): replacement_control_ids=["replacement_control_ids_value"], ignore_control_ids=["ignore_control_ids_value"], diversity_level="diversity_level_value", + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, enable_category_filter_level="enable_category_filter_level_value", solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], ) @@ -771,6 +772,10 @@ def test_create_serving_config(request_type, transport: str = "grpc"): assert response.replacement_control_ids == ["replacement_control_ids_value"] assert response.ignore_control_ids == ["ignore_control_ids_value"] assert response.diversity_level == "diversity_level_value" + assert ( + response.diversity_type + == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + ) assert response.enable_category_filter_level == "enable_category_filter_level_value" assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] @@ -828,6 +833,7 @@ async def test_create_serving_config_async( replacement_control_ids=["replacement_control_ids_value"], ignore_control_ids=["ignore_control_ids_value"], diversity_level="diversity_level_value", + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, enable_category_filter_level="enable_category_filter_level_value", solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], ) @@ -857,6 +863,10 @@ async def test_create_serving_config_async( assert response.replacement_control_ids == ["replacement_control_ids_value"] assert response.ignore_control_ids == ["ignore_control_ids_value"] assert response.diversity_level == "diversity_level_value" + assert ( + response.diversity_type + == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + ) assert response.enable_category_filter_level == "enable_category_filter_level_value" assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] @@ -1309,6 +1319,7 @@ def test_update_serving_config(request_type, transport: str = "grpc"): replacement_control_ids=["replacement_control_ids_value"], ignore_control_ids=["ignore_control_ids_value"], diversity_level="diversity_level_value", + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, enable_category_filter_level="enable_category_filter_level_value", solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], ) @@ -1337,6 +1348,10 @@ def test_update_serving_config(request_type, transport: str = "grpc"): assert response.replacement_control_ids == ["replacement_control_ids_value"] assert response.ignore_control_ids == ["ignore_control_ids_value"] assert response.diversity_level == "diversity_level_value" + assert ( + response.diversity_type + == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + ) assert response.enable_category_filter_level == "enable_category_filter_level_value" assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] @@ -1394,6 +1409,7 @@ async def test_update_serving_config_async( replacement_control_ids=["replacement_control_ids_value"], ignore_control_ids=["ignore_control_ids_value"], diversity_level="diversity_level_value", + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, enable_category_filter_level="enable_category_filter_level_value", solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], ) @@ -1423,6 +1439,10 @@ async def test_update_serving_config_async( assert response.replacement_control_ids == ["replacement_control_ids_value"] assert response.ignore_control_ids == ["ignore_control_ids_value"] assert response.diversity_level == "diversity_level_value" + assert ( + response.diversity_type + == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + ) assert response.enable_category_filter_level == "enable_category_filter_level_value" assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] @@ -1630,6 +1650,7 @@ def test_get_serving_config(request_type, transport: str = "grpc"): replacement_control_ids=["replacement_control_ids_value"], ignore_control_ids=["ignore_control_ids_value"], diversity_level="diversity_level_value", + diversity_type=serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, enable_category_filter_level="enable_category_filter_level_value", solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], ) @@ -1658,6 +1679,10 @@ def test_get_serving_config(request_type, transport: str = "grpc"): assert response.replacement_control_ids == ["replacement_control_ids_value"] assert response.ignore_control_ids == ["ignore_control_ids_value"] assert response.diversity_level == "diversity_level_value" + assert ( + response.diversity_type + == serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + ) assert response.enable_category_filter_level == "enable_category_filter_level_value" assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] @@ -1715,6 +1740,7 @@ async def test_get_serving_config_async( replacement_control_ids=["replacement_control_ids_value"], ignore_control_ids=["ignore_control_ids_value"], diversity_level="diversity_level_value", + diversity_type=serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, enable_category_filter_level="enable_category_filter_level_value", solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], ) @@ -1744,6 +1770,10 @@ async def test_get_serving_config_async( assert response.replacement_control_ids == ["replacement_control_ids_value"] assert response.ignore_control_ids == ["ignore_control_ids_value"] assert response.diversity_level == "diversity_level_value" + assert ( + response.diversity_type + == serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + ) assert response.enable_category_filter_level == "enable_category_filter_level_value" assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] @@ -2382,6 +2412,7 @@ def test_add_control(request_type, transport: str = "grpc"): replacement_control_ids=["replacement_control_ids_value"], ignore_control_ids=["ignore_control_ids_value"], diversity_level="diversity_level_value", + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, enable_category_filter_level="enable_category_filter_level_value", solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], ) @@ -2410,6 +2441,10 @@ def test_add_control(request_type, transport: str = "grpc"): assert response.replacement_control_ids == ["replacement_control_ids_value"] assert response.ignore_control_ids == ["ignore_control_ids_value"] assert response.diversity_level == "diversity_level_value" + assert ( + response.diversity_type + == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + ) assert response.enable_category_filter_level == "enable_category_filter_level_value" assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] @@ -2463,6 +2498,7 @@ async def test_add_control_async( replacement_control_ids=["replacement_control_ids_value"], ignore_control_ids=["ignore_control_ids_value"], diversity_level="diversity_level_value", + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, enable_category_filter_level="enable_category_filter_level_value", solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], ) @@ -2492,6 +2528,10 @@ async def test_add_control_async( assert response.replacement_control_ids == ["replacement_control_ids_value"] assert response.ignore_control_ids == ["ignore_control_ids_value"] assert response.diversity_level == "diversity_level_value" + assert ( + response.diversity_type + == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + ) assert response.enable_category_filter_level == "enable_category_filter_level_value" assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] @@ -2679,6 +2719,7 @@ def test_remove_control(request_type, transport: str = "grpc"): replacement_control_ids=["replacement_control_ids_value"], ignore_control_ids=["ignore_control_ids_value"], diversity_level="diversity_level_value", + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, enable_category_filter_level="enable_category_filter_level_value", solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], ) @@ -2707,6 +2748,10 @@ def test_remove_control(request_type, transport: str = "grpc"): assert response.replacement_control_ids == ["replacement_control_ids_value"] assert response.ignore_control_ids == ["ignore_control_ids_value"] assert response.diversity_level == "diversity_level_value" + assert ( + response.diversity_type + == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + ) assert response.enable_category_filter_level == "enable_category_filter_level_value" assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] @@ -2760,6 +2805,7 @@ async def test_remove_control_async( replacement_control_ids=["replacement_control_ids_value"], ignore_control_ids=["ignore_control_ids_value"], diversity_level="diversity_level_value", + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, enable_category_filter_level="enable_category_filter_level_value", solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], ) @@ -2789,6 +2835,10 @@ async def test_remove_control_async( assert response.replacement_control_ids == ["replacement_control_ids_value"] assert response.ignore_control_ids == ["ignore_control_ids_value"] assert response.diversity_level == "diversity_level_value" + assert ( + response.diversity_type + == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + ) assert response.enable_category_filter_level == "enable_category_filter_level_value" assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION]