diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index 44c78f7c..87dd0061 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -13,4 +13,4 @@ # limitations under the License. docker: image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest - digest: sha256:4e1991042fe54b991db9ca17c8fb386e61b22fe4d1472a568bf0fcac85dcf5d3 + digest: sha256:7cffbc10910c3ab1b852c05114a08d374c195a81cdec1d4a67a1d129331d0bfe diff --git a/.github/release-please.yml b/.github/release-please.yml index 466597e5..6def37a8 100644 --- a/.github/release-please.yml +++ b/.github/release-please.yml @@ -1,2 +1,8 @@ releaseType: python handleGHRelease: true +# NOTE: this section is generated by synthtool.languages.python +# See https://github.com/googleapis/synthtool/blob/master/synthtool/languages/python.py +branches: +- branch: v0 + handleGHRelease: true + releaseType: python diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml new file mode 100644 index 00000000..365ed69a --- /dev/null +++ b/.github/sync-repo-settings.yaml @@ -0,0 +1,36 @@ +# https://github.com/googleapis/repo-automation-bots/tree/main/packages/sync-repo-settings +# Rules for main branch protection +branchProtectionRules: +# Identifies the protection rule pattern. Name of the branch to be protected. +# Defaults to `main` +- pattern: main + requiresCodeOwnerReviews: true + requiresStrictStatusChecks: true + requiredStatusCheckContexts: + - 'docs' + - 'docfx' + - 'lint' + - 'unit (3.6)' + - 'unit (3.7)' + - 'unit (3.8)' + - 'unit (3.9)' + - 'unit (3.10)' + - 'cover' + - 'cla/google' + - 'OwlBot Post Processor' + - 'Samples - Lint' + - 'Samples - Python 3.7' + - 'Samples - Python 3.8' + - 'Samples - Python 3.9' + - 'Samples - Python 3.10' +permissionRules: + - team: actools-python + permission: admin + - team: actools + permission: admin + - team: yoshi-python + permission: push + - team: python-samples-owners + permission: push + - team: python-samples-reviewers + permission: push diff --git a/CHANGELOG.md b/CHANGELOG.md index d2f421b9..2d333291 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## [1.5.0](https://github.com/googleapis/python-retail/compare/v1.4.1...v1.5.0) (2022-03-30) + + +### Features + +* add new AddLocalInventories and RemoveLocalInventories APIs ([8d61976](https://github.com/googleapis/python-retail/commit/8d619760c771750d55de09fd32deb7e05bf75c8c)) +* allow search users to skip validation for invalid boost specs ([8d61976](https://github.com/googleapis/python-retail/commit/8d619760c771750d55de09fd32deb7e05bf75c8c)) +* search returns applied control ids in the response ([8d61976](https://github.com/googleapis/python-retail/commit/8d619760c771750d55de09fd32deb7e05bf75c8c)) +* support search personalization ([8d61976](https://github.com/googleapis/python-retail/commit/8d619760c771750d55de09fd32deb7e05bf75c8c)) +* users cannot switch to empty default branch unless force override ([8d61976](https://github.com/googleapis/python-retail/commit/8d619760c771750d55de09fd32deb7e05bf75c8c)) + + +### Documentation + +* deprecate request_id in ImportProductsRequest ([8d61976](https://github.com/googleapis/python-retail/commit/8d619760c771750d55de09fd32deb7e05bf75c8c)) +* deprecate search dynamic_facet_spec and suggest to config on cloud console ([8d61976](https://github.com/googleapis/python-retail/commit/8d619760c771750d55de09fd32deb7e05bf75c8c)) +* keep the API doc up-to-date with recent changes ([8d61976](https://github.com/googleapis/python-retail/commit/8d619760c771750d55de09fd32deb7e05bf75c8c)) +* suggest search users not to send IP and use hashed user id ([8d61976](https://github.com/googleapis/python-retail/commit/8d619760c771750d55de09fd32deb7e05bf75c8c)) +* users can self enroll retail search feature on cloud console ([8d61976](https://github.com/googleapis/python-retail/commit/8d619760c771750d55de09fd32deb7e05bf75c8c)) + ### [1.4.1](https://github.com/googleapis/python-retail/compare/v1.4.0...v1.4.1) (2022-03-05) diff --git a/docs/conf.py b/docs/conf.py index 329c7706..415d98ad 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -314,7 +314,13 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - (root_doc, "google-cloud-retail", "google-cloud-retail Documentation", [author], 1,) + ( + root_doc, + "google-cloud-retail", + "google-cloud-retail Documentation", + [author], + 1, + ) ] # If true, show URL addresses after external links. @@ -355,7 +361,10 @@ intersphinx_mapping = { "python": ("https://python.readthedocs.org/en/latest/", None), "google-auth": ("https://googleapis.dev/python/google-auth/latest/", None), - "google.api_core": ("https://googleapis.dev/python/google-api-core/latest/", None,), + "google.api_core": ( + "https://googleapis.dev/python/google-api-core/latest/", + None, + ), "grpc": ("https://grpc.github.io/grpc/python/", None), "proto-plus": ("https://proto-plus-python.readthedocs.io/en/latest/", None), "protobuf": ("https://googleapis.dev/python/protobuf/latest/", None), diff --git a/google/cloud/retail/__init__.py b/google/cloud/retail/__init__.py index b031326e..4314c370 100644 --- a/google/cloud/retail/__init__.py +++ b/google/cloud/retail/__init__.py @@ -59,8 +59,8 @@ from google.cloud.retail_v2.types.common import FulfillmentInfo from google.cloud.retail_v2.types.common import Image from google.cloud.retail_v2.types.common import Interval +from google.cloud.retail_v2.types.common import LocalInventory from google.cloud.retail_v2.types.common import PriceInfo -from google.cloud.retail_v2.types.common import Promotion from google.cloud.retail_v2.types.common import Rating from google.cloud.retail_v2.types.common import UserInfo from google.cloud.retail_v2.types.completion_service import CompleteQueryRequest @@ -87,6 +87,9 @@ from google.cloud.retail_v2.types.product_service import AddFulfillmentPlacesMetadata from google.cloud.retail_v2.types.product_service import AddFulfillmentPlacesRequest from google.cloud.retail_v2.types.product_service import AddFulfillmentPlacesResponse +from google.cloud.retail_v2.types.product_service import AddLocalInventoriesMetadata +from google.cloud.retail_v2.types.product_service import AddLocalInventoriesRequest +from google.cloud.retail_v2.types.product_service import AddLocalInventoriesResponse from google.cloud.retail_v2.types.product_service import CreateProductRequest from google.cloud.retail_v2.types.product_service import DeleteProductRequest from google.cloud.retail_v2.types.product_service import GetProductRequest @@ -95,10 +98,14 @@ from google.cloud.retail_v2.types.product_service import RemoveFulfillmentPlacesMetadata from google.cloud.retail_v2.types.product_service import RemoveFulfillmentPlacesRequest from google.cloud.retail_v2.types.product_service import RemoveFulfillmentPlacesResponse +from google.cloud.retail_v2.types.product_service import RemoveLocalInventoriesMetadata +from google.cloud.retail_v2.types.product_service import RemoveLocalInventoriesRequest +from google.cloud.retail_v2.types.product_service import RemoveLocalInventoriesResponse from google.cloud.retail_v2.types.product_service import SetInventoryMetadata from google.cloud.retail_v2.types.product_service import SetInventoryRequest from google.cloud.retail_v2.types.product_service import SetInventoryResponse from google.cloud.retail_v2.types.product_service import UpdateProductRequest +from google.cloud.retail_v2.types.promotion import Promotion from google.cloud.retail_v2.types.purge_config import PurgeMetadata from google.cloud.retail_v2.types.purge_config import PurgeUserEventsRequest from google.cloud.retail_v2.types.purge_config import PurgeUserEventsResponse @@ -141,8 +148,8 @@ "FulfillmentInfo", "Image", "Interval", + "LocalInventory", "PriceInfo", - "Promotion", "Rating", "UserInfo", "CompleteQueryRequest", @@ -169,6 +176,9 @@ "AddFulfillmentPlacesMetadata", "AddFulfillmentPlacesRequest", "AddFulfillmentPlacesResponse", + "AddLocalInventoriesMetadata", + "AddLocalInventoriesRequest", + "AddLocalInventoriesResponse", "CreateProductRequest", "DeleteProductRequest", "GetProductRequest", @@ -177,10 +187,14 @@ "RemoveFulfillmentPlacesMetadata", "RemoveFulfillmentPlacesRequest", "RemoveFulfillmentPlacesResponse", + "RemoveLocalInventoriesMetadata", + "RemoveLocalInventoriesRequest", + "RemoveLocalInventoriesResponse", "SetInventoryMetadata", "SetInventoryRequest", "SetInventoryResponse", "UpdateProductRequest", + "Promotion", "PurgeMetadata", "PurgeUserEventsRequest", "PurgeUserEventsResponse", diff --git a/google/cloud/retail_v2/__init__.py b/google/cloud/retail_v2/__init__.py index 079fe9c1..fd27bef4 100644 --- a/google/cloud/retail_v2/__init__.py +++ b/google/cloud/retail_v2/__init__.py @@ -41,8 +41,8 @@ from .types.common import FulfillmentInfo from .types.common import Image from .types.common import Interval +from .types.common import LocalInventory from .types.common import PriceInfo -from .types.common import Promotion from .types.common import Rating from .types.common import UserInfo from .types.completion_service import CompleteQueryRequest @@ -69,6 +69,9 @@ from .types.product_service import AddFulfillmentPlacesMetadata from .types.product_service import AddFulfillmentPlacesRequest from .types.product_service import AddFulfillmentPlacesResponse +from .types.product_service import AddLocalInventoriesMetadata +from .types.product_service import AddLocalInventoriesRequest +from .types.product_service import AddLocalInventoriesResponse from .types.product_service import CreateProductRequest from .types.product_service import DeleteProductRequest from .types.product_service import GetProductRequest @@ -77,10 +80,14 @@ from .types.product_service import RemoveFulfillmentPlacesMetadata from .types.product_service import RemoveFulfillmentPlacesRequest from .types.product_service import RemoveFulfillmentPlacesResponse +from .types.product_service import RemoveLocalInventoriesMetadata +from .types.product_service import RemoveLocalInventoriesRequest +from .types.product_service import RemoveLocalInventoriesResponse from .types.product_service import SetInventoryMetadata from .types.product_service import SetInventoryRequest from .types.product_service import SetInventoryResponse from .types.product_service import UpdateProductRequest +from .types.promotion import Promotion from .types.purge_config import PurgeMetadata from .types.purge_config import PurgeUserEventsRequest from .types.purge_config import PurgeUserEventsResponse @@ -106,6 +113,9 @@ "AddFulfillmentPlacesMetadata", "AddFulfillmentPlacesRequest", "AddFulfillmentPlacesResponse", + "AddLocalInventoriesMetadata", + "AddLocalInventoriesRequest", + "AddLocalInventoriesResponse", "Audience", "BigQuerySource", "Catalog", @@ -139,6 +149,7 @@ "ListCatalogsResponse", "ListProductsRequest", "ListProductsResponse", + "LocalInventory", "PredictRequest", "PredictResponse", "PredictionServiceClient", @@ -161,6 +172,9 @@ "RemoveFulfillmentPlacesMetadata", "RemoveFulfillmentPlacesRequest", "RemoveFulfillmentPlacesResponse", + "RemoveLocalInventoriesMetadata", + "RemoveLocalInventoriesRequest", + "RemoveLocalInventoriesResponse", "SearchRequest", "SearchResponse", "SearchServiceClient", diff --git a/google/cloud/retail_v2/gapic_metadata.json b/google/cloud/retail_v2/gapic_metadata.json index 088fcc42..9e04aec8 100644 --- a/google/cloud/retail_v2/gapic_metadata.json +++ b/google/cloud/retail_v2/gapic_metadata.json @@ -127,6 +127,11 @@ "add_fulfillment_places" ] }, + "AddLocalInventories": { + "methods": [ + "add_local_inventories" + ] + }, "CreateProduct": { "methods": [ "create_product" @@ -157,6 +162,11 @@ "remove_fulfillment_places" ] }, + "RemoveLocalInventories": { + "methods": [ + "remove_local_inventories" + ] + }, "SetInventory": { "methods": [ "set_inventory" @@ -177,6 +187,11 @@ "add_fulfillment_places" ] }, + "AddLocalInventories": { + "methods": [ + "add_local_inventories" + ] + }, "CreateProduct": { "methods": [ "create_product" @@ -207,6 +222,11 @@ "remove_fulfillment_places" ] }, + "RemoveLocalInventories": { + "methods": [ + "remove_local_inventories" + ] + }, "SetInventory": { "methods": [ "set_inventory" diff --git a/google/cloud/retail_v2/services/catalog_service/async_client.py b/google/cloud/retail_v2/services/catalog_service/async_client.py index 5977c3d0..d16af7f7 100644 --- a/google/cloud/retail_v2/services/catalog_service/async_client.py +++ b/google/cloud/retail_v2/services/catalog_service/async_client.py @@ -306,12 +306,20 @@ def sample_list_catalogs(): ) # Send the request. - response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + 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.ListCatalogsAsyncPager( - method=rpc, request=request, response=response, metadata=metadata, + method=rpc, + request=request, + response=response, + metadata=metadata, ) # Done; return the response. @@ -428,7 +436,12 @@ def sample_update_catalog(): ) # Send the request. - response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Done; return the response. return response @@ -478,11 +491,6 @@ async def set_default_branch( - UserEventService will only join events with products from branch {newBranch}. - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. - .. code-block:: python @@ -549,7 +557,10 @@ def sample_set_default_branch(): # Send the request. await rpc( - request, retry=retry, timeout=timeout, metadata=metadata, + request, + retry=retry, + timeout=timeout, + metadata=metadata, ) async def get_default_branch( @@ -565,11 +576,6 @@ async def get_default_branch( [CatalogService.SetDefaultBranch][google.cloud.retail.v2.CatalogService.SetDefaultBranch] method under a specified parent catalog. - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. - .. code-block:: python @@ -644,7 +650,12 @@ def sample_get_default_branch(): ) # Send the request. - response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Done; return the response. return response @@ -658,7 +669,9 @@ async def __aexit__(self, exc_type, exc, tb): try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution("google-cloud-retail",).version, + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, ) except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() diff --git a/google/cloud/retail_v2/services/catalog_service/client.py b/google/cloud/retail_v2/services/catalog_service/client.py index 6a93eaf6..38140ce0 100644 --- a/google/cloud/retail_v2/services/catalog_service/client.py +++ b/google/cloud/retail_v2/services/catalog_service/client.py @@ -59,7 +59,10 @@ class CatalogServiceClientMeta(type): _transport_registry["grpc"] = CatalogServiceGrpcTransport _transport_registry["grpc_asyncio"] = CatalogServiceGrpcAsyncIOTransport - def get_transport_class(cls, label: str = None,) -> Type[CatalogServiceTransport]: + def get_transport_class( + cls, + label: str = None, + ) -> Type[CatalogServiceTransport]: """Returns an appropriate transport class. Args: @@ -164,10 +167,18 @@ def transport(self) -> CatalogServiceTransport: return self._transport @staticmethod - def branch_path(project: str, location: str, catalog: str, branch: str,) -> str: + def branch_path( + project: str, + location: str, + catalog: str, + branch: str, + ) -> str: """Returns a fully-qualified branch string.""" return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format( - project=project, location=location, catalog=catalog, branch=branch, + project=project, + location=location, + catalog=catalog, + branch=branch, ) @staticmethod @@ -180,10 +191,16 @@ def parse_branch_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def catalog_path(project: str, location: str, catalog: str,) -> str: + 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, + project=project, + location=location, + catalog=catalog, ) @staticmethod @@ -196,7 +213,9 @@ def parse_catalog_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_billing_account_path(billing_account: str,) -> str: + 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, @@ -209,9 +228,13 @@ def parse_common_billing_account_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_folder_path(folder: str,) -> str: + def common_folder_path( + folder: str, + ) -> str: """Returns a fully-qualified folder string.""" - return "folders/{folder}".format(folder=folder,) + return "folders/{folder}".format( + folder=folder, + ) @staticmethod def parse_common_folder_path(path: str) -> Dict[str, str]: @@ -220,9 +243,13 @@ def parse_common_folder_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_organization_path(organization: str,) -> str: + def common_organization_path( + organization: str, + ) -> str: """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format(organization=organization,) + return "organizations/{organization}".format( + organization=organization, + ) @staticmethod def parse_common_organization_path(path: str) -> Dict[str, str]: @@ -231,9 +258,13 @@ def parse_common_organization_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_project_path(project: str,) -> str: + def common_project_path( + project: str, + ) -> str: """Returns a fully-qualified project string.""" - return "projects/{project}".format(project=project,) + return "projects/{project}".format( + project=project, + ) @staticmethod def parse_common_project_path(path: str) -> Dict[str, str]: @@ -242,10 +273,14 @@ def parse_common_project_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_location_path(project: str, location: str,) -> str: + 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, + project=project, + location=location, ) @staticmethod @@ -517,12 +552,20 @@ def sample_list_catalogs(): ) # Send the request. - response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + 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.ListCatalogsPager( - method=rpc, request=request, response=response, metadata=metadata, + method=rpc, + request=request, + response=response, + metadata=metadata, ) # Done; return the response. @@ -639,7 +682,12 @@ def sample_update_catalog(): ) # Send the request. - response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Done; return the response. return response @@ -689,11 +737,6 @@ def set_default_branch( - UserEventService will only join events with products from branch {newBranch}. - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. - .. code-block:: python @@ -760,7 +803,10 @@ def sample_set_default_branch(): # Send the request. rpc( - request, retry=retry, timeout=timeout, metadata=metadata, + request, + retry=retry, + timeout=timeout, + metadata=metadata, ) def get_default_branch( @@ -776,11 +822,6 @@ def get_default_branch( [CatalogService.SetDefaultBranch][google.cloud.retail.v2.CatalogService.SetDefaultBranch] method under a specified parent catalog. - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. - .. code-block:: python @@ -855,7 +896,12 @@ def sample_get_default_branch(): ) # Send the request. - response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Done; return the response. return response @@ -876,7 +922,9 @@ def __exit__(self, type, value, traceback): try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution("google-cloud-retail",).version, + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, ) except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() diff --git a/google/cloud/retail_v2/services/catalog_service/transports/base.py b/google/cloud/retail_v2/services/catalog_service/transports/base.py index ebc4d03a..490a9ae2 100644 --- a/google/cloud/retail_v2/services/catalog_service/transports/base.py +++ b/google/cloud/retail_v2/services/catalog_service/transports/base.py @@ -31,7 +31,9 @@ try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution("google-cloud-retail",).version, + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, ) except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() @@ -121,25 +123,33 @@ def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { self.list_catalogs: gapic_v1.method.wrap_method( - self.list_catalogs, default_timeout=None, client_info=client_info, + self.list_catalogs, + default_timeout=None, + client_info=client_info, ), self.update_catalog: gapic_v1.method.wrap_method( - self.update_catalog, default_timeout=None, client_info=client_info, + self.update_catalog, + default_timeout=None, + client_info=client_info, ), self.set_default_branch: gapic_v1.method.wrap_method( - self.set_default_branch, default_timeout=None, client_info=client_info, + self.set_default_branch, + default_timeout=None, + client_info=client_info, ), self.get_default_branch: gapic_v1.method.wrap_method( - self.get_default_branch, default_timeout=None, client_info=client_info, + self.get_default_branch, + 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! + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! """ raise NotImplementedError() diff --git a/google/cloud/retail_v2/services/catalog_service/transports/grpc.py b/google/cloud/retail_v2/services/catalog_service/transports/grpc.py index 19062639..efe548fb 100644 --- a/google/cloud/retail_v2/services/catalog_service/transports/grpc.py +++ b/google/cloud/retail_v2/services/catalog_service/transports/grpc.py @@ -226,8 +226,7 @@ def create_channel( @property def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service. - """ + """Return the channel designed to connect to this service.""" return self._grpc_channel @property @@ -327,11 +326,6 @@ def set_default_branch( - UserEventService will only join events with products from branch {newBranch}. - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. - Returns: Callable[[~.SetDefaultBranchRequest], ~.Empty]: @@ -363,11 +357,6 @@ def get_default_branch( [CatalogService.SetDefaultBranch][google.cloud.retail.v2.CatalogService.SetDefaultBranch] method under a specified parent catalog. - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. - Returns: Callable[[~.GetDefaultBranchRequest], ~.GetDefaultBranchResponse]: diff --git a/google/cloud/retail_v2/services/catalog_service/transports/grpc_asyncio.py b/google/cloud/retail_v2/services/catalog_service/transports/grpc_asyncio.py index 7d06238a..cba5a296 100644 --- a/google/cloud/retail_v2/services/catalog_service/transports/grpc_asyncio.py +++ b/google/cloud/retail_v2/services/catalog_service/transports/grpc_asyncio.py @@ -334,11 +334,6 @@ def set_default_branch( - UserEventService will only join events with products from branch {newBranch}. - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. - Returns: Callable[[~.SetDefaultBranchRequest], Awaitable[~.Empty]]: @@ -370,11 +365,6 @@ def get_default_branch( [CatalogService.SetDefaultBranch][google.cloud.retail.v2.CatalogService.SetDefaultBranch] method under a specified parent catalog. - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. - Returns: Callable[[~.GetDefaultBranchRequest], Awaitable[~.GetDefaultBranchResponse]]: diff --git a/google/cloud/retail_v2/services/completion_service/async_client.py b/google/cloud/retail_v2/services/completion_service/async_client.py index 7275c19e..dda38f1f 100644 --- a/google/cloud/retail_v2/services/completion_service/async_client.py +++ b/google/cloud/retail_v2/services/completion_service/async_client.py @@ -42,11 +42,9 @@ class CompletionServiceAsyncClient: """Auto-completion service for retail. - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud sales - if you are interested in using Retail Search. + enabled. Please enable Retail Search on Cloud Console before + using this feature. """ _client: CompletionServiceClient @@ -218,12 +216,11 @@ async def complete_query( timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> completion_service.CompleteQueryResponse: - r"""Completes the specified prefix with keyword suggestions. - - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + 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. .. code-block:: python @@ -277,7 +274,12 @@ def sample_complete_query(): ) # Send the request. - response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Done; return the response. return response @@ -291,14 +293,14 @@ async def import_completion_data( metadata: Sequence[Tuple[str, str]] = (), ) -> operation_async.AsyncOperation: r"""Bulk import of processed completion dataset. - - Request processing may be synchronous. Partial updating is not - supported. - - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + Request processing is asynchronous. Partial updating is + not supported. + The operation is successfully finished only after the + 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. .. code-block:: python @@ -369,7 +371,12 @@ def sample_import_completion_data(): ) # Send the request. - response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Wrap the response in an operation future. response = operation_async.from_gapic( @@ -391,7 +398,9 @@ async def __aexit__(self, exc_type, exc, tb): try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution("google-cloud-retail",).version, + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, ) except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() diff --git a/google/cloud/retail_v2/services/completion_service/client.py b/google/cloud/retail_v2/services/completion_service/client.py index 0fe42b09..26b6e962 100644 --- a/google/cloud/retail_v2/services/completion_service/client.py +++ b/google/cloud/retail_v2/services/completion_service/client.py @@ -58,7 +58,8 @@ class CompletionServiceClientMeta(type): _transport_registry["grpc_asyncio"] = CompletionServiceGrpcAsyncIOTransport def get_transport_class( - cls, label: str = None, + cls, + label: str = None, ) -> Type[CompletionServiceTransport]: """Returns an appropriate transport class. @@ -80,11 +81,9 @@ 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 submit a form - `here `__ to contact cloud sales - if you are interested in using Retail Search. + enabled. Please enable Retail Search on Cloud Console before + using this feature. """ @staticmethod @@ -170,10 +169,16 @@ def transport(self) -> CompletionServiceTransport: return self._transport @staticmethod - def catalog_path(project: str, location: str, catalog: str,) -> str: + 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, + project=project, + location=location, + catalog=catalog, ) @staticmethod @@ -186,7 +191,9 @@ def parse_catalog_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_billing_account_path(billing_account: str,) -> str: + 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, @@ -199,9 +206,13 @@ def parse_common_billing_account_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_folder_path(folder: str,) -> str: + def common_folder_path( + folder: str, + ) -> str: """Returns a fully-qualified folder string.""" - return "folders/{folder}".format(folder=folder,) + return "folders/{folder}".format( + folder=folder, + ) @staticmethod def parse_common_folder_path(path: str) -> Dict[str, str]: @@ -210,9 +221,13 @@ def parse_common_folder_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_organization_path(organization: str,) -> str: + def common_organization_path( + organization: str, + ) -> str: """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format(organization=organization,) + return "organizations/{organization}".format( + organization=organization, + ) @staticmethod def parse_common_organization_path(path: str) -> Dict[str, str]: @@ -221,9 +236,13 @@ def parse_common_organization_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_project_path(project: str,) -> str: + def common_project_path( + project: str, + ) -> str: """Returns a fully-qualified project string.""" - return "projects/{project}".format(project=project,) + return "projects/{project}".format( + project=project, + ) @staticmethod def parse_common_project_path(path: str) -> Dict[str, str]: @@ -232,10 +251,14 @@ def parse_common_project_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_location_path(project: str, location: str,) -> str: + 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, + project=project, + location=location, ) @staticmethod @@ -417,12 +440,11 @@ def complete_query( timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> completion_service.CompleteQueryResponse: - r"""Completes the specified prefix with keyword suggestions. - - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + 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. .. code-block:: python @@ -477,7 +499,12 @@ def sample_complete_query(): ) # Send the request. - response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Done; return the response. return response @@ -491,14 +518,14 @@ def import_completion_data( metadata: Sequence[Tuple[str, str]] = (), ) -> operation.Operation: r"""Bulk import of processed completion dataset. - - Request processing may be synchronous. Partial updating is not - supported. - - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + Request processing is asynchronous. Partial updating is + not supported. + The operation is successfully finished only after the + 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. .. code-block:: python @@ -570,7 +597,12 @@ def sample_import_completion_data(): ) # Send the request. - response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Wrap the response in an operation future. response = operation.from_gapic( @@ -599,7 +631,9 @@ def __exit__(self, type, value, traceback): try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution("google-cloud-retail",).version, + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, ) except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() diff --git a/google/cloud/retail_v2/services/completion_service/transports/base.py b/google/cloud/retail_v2/services/completion_service/transports/base.py index d706b89d..d3fefcd1 100644 --- a/google/cloud/retail_v2/services/completion_service/transports/base.py +++ b/google/cloud/retail_v2/services/completion_service/transports/base.py @@ -32,7 +32,9 @@ try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution("google-cloud-retail",).version, + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, ) except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() @@ -122,7 +124,9 @@ def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { self.complete_query: gapic_v1.method.wrap_method( - self.complete_query, default_timeout=None, client_info=client_info, + self.complete_query, + default_timeout=None, + client_info=client_info, ), self.import_completion_data: gapic_v1.method.wrap_method( self.import_completion_data, @@ -134,9 +138,9 @@ def _prep_wrapped_messages(self, 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! + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! """ raise NotImplementedError() diff --git a/google/cloud/retail_v2/services/completion_service/transports/grpc.py b/google/cloud/retail_v2/services/completion_service/transports/grpc.py index d77303d2..2e18583f 100644 --- a/google/cloud/retail_v2/services/completion_service/transports/grpc.py +++ b/google/cloud/retail_v2/services/completion_service/transports/grpc.py @@ -35,11 +35,9 @@ class CompletionServiceGrpcTransport(CompletionServiceTransport): """gRPC backend transport for CompletionService. Auto-completion service for retail. - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud sales - if you are interested in using Retail Search. + enabled. Please 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 @@ -233,8 +231,7 @@ def create_channel( @property def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service. - """ + """Return the channel designed to connect to this service.""" return self._grpc_channel @property @@ -260,12 +257,11 @@ def complete_query( ]: r"""Return a callable for the complete query method over gRPC. - Completes the specified prefix with keyword suggestions. - - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + 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. Returns: Callable[[~.CompleteQueryRequest], @@ -294,14 +290,14 @@ def import_completion_data( r"""Return a callable for the import completion data method over gRPC. Bulk import of processed completion dataset. - - Request processing may be synchronous. Partial updating is not - supported. - - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + Request processing is asynchronous. Partial updating is + not supported. + The operation is successfully finished only after the + 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. Returns: Callable[[~.ImportCompletionDataRequest], diff --git a/google/cloud/retail_v2/services/completion_service/transports/grpc_asyncio.py b/google/cloud/retail_v2/services/completion_service/transports/grpc_asyncio.py index d81955e3..d4ced221 100644 --- a/google/cloud/retail_v2/services/completion_service/transports/grpc_asyncio.py +++ b/google/cloud/retail_v2/services/completion_service/transports/grpc_asyncio.py @@ -36,11 +36,9 @@ class CompletionServiceGrpcAsyncIOTransport(CompletionServiceTransport): """gRPC AsyncIO backend transport for CompletionService. Auto-completion service for retail. - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud sales - if you are interested in using Retail Search. + enabled. Please 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,12 +262,11 @@ def complete_query( ]: r"""Return a callable for the complete query method over gRPC. - Completes the specified prefix with keyword suggestions. - - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + 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. Returns: Callable[[~.CompleteQueryRequest], @@ -298,14 +295,14 @@ def import_completion_data( r"""Return a callable for the import completion data method over gRPC. Bulk import of processed completion dataset. - - Request processing may be synchronous. Partial updating is not - supported. - - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + Request processing is asynchronous. Partial updating is + not supported. + The operation is successfully finished only after the + 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. Returns: Callable[[~.ImportCompletionDataRequest], diff --git a/google/cloud/retail_v2/services/prediction_service/async_client.py b/google/cloud/retail_v2/services/prediction_service/async_client.py index e27737ed..6de4ae08 100644 --- a/google/cloud/retail_v2/services/prediction_service/async_client.py +++ b/google/cloud/retail_v2/services/prediction_service/async_client.py @@ -268,7 +268,12 @@ def sample_predict(): ) # Send the request. - response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Done; return the response. return response @@ -282,7 +287,9 @@ async def __aexit__(self, exc_type, exc, tb): try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution("google-cloud-retail",).version, + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, ) except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() diff --git a/google/cloud/retail_v2/services/prediction_service/client.py b/google/cloud/retail_v2/services/prediction_service/client.py index d1a65dc2..403f007b 100644 --- a/google/cloud/retail_v2/services/prediction_service/client.py +++ b/google/cloud/retail_v2/services/prediction_service/client.py @@ -55,7 +55,8 @@ class PredictionServiceClientMeta(type): _transport_registry["grpc_asyncio"] = PredictionServiceGrpcAsyncIOTransport def get_transport_class( - cls, label: str = None, + cls, + label: str = None, ) -> Type[PredictionServiceTransport]: """Returns an appropriate transport class. @@ -162,7 +163,11 @@ def transport(self) -> PredictionServiceTransport: @staticmethod def product_path( - project: str, location: str, catalog: str, branch: str, product: str, + project: str, + location: str, + catalog: str, + branch: str, + product: str, ) -> str: """Returns a fully-qualified product string.""" return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format( @@ -183,7 +188,9 @@ def parse_product_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_billing_account_path(billing_account: str,) -> str: + 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, @@ -196,9 +203,13 @@ def parse_common_billing_account_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_folder_path(folder: str,) -> str: + def common_folder_path( + folder: str, + ) -> str: """Returns a fully-qualified folder string.""" - return "folders/{folder}".format(folder=folder,) + return "folders/{folder}".format( + folder=folder, + ) @staticmethod def parse_common_folder_path(path: str) -> Dict[str, str]: @@ -207,9 +218,13 @@ def parse_common_folder_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_organization_path(organization: str,) -> str: + def common_organization_path( + organization: str, + ) -> str: """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format(organization=organization,) + return "organizations/{organization}".format( + organization=organization, + ) @staticmethod def parse_common_organization_path(path: str) -> Dict[str, str]: @@ -218,9 +233,13 @@ def parse_common_organization_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_project_path(project: str,) -> str: + def common_project_path( + project: str, + ) -> str: """Returns a fully-qualified project string.""" - return "projects/{project}".format(project=project,) + return "projects/{project}".format( + project=project, + ) @staticmethod def parse_common_project_path(path: str) -> Dict[str, str]: @@ -229,10 +248,14 @@ def parse_common_project_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_location_path(project: str, location: str,) -> str: + 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, + project=project, + location=location, ) @staticmethod @@ -474,7 +497,12 @@ def sample_predict(): ) # Send the request. - response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Done; return the response. return response @@ -495,7 +523,9 @@ def __exit__(self, type, value, traceback): try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution("google-cloud-retail",).version, + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, ) except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() diff --git a/google/cloud/retail_v2/services/prediction_service/transports/base.py b/google/cloud/retail_v2/services/prediction_service/transports/base.py index c3bee8e2..4ca0d178 100644 --- a/google/cloud/retail_v2/services/prediction_service/transports/base.py +++ b/google/cloud/retail_v2/services/prediction_service/transports/base.py @@ -29,7 +29,9 @@ try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution("google-cloud-retail",).version, + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, ) except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() @@ -119,16 +121,18 @@ def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { self.predict: gapic_v1.method.wrap_method( - self.predict, default_timeout=None, client_info=client_info, + self.predict, + 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! + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! """ raise NotImplementedError() diff --git a/google/cloud/retail_v2/services/prediction_service/transports/grpc.py b/google/cloud/retail_v2/services/prediction_service/transports/grpc.py index 42691d95..1f766b20 100644 --- a/google/cloud/retail_v2/services/prediction_service/transports/grpc.py +++ b/google/cloud/retail_v2/services/prediction_service/transports/grpc.py @@ -224,8 +224,7 @@ def create_channel( @property def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service. - """ + """Return the channel designed to connect to this service.""" return self._grpc_channel @property diff --git a/google/cloud/retail_v2/services/product_service/async_client.py b/google/cloud/retail_v2/services/product_service/async_client.py index ef02d43c..43209dbe 100644 --- a/google/cloud/retail_v2/services/product_service/async_client.py +++ b/google/cloud/retail_v2/services/product_service/async_client.py @@ -39,6 +39,7 @@ from google.cloud.retail_v2.types import product from google.cloud.retail_v2.types import product as gcr_product from google.cloud.retail_v2.types import product_service +from google.cloud.retail_v2.types import promotion from google.protobuf import duration_pb2 # type: ignore from google.protobuf import field_mask_pb2 # type: ignore from google.protobuf import timestamp_pb2 # type: ignore @@ -343,7 +344,12 @@ def sample_create_product(): ) # Send the request. - response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Done; return the response. return response @@ -444,7 +450,12 @@ def sample_get_product(): ) # Send the request. - response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Done; return the response. return response @@ -547,12 +558,20 @@ def sample_list_products(): ) # Send the request. - response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + 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.ListProductsAsyncPager( - method=rpc, request=request, response=response, metadata=metadata, + method=rpc, + request=request, + response=response, + metadata=metadata, ) # Done; return the response. @@ -674,7 +693,12 @@ def sample_update_product(): ) # Send the request. - response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Done; return the response. return response @@ -779,7 +803,10 @@ def sample_delete_product(): # Send the request. await rpc( - request, retry=retry, timeout=timeout, metadata=metadata, + request, + retry=retry, + timeout=timeout, + metadata=metadata, ) async def import_products( @@ -877,7 +904,12 @@ def sample_import_products(): ) # Send the request. - response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Wrap the response in an operation future. response = operation_async.from_gapic( @@ -934,8 +966,8 @@ async def set_inventory( will be used. If no inventory fields are set in - [UpdateProductRequest.set_mask][], then any existing inventory - information will be preserved. + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask], + then any existing inventory information will be preserved. Pre-existing inventory information can only be updated with [SetInventory][google.cloud.retail.v2.ProductService.SetInventory], @@ -944,9 +976,8 @@ async def set_inventory( [RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]. This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + enabled. Please enable Retail Search on Cloud Console before + using this feature. .. code-block:: python @@ -1010,6 +1041,26 @@ def sample_set_inventory(): provided or default value for [SetInventoryRequest.set_time][google.cloud.retail.v2.SetInventoryRequest.set_time]. + The caller can replace place IDs for a subset of + fulfillment types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types and + corresponding place IDs to update in + [SetInventoryRequest.inventory.fulfillment_info][] + + The caller can clear all place IDs from a subset of + fulfillment types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types to clear + in [SetInventoryRequest.inventory.fulfillment_info][] + - Checks that only the desired fulfillment info types + have empty + [SetInventoryRequest.inventory.fulfillment_info.place_ids][] + The last update time is recorded for the following inventory fields: @@ -1027,9 +1078,9 @@ def sample_set_inventory(): should not be set. set_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): Indicates which inventory fields in the provided - [Product][google.cloud.retail.v2.Product] to update. If - not set or set with empty paths, all inventory fields - will be updated. + [Product][google.cloud.retail.v2.Product] to update. + + At least one field must be provided. If an unsupported or unknown field is provided, an INVALID_ARGUMENT error is returned and the entire update @@ -1089,7 +1140,12 @@ def sample_set_inventory(): ) # Send the request. - response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Wrap the response in an operation future. response = operation_async.from_gapic( @@ -1126,9 +1182,8 @@ async def add_fulfillment_places( [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + enabled. Please enable Retail Search on Cloud Console before + using this feature. .. code-block:: python @@ -1220,7 +1275,12 @@ def sample_add_fulfillment_places(): ) # Send the request. - response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Wrap the response in an operation future. response = operation_async.from_gapic( @@ -1257,9 +1317,8 @@ async def remove_fulfillment_places( [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + enabled. Please enable Retail Search on Cloud Console before + using this feature. .. code-block:: python @@ -1351,7 +1410,12 @@ def sample_remove_fulfillment_places(): ) # Send the request. - response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Wrap the response in an operation future. response = operation_async.from_gapic( @@ -1364,6 +1428,288 @@ def sample_remove_fulfillment_places(): # Done; return the response. return response + async def add_local_inventories( + self, + request: Union[product_service.AddLocalInventoriesRequest, dict] = None, + *, + product: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Updates local inventory information for a + [Product][google.cloud.retail.v2.Product] at a list of places, + while respecting the last update timestamps of each inventory + field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating inventory 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.v2.Product] queried by + [GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + Local inventory information can only be modified using this + method. + [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + has no effect on local inventories. + + This feature is only available for users who have Retail Search + enabled. Please enable Retail Search on Cloud Console before + using this feature. + + + .. code-block:: python + + from google.cloud import retail_v2 + + def sample_add_local_inventories(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2.AddLocalInventoriesRequest( + product="product_value", + ) + + # Make the request + operation = client.add_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.AddLocalInventoriesRequest, dict]): + The request object. Request message for + [AddLocalInventories][] method. + product (:class:`str`): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2.types.AddLocalInventoriesResponse` Response of the [AddLocalInventories][] API. Currently empty because + there is no meaningful response populated from the + [AddLocalInventories][] method. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([product]) + 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 = product_service.AddLocalInventoriesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if product is not None: + request.product = product + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.add_local_inventories, + 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((("product", request.product),)), + ) + + # 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, + product_service.AddLocalInventoriesResponse, + metadata_type=product_service.AddLocalInventoriesMetadata, + ) + + # Done; return the response. + return response + + async def remove_local_inventories( + self, + request: Union[product_service.RemoveLocalInventoriesRequest, dict] = None, + *, + product: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Remove local inventory information for a + [Product][google.cloud.retail.v2.Product] at a list of places at + a removal timestamp. + + This process is asynchronous. If the request is valid, the + removal will be enqueued and processed downstream. As a + consequence, when a response is returned, removals are not + immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + Local inventory information can only be removed using this + method. + [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + has no effect on local inventories. + + This feature is only available for users who have Retail Search + enabled. Please enable Retail Search on Cloud Console before + using this feature. + + + .. code-block:: python + + from google.cloud import retail_v2 + + def sample_remove_local_inventories(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2.RemoveLocalInventoriesRequest( + product="product_value", + place_ids=['place_ids_value_1', 'place_ids_value_2'], + ) + + # Make the request + operation = client.remove_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.RemoveLocalInventoriesRequest, dict]): + The request object. Request message for + [RemoveLocalInventories][] method. + product (:class:`str`): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2.types.RemoveLocalInventoriesResponse` Response of the [RemoveLocalInventories][] API. Currently empty because + there is no meaningful response populated from the + [RemoveLocalInventories][] method. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([product]) + 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 = product_service.RemoveLocalInventoriesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if product is not None: + request.product = product + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.remove_local_inventories, + 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((("product", request.product),)), + ) + + # 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, + product_service.RemoveLocalInventoriesResponse, + metadata_type=product_service.RemoveLocalInventoriesMetadata, + ) + + # Done; return the response. + return response + async def __aenter__(self): return self @@ -1373,7 +1719,9 @@ async def __aexit__(self, exc_type, exc, tb): try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution("google-cloud-retail",).version, + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, ) except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() diff --git a/google/cloud/retail_v2/services/product_service/client.py b/google/cloud/retail_v2/services/product_service/client.py index ff579dc9..8b252968 100644 --- a/google/cloud/retail_v2/services/product_service/client.py +++ b/google/cloud/retail_v2/services/product_service/client.py @@ -42,6 +42,7 @@ from google.cloud.retail_v2.types import product from google.cloud.retail_v2.types import product as gcr_product from google.cloud.retail_v2.types import product_service +from google.cloud.retail_v2.types import promotion from google.protobuf import duration_pb2 # type: ignore from google.protobuf import field_mask_pb2 # type: ignore from google.protobuf import timestamp_pb2 # type: ignore @@ -65,7 +66,10 @@ class ProductServiceClientMeta(type): _transport_registry["grpc"] = ProductServiceGrpcTransport _transport_registry["grpc_asyncio"] = ProductServiceGrpcAsyncIOTransport - def get_transport_class(cls, label: str = None,) -> Type[ProductServiceTransport]: + def get_transport_class( + cls, + label: str = None, + ) -> Type[ProductServiceTransport]: """Returns an appropriate transport class. Args: @@ -172,10 +176,18 @@ def transport(self) -> ProductServiceTransport: return self._transport @staticmethod - def branch_path(project: str, location: str, catalog: str, branch: str,) -> str: + def branch_path( + project: str, + location: str, + catalog: str, + branch: str, + ) -> str: """Returns a fully-qualified branch string.""" return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format( - project=project, location=location, catalog=catalog, branch=branch, + project=project, + location=location, + catalog=catalog, + branch=branch, ) @staticmethod @@ -189,7 +201,11 @@ def parse_branch_path(path: str) -> Dict[str, str]: @staticmethod def product_path( - project: str, location: str, catalog: str, branch: str, product: str, + project: str, + location: str, + catalog: str, + branch: str, + product: str, ) -> str: """Returns a fully-qualified product string.""" return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format( @@ -210,7 +226,9 @@ def parse_product_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_billing_account_path(billing_account: str,) -> str: + 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, @@ -223,9 +241,13 @@ def parse_common_billing_account_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_folder_path(folder: str,) -> str: + def common_folder_path( + folder: str, + ) -> str: """Returns a fully-qualified folder string.""" - return "folders/{folder}".format(folder=folder,) + return "folders/{folder}".format( + folder=folder, + ) @staticmethod def parse_common_folder_path(path: str) -> Dict[str, str]: @@ -234,9 +256,13 @@ def parse_common_folder_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_organization_path(organization: str,) -> str: + def common_organization_path( + organization: str, + ) -> str: """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format(organization=organization,) + return "organizations/{organization}".format( + organization=organization, + ) @staticmethod def parse_common_organization_path(path: str) -> Dict[str, str]: @@ -245,9 +271,13 @@ def parse_common_organization_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_project_path(project: str,) -> str: + def common_project_path( + project: str, + ) -> str: """Returns a fully-qualified project string.""" - return "projects/{project}".format(project=project,) + return "projects/{project}".format( + project=project, + ) @staticmethod def parse_common_project_path(path: str) -> Dict[str, str]: @@ -256,10 +286,14 @@ def parse_common_project_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_location_path(project: str, location: str,) -> str: + 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, + project=project, + location=location, ) @staticmethod @@ -560,7 +594,12 @@ def sample_create_product(): ) # Send the request. - response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Done; return the response. return response @@ -661,7 +700,12 @@ def sample_get_product(): ) # Send the request. - response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Done; return the response. return response @@ -764,12 +808,20 @@ def sample_list_products(): ) # Send the request. - response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + 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.ListProductsPager( - method=rpc, request=request, response=response, metadata=metadata, + method=rpc, + request=request, + response=response, + metadata=metadata, ) # Done; return the response. @@ -891,7 +943,12 @@ def sample_update_product(): ) # Send the request. - response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Done; return the response. return response @@ -996,7 +1053,10 @@ def sample_delete_product(): # Send the request. rpc( - request, retry=retry, timeout=timeout, metadata=metadata, + request, + retry=retry, + timeout=timeout, + metadata=metadata, ) def import_products( @@ -1085,7 +1145,12 @@ def sample_import_products(): ) # Send the request. - response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Wrap the response in an operation future. response = operation.from_gapic( @@ -1142,8 +1207,8 @@ def set_inventory( will be used. If no inventory fields are set in - [UpdateProductRequest.set_mask][], then any existing inventory - information will be preserved. + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask], + then any existing inventory information will be preserved. Pre-existing inventory information can only be updated with [SetInventory][google.cloud.retail.v2.ProductService.SetInventory], @@ -1152,9 +1217,8 @@ def set_inventory( [RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]. This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + enabled. Please enable Retail Search on Cloud Console before + using this feature. .. code-block:: python @@ -1218,6 +1282,26 @@ def sample_set_inventory(): provided or default value for [SetInventoryRequest.set_time][google.cloud.retail.v2.SetInventoryRequest.set_time]. + The caller can replace place IDs for a subset of + fulfillment types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types and + corresponding place IDs to update in + [SetInventoryRequest.inventory.fulfillment_info][] + + The caller can clear all place IDs from a subset of + fulfillment types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types to clear + in [SetInventoryRequest.inventory.fulfillment_info][] + - Checks that only the desired fulfillment info types + have empty + [SetInventoryRequest.inventory.fulfillment_info.place_ids][] + The last update time is recorded for the following inventory fields: @@ -1235,9 +1319,9 @@ def sample_set_inventory(): should not be set. set_mask (google.protobuf.field_mask_pb2.FieldMask): Indicates which inventory fields in the provided - [Product][google.cloud.retail.v2.Product] to update. If - not set or set with empty paths, all inventory fields - will be updated. + [Product][google.cloud.retail.v2.Product] to update. + + At least one field must be provided. If an unsupported or unknown field is provided, an INVALID_ARGUMENT error is returned and the entire update @@ -1297,7 +1381,12 @@ def sample_set_inventory(): ) # Send the request. - response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Wrap the response in an operation future. response = operation.from_gapic( @@ -1334,9 +1423,8 @@ def add_fulfillment_places( [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + enabled. Please enable Retail Search on Cloud Console before + using this feature. .. code-block:: python @@ -1428,7 +1516,12 @@ def sample_add_fulfillment_places(): ) # Send the request. - response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Wrap the response in an operation future. response = operation.from_gapic( @@ -1465,9 +1558,8 @@ def remove_fulfillment_places( [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + enabled. Please enable Retail Search on Cloud Console before + using this feature. .. code-block:: python @@ -1561,7 +1653,12 @@ def sample_remove_fulfillment_places(): ) # Send the request. - response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Wrap the response in an operation future. response = operation.from_gapic( @@ -1574,6 +1671,288 @@ def sample_remove_fulfillment_places(): # Done; return the response. return response + def add_local_inventories( + self, + request: Union[product_service.AddLocalInventoriesRequest, dict] = None, + *, + product: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Updates local inventory information for a + [Product][google.cloud.retail.v2.Product] at a list of places, + while respecting the last update timestamps of each inventory + field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating inventory 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.v2.Product] queried by + [GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + Local inventory information can only be modified using this + method. + [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + has no effect on local inventories. + + This feature is only available for users who have Retail Search + enabled. Please enable Retail Search on Cloud Console before + using this feature. + + + .. code-block:: python + + from google.cloud import retail_v2 + + def sample_add_local_inventories(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2.AddLocalInventoriesRequest( + product="product_value", + ) + + # Make the request + operation = client.add_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.AddLocalInventoriesRequest, dict]): + The request object. Request message for + [AddLocalInventories][] method. + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2.types.AddLocalInventoriesResponse` Response of the [AddLocalInventories][] API. Currently empty because + there is no meaningful response populated from the + [AddLocalInventories][] method. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([product]) + 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 product_service.AddLocalInventoriesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.AddLocalInventoriesRequest): + request = product_service.AddLocalInventoriesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if product is not None: + request.product = product + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.add_local_inventories] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("product", request.product),)), + ) + + # 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, + product_service.AddLocalInventoriesResponse, + metadata_type=product_service.AddLocalInventoriesMetadata, + ) + + # Done; return the response. + return response + + def remove_local_inventories( + self, + request: Union[product_service.RemoveLocalInventoriesRequest, dict] = None, + *, + product: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Remove local inventory information for a + [Product][google.cloud.retail.v2.Product] at a list of places at + a removal timestamp. + + This process is asynchronous. If the request is valid, the + removal will be enqueued and processed downstream. As a + consequence, when a response is returned, removals are not + immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + Local inventory information can only be removed using this + method. + [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + has no effect on local inventories. + + This feature is only available for users who have Retail Search + enabled. Please enable Retail Search on Cloud Console before + using this feature. + + + .. code-block:: python + + from google.cloud import retail_v2 + + def sample_remove_local_inventories(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2.RemoveLocalInventoriesRequest( + product="product_value", + place_ids=['place_ids_value_1', 'place_ids_value_2'], + ) + + # Make the request + operation = client.remove_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.RemoveLocalInventoriesRequest, dict]): + The request object. Request message for + [RemoveLocalInventories][] method. + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2.types.RemoveLocalInventoriesResponse` Response of the [RemoveLocalInventories][] API. Currently empty because + there is no meaningful response populated from the + [RemoveLocalInventories][] method. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([product]) + 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 product_service.RemoveLocalInventoriesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.RemoveLocalInventoriesRequest): + request = product_service.RemoveLocalInventoriesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if product is not None: + request.product = product + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.remove_local_inventories] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("product", request.product),)), + ) + + # 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, + product_service.RemoveLocalInventoriesResponse, + metadata_type=product_service.RemoveLocalInventoriesMetadata, + ) + + # Done; return the response. + return response + def __enter__(self): return self @@ -1590,7 +1969,9 @@ def __exit__(self, type, value, traceback): try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution("google-cloud-retail",).version, + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, ) except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() diff --git a/google/cloud/retail_v2/services/product_service/transports/base.py b/google/cloud/retail_v2/services/product_service/transports/base.py index 2649bd86..0b7721ef 100644 --- a/google/cloud/retail_v2/services/product_service/transports/base.py +++ b/google/cloud/retail_v2/services/product_service/transports/base.py @@ -35,7 +35,9 @@ try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution("google-cloud-retail",).version, + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, ) except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() @@ -125,19 +127,29 @@ def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { self.create_product: gapic_v1.method.wrap_method( - self.create_product, default_timeout=None, client_info=client_info, + self.create_product, + default_timeout=None, + client_info=client_info, ), self.get_product: gapic_v1.method.wrap_method( - self.get_product, default_timeout=None, client_info=client_info, + self.get_product, + default_timeout=None, + client_info=client_info, ), self.list_products: gapic_v1.method.wrap_method( - self.list_products, default_timeout=None, client_info=client_info, + self.list_products, + default_timeout=None, + client_info=client_info, ), self.update_product: gapic_v1.method.wrap_method( - self.update_product, default_timeout=None, client_info=client_info, + self.update_product, + default_timeout=None, + client_info=client_info, ), self.delete_product: gapic_v1.method.wrap_method( - self.delete_product, default_timeout=None, client_info=client_info, + self.delete_product, + default_timeout=None, + client_info=client_info, ), self.import_products: gapic_v1.method.wrap_method( self.import_products, @@ -155,7 +167,9 @@ def _prep_wrapped_messages(self, client_info): client_info=client_info, ), self.set_inventory: gapic_v1.method.wrap_method( - self.set_inventory, default_timeout=None, client_info=client_info, + self.set_inventory, + default_timeout=None, + client_info=client_info, ), self.add_fulfillment_places: gapic_v1.method.wrap_method( self.add_fulfillment_places, @@ -167,14 +181,24 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.add_local_inventories: gapic_v1.method.wrap_method( + self.add_local_inventories, + default_timeout=None, + client_info=client_info, + ), + self.remove_local_inventories: gapic_v1.method.wrap_method( + self.remove_local_inventories, + 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! + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! """ raise NotImplementedError() @@ -267,5 +291,23 @@ def remove_fulfillment_places( ]: raise NotImplementedError() + @property + def add_local_inventories( + self, + ) -> Callable[ + [product_service.AddLocalInventoriesRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def remove_local_inventories( + self, + ) -> Callable[ + [product_service.RemoveLocalInventoriesRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + __all__ = ("ProductServiceTransport",) diff --git a/google/cloud/retail_v2/services/product_service/transports/grpc.py b/google/cloud/retail_v2/services/product_service/transports/grpc.py index 401e325f..7e491bb9 100644 --- a/google/cloud/retail_v2/services/product_service/transports/grpc.py +++ b/google/cloud/retail_v2/services/product_service/transports/grpc.py @@ -232,8 +232,7 @@ def create_channel( @property def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service. - """ + """Return the channel designed to connect to this service.""" return self._grpc_channel @property @@ -456,8 +455,8 @@ def set_inventory( will be used. If no inventory fields are set in - [UpdateProductRequest.set_mask][], then any existing inventory - information will be preserved. + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask], + then any existing inventory information will be preserved. Pre-existing inventory information can only be updated with [SetInventory][google.cloud.retail.v2.ProductService.SetInventory], @@ -466,9 +465,8 @@ def set_inventory( [RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]. This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + enabled. Please enable Retail Search on Cloud Console before + using this feature. Returns: Callable[[~.SetInventoryRequest], @@ -511,9 +509,8 @@ def add_fulfillment_places( [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + enabled. Please enable Retail Search on Cloud Console before + using this feature. Returns: Callable[[~.AddFulfillmentPlacesRequest], @@ -556,9 +553,8 @@ def remove_fulfillment_places( [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + enabled. Please enable Retail Search on Cloud Console before + using this feature. Returns: Callable[[~.RemoveFulfillmentPlacesRequest], @@ -578,6 +574,109 @@ def remove_fulfillment_places( ) return self._stubs["remove_fulfillment_places"] + @property + def add_local_inventories( + self, + ) -> Callable[ + [product_service.AddLocalInventoriesRequest], operations_pb2.Operation + ]: + r"""Return a callable for the add local inventories method over gRPC. + + Updates local inventory information for a + [Product][google.cloud.retail.v2.Product] at a list of places, + while respecting the last update timestamps of each inventory + field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating inventory 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.v2.Product] queried by + [GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + Local inventory information can only be modified using this + method. + [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + has no effect on local inventories. + + This feature is only available for users who have Retail Search + enabled. Please enable Retail Search on Cloud Console before + using this feature. + + Returns: + Callable[[~.AddLocalInventoriesRequest], + ~.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 "add_local_inventories" not in self._stubs: + self._stubs["add_local_inventories"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2.ProductService/AddLocalInventories", + request_serializer=product_service.AddLocalInventoriesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["add_local_inventories"] + + @property + def remove_local_inventories( + self, + ) -> Callable[ + [product_service.RemoveLocalInventoriesRequest], operations_pb2.Operation + ]: + r"""Return a callable for the remove local inventories method over gRPC. + + Remove local inventory information for a + [Product][google.cloud.retail.v2.Product] at a list of places at + a removal timestamp. + + This process is asynchronous. If the request is valid, the + removal will be enqueued and processed downstream. As a + consequence, when a response is returned, removals are not + immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + Local inventory information can only be removed using this + method. + [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + has no effect on local inventories. + + This feature is only available for users who have Retail Search + enabled. Please enable Retail Search on Cloud Console before + using this feature. + + Returns: + Callable[[~.RemoveLocalInventoriesRequest], + ~.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 "remove_local_inventories" not in self._stubs: + self._stubs["remove_local_inventories"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2.ProductService/RemoveLocalInventories", + request_serializer=product_service.RemoveLocalInventoriesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["remove_local_inventories"] + def close(self): self.grpc_channel.close() diff --git a/google/cloud/retail_v2/services/product_service/transports/grpc_asyncio.py b/google/cloud/retail_v2/services/product_service/transports/grpc_asyncio.py index 5579ad53..417a4d0d 100644 --- a/google/cloud/retail_v2/services/product_service/transports/grpc_asyncio.py +++ b/google/cloud/retail_v2/services/product_service/transports/grpc_asyncio.py @@ -469,8 +469,8 @@ def set_inventory( will be used. If no inventory fields are set in - [UpdateProductRequest.set_mask][], then any existing inventory - information will be preserved. + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask], + then any existing inventory information will be preserved. Pre-existing inventory information can only be updated with [SetInventory][google.cloud.retail.v2.ProductService.SetInventory], @@ -479,9 +479,8 @@ def set_inventory( [RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]. This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + enabled. Please enable Retail Search on Cloud Console before + using this feature. Returns: Callable[[~.SetInventoryRequest], @@ -525,9 +524,8 @@ def add_fulfillment_places( [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + enabled. Please enable Retail Search on Cloud Console before + using this feature. Returns: Callable[[~.AddFulfillmentPlacesRequest], @@ -571,9 +569,8 @@ def remove_fulfillment_places( [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + enabled. Please enable Retail Search on Cloud Console before + using this feature. Returns: Callable[[~.RemoveFulfillmentPlacesRequest], @@ -593,6 +590,111 @@ def remove_fulfillment_places( ) return self._stubs["remove_fulfillment_places"] + @property + def add_local_inventories( + self, + ) -> Callable[ + [product_service.AddLocalInventoriesRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the add local inventories method over gRPC. + + Updates local inventory information for a + [Product][google.cloud.retail.v2.Product] at a list of places, + while respecting the last update timestamps of each inventory + field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating inventory 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.v2.Product] queried by + [GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + Local inventory information can only be modified using this + method. + [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + has no effect on local inventories. + + This feature is only available for users who have Retail Search + enabled. Please enable Retail Search on Cloud Console before + using this feature. + + Returns: + Callable[[~.AddLocalInventoriesRequest], + 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 "add_local_inventories" not in self._stubs: + self._stubs["add_local_inventories"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2.ProductService/AddLocalInventories", + request_serializer=product_service.AddLocalInventoriesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["add_local_inventories"] + + @property + def remove_local_inventories( + self, + ) -> Callable[ + [product_service.RemoveLocalInventoriesRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the remove local inventories method over gRPC. + + Remove local inventory information for a + [Product][google.cloud.retail.v2.Product] at a list of places at + a removal timestamp. + + This process is asynchronous. If the request is valid, the + removal will be enqueued and processed downstream. As a + consequence, when a response is returned, removals are not + immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + Local inventory information can only be removed using this + method. + [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + has no effect on local inventories. + + This feature is only available for users who have Retail Search + enabled. Please enable Retail Search on Cloud Console before + using this feature. + + Returns: + Callable[[~.RemoveLocalInventoriesRequest], + 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 "remove_local_inventories" not in self._stubs: + self._stubs["remove_local_inventories"] = self.grpc_channel.unary_unary( + "/google.cloud.retail.v2.ProductService/RemoveLocalInventories", + request_serializer=product_service.RemoveLocalInventoriesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["remove_local_inventories"] + def close(self): return self.grpc_channel.close() diff --git a/google/cloud/retail_v2/services/search_service/async_client.py b/google/cloud/retail_v2/services/search_service/async_client.py index 4cb5fec6..dc6608f7 100644 --- a/google/cloud/retail_v2/services/search_service/async_client.py +++ b/google/cloud/retail_v2/services/search_service/async_client.py @@ -40,11 +40,9 @@ class SearchServiceAsyncClient: """Service for search. - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud sales - if you are interested in using Retail Search. + enabled. Please enable Retail Search on Cloud Console before + using this feature. """ _client: SearchServiceClient @@ -219,11 +217,9 @@ async def search( metadata: Sequence[Tuple[str, str]] = (), ) -> pagers.SearchAsyncPager: r"""Performs a search. - - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + This feature is only available for users who have Retail + Search enabled. Please enable Retail Search on Cloud + Console before using this feature. .. code-block:: python @@ -288,12 +284,20 @@ def sample_search(): ) # Send the request. - response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + 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.SearchAsyncPager( - method=rpc, request=request, response=response, metadata=metadata, + method=rpc, + request=request, + response=response, + metadata=metadata, ) # Done; return the response. @@ -308,7 +312,9 @@ async def __aexit__(self, exc_type, exc, tb): try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution("google-cloud-retail",).version, + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, ) except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() diff --git a/google/cloud/retail_v2/services/search_service/client.py b/google/cloud/retail_v2/services/search_service/client.py index 58d724ba..603c02bc 100644 --- a/google/cloud/retail_v2/services/search_service/client.py +++ b/google/cloud/retail_v2/services/search_service/client.py @@ -53,7 +53,10 @@ class SearchServiceClientMeta(type): _transport_registry["grpc"] = SearchServiceGrpcTransport _transport_registry["grpc_asyncio"] = SearchServiceGrpcAsyncIOTransport - def get_transport_class(cls, label: str = None,) -> Type[SearchServiceTransport]: + def get_transport_class( + cls, + label: str = None, + ) -> Type[SearchServiceTransport]: """Returns an appropriate transport class. Args: @@ -74,11 +77,9 @@ def get_transport_class(cls, label: str = None,) -> Type[SearchServiceTransport] class SearchServiceClient(metaclass=SearchServiceClientMeta): """Service for search. - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud sales - if you are interested in using Retail Search. + enabled. Please enable Retail Search on Cloud Console before + using this feature. """ @staticmethod @@ -164,10 +165,18 @@ def transport(self) -> SearchServiceTransport: return self._transport @staticmethod - def branch_path(project: str, location: str, catalog: str, branch: str,) -> str: + def branch_path( + project: str, + location: str, + catalog: str, + branch: str, + ) -> str: """Returns a fully-qualified branch string.""" return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format( - project=project, location=location, catalog=catalog, branch=branch, + project=project, + location=location, + catalog=catalog, + branch=branch, ) @staticmethod @@ -181,7 +190,11 @@ def parse_branch_path(path: str) -> Dict[str, str]: @staticmethod def product_path( - project: str, location: str, catalog: str, branch: str, product: str, + project: str, + location: str, + catalog: str, + branch: str, + product: str, ) -> str: """Returns a fully-qualified product string.""" return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format( @@ -202,7 +215,9 @@ def parse_product_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_billing_account_path(billing_account: str,) -> str: + 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, @@ -215,9 +230,13 @@ def parse_common_billing_account_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_folder_path(folder: str,) -> str: + def common_folder_path( + folder: str, + ) -> str: """Returns a fully-qualified folder string.""" - return "folders/{folder}".format(folder=folder,) + return "folders/{folder}".format( + folder=folder, + ) @staticmethod def parse_common_folder_path(path: str) -> Dict[str, str]: @@ -226,9 +245,13 @@ def parse_common_folder_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_organization_path(organization: str,) -> str: + def common_organization_path( + organization: str, + ) -> str: """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format(organization=organization,) + return "organizations/{organization}".format( + organization=organization, + ) @staticmethod def parse_common_organization_path(path: str) -> Dict[str, str]: @@ -237,9 +260,13 @@ def parse_common_organization_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_project_path(project: str,) -> str: + def common_project_path( + project: str, + ) -> str: """Returns a fully-qualified project string.""" - return "projects/{project}".format(project=project,) + return "projects/{project}".format( + project=project, + ) @staticmethod def parse_common_project_path(path: str) -> Dict[str, str]: @@ -248,10 +275,14 @@ def parse_common_project_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_location_path(project: str, location: str,) -> str: + 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, + project=project, + location=location, ) @staticmethod @@ -434,11 +465,9 @@ def search( metadata: Sequence[Tuple[str, str]] = (), ) -> pagers.SearchPager: r"""Performs a search. - - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + This feature is only available for users who have Retail + Search enabled. Please enable Retail Search on Cloud + Console before using this feature. .. code-block:: python @@ -504,12 +533,20 @@ def sample_search(): ) # Send the request. - response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + 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.SearchPager( - method=rpc, request=request, response=response, metadata=metadata, + method=rpc, + request=request, + response=response, + metadata=metadata, ) # Done; return the response. @@ -531,7 +568,9 @@ def __exit__(self, type, value, traceback): try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution("google-cloud-retail",).version, + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, ) except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() diff --git a/google/cloud/retail_v2/services/search_service/transports/base.py b/google/cloud/retail_v2/services/search_service/transports/base.py index 2083f113..1cdcb365 100644 --- a/google/cloud/retail_v2/services/search_service/transports/base.py +++ b/google/cloud/retail_v2/services/search_service/transports/base.py @@ -29,7 +29,9 @@ try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution("google-cloud-retail",).version, + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, ) except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() @@ -119,16 +121,18 @@ def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { self.search: gapic_v1.method.wrap_method( - self.search, default_timeout=None, client_info=client_info, + self.search, + 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! + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! """ raise NotImplementedError() diff --git a/google/cloud/retail_v2/services/search_service/transports/grpc.py b/google/cloud/retail_v2/services/search_service/transports/grpc.py index 7e7d1f90..e0560031 100644 --- a/google/cloud/retail_v2/services/search_service/transports/grpc.py +++ b/google/cloud/retail_v2/services/search_service/transports/grpc.py @@ -32,11 +32,9 @@ class SearchServiceGrpcTransport(SearchServiceTransport): """gRPC backend transport for SearchService. Service for search. - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud sales - if you are interested in using Retail Search. + enabled. Please 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 @@ -229,8 +227,7 @@ def create_channel( @property def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service. - """ + """Return the channel designed to connect to this service.""" return self._grpc_channel @property @@ -240,11 +237,9 @@ def search( r"""Return a callable for the search method over gRPC. Performs a search. - - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + This feature is only available for users who have Retail + Search enabled. Please enable Retail Search on Cloud + Console before using this feature. Returns: Callable[[~.SearchRequest], diff --git a/google/cloud/retail_v2/services/search_service/transports/grpc_asyncio.py b/google/cloud/retail_v2/services/search_service/transports/grpc_asyncio.py index e5ebd6ac..fb5e5d36 100644 --- a/google/cloud/retail_v2/services/search_service/transports/grpc_asyncio.py +++ b/google/cloud/retail_v2/services/search_service/transports/grpc_asyncio.py @@ -33,11 +33,9 @@ class SearchServiceGrpcAsyncIOTransport(SearchServiceTransport): """gRPC AsyncIO backend transport for SearchService. Service for search. - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud sales - if you are interested in using Retail Search. + enabled. Please 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,11 +242,9 @@ def search( r"""Return a callable for the search method over gRPC. Performs a search. - - This feature is only available for users who have Retail Search - enabled. Please submit a form - `here `__ to contact cloud - sales if you are interested in using Retail Search. + This feature is only available for users who have Retail + Search enabled. Please enable Retail Search on Cloud + Console before using this feature. Returns: Callable[[~.SearchRequest], diff --git a/google/cloud/retail_v2/services/user_event_service/async_client.py b/google/cloud/retail_v2/services/user_event_service/async_client.py index c962ca36..92eba928 100644 --- a/google/cloud/retail_v2/services/user_event_service/async_client.py +++ b/google/cloud/retail_v2/services/user_event_service/async_client.py @@ -284,7 +284,12 @@ def sample_write_user_event(): ) # Send the request. - response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Done; return the response. return response @@ -403,7 +408,12 @@ def sample_collect_user_event(): ) # Send the request. - response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Done; return the response. return response @@ -494,7 +504,12 @@ def sample_purge_user_events(): ) # Send the request. - response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Wrap the response in an operation future. response = operation_async.from_gapic( @@ -601,7 +616,12 @@ def sample_import_user_events(): ) # Send the request. - response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Wrap the response in an operation future. response = operation_async.from_gapic( @@ -622,16 +642,17 @@ async def rejoin_user_events( timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> operation_async.AsyncOperation: - r"""Triggers a user event rejoin operation with latest + 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 API can be - used to trigger a 'join' operation on specified events + 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 wrong product - catalog. + used to correct events joined with the wrong product + catalog. A rejoin operation can take hours or days to + complete. .. code-block:: python @@ -694,7 +715,12 @@ def sample_rejoin_user_events(): ) # Send the request. - response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Wrap the response in an operation future. response = operation_async.from_gapic( @@ -716,7 +742,9 @@ async def __aexit__(self, exc_type, exc, tb): try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution("google-cloud-retail",).version, + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, ) except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() diff --git a/google/cloud/retail_v2/services/user_event_service/client.py b/google/cloud/retail_v2/services/user_event_service/client.py index aa9e1d69..73f8afe1 100644 --- a/google/cloud/retail_v2/services/user_event_service/client.py +++ b/google/cloud/retail_v2/services/user_event_service/client.py @@ -63,7 +63,10 @@ class UserEventServiceClientMeta(type): _transport_registry["grpc"] = UserEventServiceGrpcTransport _transport_registry["grpc_asyncio"] = UserEventServiceGrpcAsyncIOTransport - def get_transport_class(cls, label: str = None,) -> Type[UserEventServiceTransport]: + def get_transport_class( + cls, + label: str = None, + ) -> Type[UserEventServiceTransport]: """Returns an appropriate transport class. Args: @@ -170,10 +173,16 @@ def transport(self) -> UserEventServiceTransport: return self._transport @staticmethod - def catalog_path(project: str, location: str, catalog: str,) -> str: + 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, + project=project, + location=location, + catalog=catalog, ) @staticmethod @@ -187,7 +196,11 @@ def parse_catalog_path(path: str) -> Dict[str, str]: @staticmethod def product_path( - project: str, location: str, catalog: str, branch: str, product: str, + project: str, + location: str, + catalog: str, + branch: str, + product: str, ) -> str: """Returns a fully-qualified product string.""" return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format( @@ -208,7 +221,9 @@ def parse_product_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_billing_account_path(billing_account: str,) -> str: + 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, @@ -221,9 +236,13 @@ def parse_common_billing_account_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_folder_path(folder: str,) -> str: + def common_folder_path( + folder: str, + ) -> str: """Returns a fully-qualified folder string.""" - return "folders/{folder}".format(folder=folder,) + return "folders/{folder}".format( + folder=folder, + ) @staticmethod def parse_common_folder_path(path: str) -> Dict[str, str]: @@ -232,9 +251,13 @@ def parse_common_folder_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_organization_path(organization: str,) -> str: + def common_organization_path( + organization: str, + ) -> str: """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format(organization=organization,) + return "organizations/{organization}".format( + organization=organization, + ) @staticmethod def parse_common_organization_path(path: str) -> Dict[str, str]: @@ -243,9 +266,13 @@ def parse_common_organization_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_project_path(project: str,) -> str: + def common_project_path( + project: str, + ) -> str: """Returns a fully-qualified project string.""" - return "projects/{project}".format(project=project,) + return "projects/{project}".format( + project=project, + ) @staticmethod def parse_common_project_path(path: str) -> Dict[str, str]: @@ -254,10 +281,14 @@ def parse_common_project_path(path: str) -> Dict[str, str]: return m.groupdict() if m else {} @staticmethod - def common_location_path(project: str, location: str,) -> str: + 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, + project=project, + location=location, ) @staticmethod @@ -502,7 +533,12 @@ def sample_write_user_event(): ) # Send the request. - response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Done; return the response. return response @@ -622,7 +658,12 @@ def sample_collect_user_event(): ) # Send the request. - response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Done; return the response. return response @@ -704,7 +745,12 @@ def sample_purge_user_events(): ) # Send the request. - response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Wrap the response in an operation future. response = operation.from_gapic( @@ -802,7 +848,12 @@ def sample_import_user_events(): ) # Send the request. - response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Wrap the response in an operation future. response = operation.from_gapic( @@ -823,16 +874,17 @@ def rejoin_user_events( timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> operation.Operation: - r"""Triggers a user event rejoin operation with latest + 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 API can be - used to trigger a 'join' operation on specified events + 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 wrong product - catalog. + used to correct events joined with the wrong product + catalog. A rejoin operation can take hours or days to + complete. .. code-block:: python @@ -896,7 +948,12 @@ def sample_rejoin_user_events(): ) # Send the request. - response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) # Wrap the response in an operation future. response = operation.from_gapic( @@ -925,7 +982,9 @@ def __exit__(self, type, value, traceback): try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution("google-cloud-retail",).version, + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, ) except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() diff --git a/google/cloud/retail_v2/services/user_event_service/transports/base.py b/google/cloud/retail_v2/services/user_event_service/transports/base.py index 4a9ab57d..e2d82e3b 100644 --- a/google/cloud/retail_v2/services/user_event_service/transports/base.py +++ b/google/cloud/retail_v2/services/user_event_service/transports/base.py @@ -35,7 +35,9 @@ try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution("google-cloud-retail",).version, + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, ) except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() @@ -125,10 +127,14 @@ def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { self.write_user_event: gapic_v1.method.wrap_method( - self.write_user_event, default_timeout=None, client_info=client_info, + self.write_user_event, + default_timeout=None, + client_info=client_info, ), self.collect_user_event: gapic_v1.method.wrap_method( - self.collect_user_event, default_timeout=None, client_info=client_info, + self.collect_user_event, + default_timeout=None, + client_info=client_info, ), self.purge_user_events: gapic_v1.method.wrap_method( self.purge_user_events, @@ -161,16 +167,18 @@ def _prep_wrapped_messages(self, client_info): client_info=client_info, ), self.rejoin_user_events: gapic_v1.method.wrap_method( - self.rejoin_user_events, default_timeout=None, client_info=client_info, + self.rejoin_user_events, + 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! + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! """ raise NotImplementedError() diff --git a/google/cloud/retail_v2/services/user_event_service/transports/grpc.py b/google/cloud/retail_v2/services/user_event_service/transports/grpc.py index 7c21df2b..a13a97d0 100644 --- a/google/cloud/retail_v2/services/user_event_service/transports/grpc.py +++ b/google/cloud/retail_v2/services/user_event_service/transports/grpc.py @@ -232,8 +232,7 @@ def create_channel( @property def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service. - """ + """Return the channel designed to connect to this service.""" return self._grpc_channel @property @@ -377,16 +376,17 @@ def rejoin_user_events( ]: r"""Return a callable for the rejoin user events method over gRPC. - Triggers a user event rejoin operation with latest + 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 API can be - used to trigger a 'join' operation on specified events + 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 wrong product - catalog. + used to correct events joined with the wrong product + catalog. A rejoin operation can take hours or days to + complete. Returns: Callable[[~.RejoinUserEventsRequest], diff --git a/google/cloud/retail_v2/services/user_event_service/transports/grpc_asyncio.py b/google/cloud/retail_v2/services/user_event_service/transports/grpc_asyncio.py index a64bf24f..5a42db6f 100644 --- a/google/cloud/retail_v2/services/user_event_service/transports/grpc_asyncio.py +++ b/google/cloud/retail_v2/services/user_event_service/transports/grpc_asyncio.py @@ -390,16 +390,17 @@ def rejoin_user_events( ]: r"""Return a callable for the rejoin user events method over gRPC. - Triggers a user event rejoin operation with latest + 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 API can be - used to trigger a 'join' operation on specified events + 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 wrong product - catalog. + used to correct events joined with the wrong product + catalog. A rejoin operation can take hours or days to + complete. Returns: Callable[[~.RejoinUserEventsRequest], diff --git a/google/cloud/retail_v2/types/__init__.py b/google/cloud/retail_v2/types/__init__.py index d6b44086..33da83a9 100644 --- a/google/cloud/retail_v2/types/__init__.py +++ b/google/cloud/retail_v2/types/__init__.py @@ -32,8 +32,8 @@ FulfillmentInfo, Image, Interval, + LocalInventory, PriceInfo, - Promotion, Rating, UserInfo, ) @@ -68,6 +68,9 @@ AddFulfillmentPlacesMetadata, AddFulfillmentPlacesRequest, AddFulfillmentPlacesResponse, + AddLocalInventoriesMetadata, + AddLocalInventoriesRequest, + AddLocalInventoriesResponse, CreateProductRequest, DeleteProductRequest, GetProductRequest, @@ -76,11 +79,15 @@ RemoveFulfillmentPlacesMetadata, RemoveFulfillmentPlacesRequest, RemoveFulfillmentPlacesResponse, + RemoveLocalInventoriesMetadata, + RemoveLocalInventoriesRequest, + RemoveLocalInventoriesResponse, SetInventoryMetadata, SetInventoryRequest, SetInventoryResponse, UpdateProductRequest, ) +from .promotion import Promotion from .purge_config import ( PurgeMetadata, PurgeUserEventsRequest, @@ -119,8 +126,8 @@ "FulfillmentInfo", "Image", "Interval", + "LocalInventory", "PriceInfo", - "Promotion", "Rating", "UserInfo", "CompleteQueryRequest", @@ -147,6 +154,9 @@ "AddFulfillmentPlacesMetadata", "AddFulfillmentPlacesRequest", "AddFulfillmentPlacesResponse", + "AddLocalInventoriesMetadata", + "AddLocalInventoriesRequest", + "AddLocalInventoriesResponse", "CreateProductRequest", "DeleteProductRequest", "GetProductRequest", @@ -155,10 +165,14 @@ "RemoveFulfillmentPlacesMetadata", "RemoveFulfillmentPlacesRequest", "RemoveFulfillmentPlacesResponse", + "RemoveLocalInventoriesMetadata", + "RemoveLocalInventoriesRequest", + "RemoveLocalInventoriesResponse", "SetInventoryMetadata", "SetInventoryRequest", "SetInventoryResponse", "UpdateProductRequest", + "Promotion", "PurgeMetadata", "PurgeUserEventsRequest", "PurgeUserEventsResponse", diff --git a/google/cloud/retail_v2/types/catalog.py b/google/cloud/retail_v2/types/catalog.py index 41e5bef6..0dad7cc3 100644 --- a/google/cloud/retail_v2/types/catalog.py +++ b/google/cloud/retail_v2/types/catalog.py @@ -17,7 +17,11 @@ __protobuf__ = proto.module( - package="google.cloud.retail.v2", manifest={"ProductLevelConfig", "Catalog",}, + package="google.cloud.retail.v2", + manifest={ + "ProductLevelConfig", + "Catalog", + }, ) @@ -81,8 +85,14 @@ class ProductLevelConfig(proto.Message): for more details. """ - ingestion_product_type = proto.Field(proto.STRING, number=1,) - merchant_center_product_id_field = proto.Field(proto.STRING, number=2,) + ingestion_product_type = proto.Field( + proto.STRING, + number=1, + ) + merchant_center_product_id_field = proto.Field( + proto.STRING, + number=2, + ) class Catalog(proto.Message): @@ -102,10 +112,18 @@ class Catalog(proto.Message): Required. The product level configuration. """ - name = proto.Field(proto.STRING, number=1,) - display_name = proto.Field(proto.STRING, number=2,) + name = proto.Field( + proto.STRING, + number=1, + ) + display_name = proto.Field( + proto.STRING, + number=2, + ) product_level_config = proto.Field( - proto.MESSAGE, number=4, message="ProductLevelConfig", + proto.MESSAGE, + number=4, + message="ProductLevelConfig", ) diff --git a/google/cloud/retail_v2/types/catalog_service.py b/google/cloud/retail_v2/types/catalog_service.py index 740bc31a..c7475dc3 100644 --- a/google/cloud/retail_v2/types/catalog_service.py +++ b/google/cloud/retail_v2/types/catalog_service.py @@ -67,9 +67,18 @@ class ListCatalogsRequest(proto.Message): an INVALID_ARGUMENT error is returned. """ - parent = proto.Field(proto.STRING, number=1,) - page_size = proto.Field(proto.INT32, number=2,) - page_token = proto.Field(proto.STRING, number=3,) + parent = proto.Field( + proto.STRING, + number=1, + ) + page_size = proto.Field( + proto.INT32, + number=2, + ) + page_token = proto.Field( + proto.STRING, + number=3, + ) class ListCatalogsResponse(proto.Message): @@ -93,9 +102,14 @@ def raw_page(self): return self catalogs = proto.RepeatedField( - proto.MESSAGE, number=1, message=gcr_catalog.Catalog, + proto.MESSAGE, + number=1, + message=gcr_catalog.Catalog, + ) + next_page_token = proto.Field( + proto.STRING, + number=2, ) - next_page_token = proto.Field(proto.STRING, number=2,) class UpdateCatalogRequest(proto.Message): @@ -123,9 +137,15 @@ class UpdateCatalogRequest(proto.Message): INVALID_ARGUMENT error is returned. """ - catalog = proto.Field(proto.MESSAGE, number=1, message=gcr_catalog.Catalog,) + catalog = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_catalog.Catalog, + ) update_mask = proto.Field( - proto.MESSAGE, number=2, message=field_mask_pb2.FieldMask, + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, ) @@ -141,6 +161,11 @@ class SetDefaultBranchRequest(proto.Message): This field must be one of "0", "1" or "2". Otherwise, an INVALID_ARGUMENT error is returned. + + If there are no sufficient active products in the targeted + branch and + [force][google.cloud.retail.v2.SetDefaultBranchRequest.force] + is not set, a FAILED_PRECONDITION error is returned. note (str): Some note on this request, this can be retrieved by [CatalogService.GetDefaultBranch][google.cloud.retail.v2.CatalogService.GetDefaultBranch] @@ -149,11 +174,28 @@ class SetDefaultBranchRequest(proto.Message): This field must be a UTF-8 encoded string with a length limit of 1,000 characters. Otherwise, an INVALID_ARGUMENT error is returned. + force (bool): + If set to true, it permits switching to a branch with + [branch_id][google.cloud.retail.v2.SetDefaultBranchRequest.branch_id] + even if it has no sufficient active products. """ - catalog = proto.Field(proto.STRING, number=1,) - branch_id = proto.Field(proto.STRING, number=2,) - note = proto.Field(proto.STRING, number=3,) + catalog = proto.Field( + proto.STRING, + number=1, + ) + branch_id = proto.Field( + proto.STRING, + number=2, + ) + note = proto.Field( + proto.STRING, + number=3, + ) + force = proto.Field( + proto.BOOL, + number=4, + ) class GetDefaultBranchRequest(proto.Message): @@ -166,7 +208,10 @@ class GetDefaultBranchRequest(proto.Message): ``projects/*/locations/global/catalogs/default_catalog``. """ - catalog = proto.Field(proto.STRING, number=1,) + catalog = proto.Field( + proto.STRING, + number=1, + ) class GetDefaultBranchResponse(proto.Message): @@ -185,9 +230,19 @@ class GetDefaultBranchResponse(proto.Message): field, when this branch was set as default. """ - branch = proto.Field(proto.STRING, number=1,) - set_time = proto.Field(proto.MESSAGE, number=2, message=timestamp_pb2.Timestamp,) - note = proto.Field(proto.STRING, number=3,) + branch = proto.Field( + proto.STRING, + number=1, + ) + set_time = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + note = proto.Field( + proto.STRING, + number=3, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/retail_v2/types/common.py b/google/cloud/retail_v2/types/common.py index cecf1ce2..1f66ac42 100644 --- a/google/cloud/retail_v2/types/common.py +++ b/google/cloud/retail_v2/types/common.py @@ -30,7 +30,7 @@ "PriceInfo", "Rating", "UserInfo", - "Promotion", + "LocalInventory", }, ) @@ -70,8 +70,14 @@ class Audience(proto.Message): `Product.audience.suggestedMaxAge `__. """ - genders = proto.RepeatedField(proto.STRING, number=1,) - age_groups = proto.RepeatedField(proto.STRING, number=2,) + genders = proto.RepeatedField( + proto.STRING, + number=1, + ) + age_groups = proto.RepeatedField( + proto.STRING, + number=2, + ) class ColorInfo(proto.Message): @@ -112,8 +118,14 @@ class ColorInfo(proto.Message): `Product.color `__. """ - color_families = proto.RepeatedField(proto.STRING, number=1,) - colors = proto.RepeatedField(proto.STRING, number=2,) + color_families = proto.RepeatedField( + proto.STRING, + number=1, + ) + colors = proto.RepeatedField( + proto.STRING, + number=2, + ) class CustomAttribute(proto.Message): @@ -125,10 +137,8 @@ class CustomAttribute(proto.Message): The textual values of this custom attribute. For example, ``["yellow", "green"]`` when the key is "color". - At most 400 values are allowed. Empty values are not - allowed. Each value must be a UTF-8 encoded string with a - length limit of 256 characters. Otherwise, an - INVALID_ARGUMENT error is returned. + Empty string is not allowed. Otherwise, an INVALID_ARGUMENT + error is returned. Exactly one of [text][google.cloud.retail.v2.CustomAttribute.text] or @@ -139,17 +149,17 @@ class CustomAttribute(proto.Message): The numerical values of this custom attribute. For example, ``[2.3, 15.4]`` when the key is "lengths_cm". - At most 400 values are allowed.Otherwise, an - INVALID_ARGUMENT error is returned. - Exactly one of [text][google.cloud.retail.v2.CustomAttribute.text] or [numbers][google.cloud.retail.v2.CustomAttribute.numbers] should be set. Otherwise, an INVALID_ARGUMENT error is returned. searchable (bool): - If true, custom attribute values are searchable by text - queries in + This field will only be used when + [AttributesConfig.attribute_config_level][] of the + [Catalog][google.cloud.retail.v2.Catalog] is + 'PRODUCT_LEVEL_ATTRIBUTE_CONFIG', if true, custom attribute + values are searchable by text queries in [SearchService.Search][google.cloud.retail.v2.SearchService.Search]. This field is ignored in a @@ -161,8 +171,12 @@ class CustomAttribute(proto.Message): This field is a member of `oneof`_ ``_searchable``. indexable (bool): - If true, custom attribute values are indexed, so that it can - be filtered, faceted or boosted in + This field will only be used when + [AttributesConfig.attribute_config_level][] of the + [Catalog][google.cloud.retail.v2.Catalog] is + 'PRODUCT_LEVEL_ATTRIBUTE_CONFIG', if true, custom attribute + values are indexed, so that it can be filtered, faceted or + boosted in [SearchService.Search][google.cloud.retail.v2.SearchService.Search]. This field is ignored in a @@ -178,10 +192,24 @@ class CustomAttribute(proto.Message): This field is a member of `oneof`_ ``_indexable``. """ - text = proto.RepeatedField(proto.STRING, number=1,) - numbers = proto.RepeatedField(proto.DOUBLE, number=2,) - searchable = proto.Field(proto.BOOL, number=3, optional=True,) - indexable = proto.Field(proto.BOOL, number=4, optional=True,) + text = proto.RepeatedField( + proto.STRING, + number=1, + ) + numbers = proto.RepeatedField( + proto.DOUBLE, + number=2, + ) + searchable = proto.Field( + proto.BOOL, + number=3, + optional=True, + ) + indexable = proto.Field( + proto.BOOL, + number=4, + optional=True, + ) class FulfillmentInfo(proto.Message): @@ -223,12 +251,22 @@ class FulfillmentInfo(proto.Message): Otherwise, an INVALID_ARGUMENT error is returned. """ - type_ = proto.Field(proto.STRING, number=1,) - place_ids = proto.RepeatedField(proto.STRING, number=2,) + type_ = proto.Field( + proto.STRING, + number=1, + ) + place_ids = proto.RepeatedField( + proto.STRING, + number=2, + ) class Image(proto.Message): - r"""[Product][google.cloud.retail.v2.Product] thumbnail/detail image. + r"""[Product][google.cloud.retail.v2.Product] image. Recommendations AI + and Retail Search do not use product images to improve prediction + and search results. However, product images can be returned in + results, and are shown in prediction or search previews in the + console. Attributes: uri (str): @@ -254,9 +292,18 @@ class Image(proto.Message): INVALID_ARGUMENT error is returned. """ - uri = proto.Field(proto.STRING, number=1,) - height = proto.Field(proto.INT32, number=2,) - width = proto.Field(proto.INT32, number=3,) + uri = proto.Field( + proto.STRING, + number=1, + ) + height = proto.Field( + proto.INT32, + number=2, + ) + width = proto.Field( + proto.INT32, + number=3, + ) class Interval(proto.Message): @@ -288,10 +335,26 @@ class Interval(proto.Message): This field is a member of `oneof`_ ``max``. """ - minimum = proto.Field(proto.DOUBLE, number=1, oneof="min",) - exclusive_minimum = proto.Field(proto.DOUBLE, number=2, oneof="min",) - maximum = proto.Field(proto.DOUBLE, number=3, oneof="max",) - exclusive_maximum = proto.Field(proto.DOUBLE, number=4, oneof="max",) + minimum = proto.Field( + proto.DOUBLE, + number=1, + oneof="min", + ) + exclusive_minimum = proto.Field( + proto.DOUBLE, + number=2, + oneof="min", + ) + maximum = proto.Field( + proto.DOUBLE, + number=3, + oneof="max", + ) + exclusive_maximum = proto.Field( + proto.DOUBLE, + number=4, + oneof="max", + ) class PriceInfo(proto.Message): @@ -319,7 +382,7 @@ class PriceInfo(proto.Message): Google Merchant Center property `price `__. Schema.org property - `Offer.priceSpecification `__. + `Offer.price `__. original_price (float): Price of the product without any discount. If zero, by default set to be the @@ -408,20 +471,48 @@ class PriceRange(proto.Message): [Product.primary_product_id][google.cloud.retail.v2.Product.primary_product_id]. """ - price = proto.Field(proto.MESSAGE, number=1, message="Interval",) - original_price = proto.Field(proto.MESSAGE, number=2, message="Interval",) - - currency_code = proto.Field(proto.STRING, number=1,) - price = proto.Field(proto.FLOAT, number=2,) - original_price = proto.Field(proto.FLOAT, number=3,) - cost = proto.Field(proto.FLOAT, number=4,) + price = proto.Field( + proto.MESSAGE, + number=1, + message="Interval", + ) + original_price = proto.Field( + proto.MESSAGE, + number=2, + message="Interval", + ) + + currency_code = proto.Field( + proto.STRING, + number=1, + ) + price = proto.Field( + proto.FLOAT, + number=2, + ) + original_price = proto.Field( + proto.FLOAT, + number=3, + ) + cost = proto.Field( + proto.FLOAT, + number=4, + ) price_effective_time = proto.Field( - proto.MESSAGE, number=5, message=timestamp_pb2.Timestamp, + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, ) price_expire_time = proto.Field( - proto.MESSAGE, number=6, message=timestamp_pb2.Timestamp, + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + price_range = proto.Field( + proto.MESSAGE, + number=7, + message=PriceRange, ) - price_range = proto.Field(proto.MESSAGE, number=7, message=PriceRange,) class Rating(proto.Message): @@ -452,9 +543,18 @@ class Rating(proto.Message): with 1 star, 14 ratings with 2 star, and so on. """ - rating_count = proto.Field(proto.INT32, number=1,) - average_rating = proto.Field(proto.FLOAT, number=2,) - rating_histogram = proto.RepeatedField(proto.INT32, number=3,) + rating_count = proto.Field( + proto.INT32, + number=1, + ) + average_rating = proto.Field( + proto.FLOAT, + number=2, + ) + rating_histogram = proto.RepeatedField( + proto.INT32, + number=3, + ) class UserInfo(proto.Message): @@ -465,25 +565,29 @@ class UserInfo(proto.Message): Highly recommended for logged-in users. Unique identifier for logged-in user, such as a user name. + Always use a hashed value for this ID. + The field must be a UTF-8 encoded string with a length limit of 128 characters. Otherwise, an INVALID_ARGUMENT error is returned. ip_address (str): - The end user's IP address. Required for getting - [SearchResponse.sponsored_results][google.cloud.retail.v2.SearchResponse.sponsored_results]. - This field is used to extract location information for - personalization. + The end user's IP address. This field is used to extract + location information for personalization. This field must be either an IPv4 address (e.g. "104.133.9.80") or an IPv6 address (e.g. "2001:0db8:85a3:0000:0000:8a2e:0370:7334"). Otherwise, an INVALID_ARGUMENT error is returned. - This should not be set when using the JavaScript tag in - [UserEventService.CollectUserEvent][google.cloud.retail.v2.UserEventService.CollectUserEvent] - or if - [direct_user_request][google.cloud.retail.v2.UserInfo.direct_user_request] - is set. + This should not be set when: + + - setting + [SearchRequest.user_info][google.cloud.retail.v2.SearchRequest.user_info]. + - using the JavaScript tag in + [UserEventService.CollectUserEvent][google.cloud.retail.v2.UserEventService.CollectUserEvent] + or if + [direct_user_request][google.cloud.retail.v2.UserInfo.direct_user_request] + is set. user_agent (str): User agent as included in the HTTP header. Required for getting @@ -513,30 +617,104 @@ class UserInfo(proto.Message): [UserEventService.CollectUserEvent][google.cloud.retail.v2.UserEventService.CollectUserEvent]. """ - user_id = proto.Field(proto.STRING, number=1,) - ip_address = proto.Field(proto.STRING, number=2,) - user_agent = proto.Field(proto.STRING, number=3,) - direct_user_request = proto.Field(proto.BOOL, number=4,) + user_id = proto.Field( + proto.STRING, + number=1, + ) + ip_address = proto.Field( + proto.STRING, + number=2, + ) + user_agent = proto.Field( + proto.STRING, + number=3, + ) + direct_user_request = proto.Field( + proto.BOOL, + number=4, + ) -class Promotion(proto.Message): - r"""Promotion information. +class LocalInventory(proto.Message): + r"""The inventory information at a place (e.g. a store) + identified by a place ID. Attributes: - promotion_id (str): - ID of the promotion. For example, "free gift". - - The value value must be a UTF-8 encoded string with a length - limit of 128 characters, and match the pattern: - ``[a-zA-Z][a-zA-Z0-9_]*``. For example, id0LikeThis or - ID_1_LIKE_THIS. Otherwise, an INVALID_ARGUMENT error is - returned. + place_id (str): + The place ID for the current set of inventory + information. + price_info (google.cloud.retail_v2.types.PriceInfo): + Product price and cost information. Google Merchant Center property - `promotion `__. + `price `__. + attributes (Sequence[google.cloud.retail_v2.types.LocalInventory.AttributesEntry]): + Additional local inventory attributes, for example, store + name, promotion tags, etc. + + This field needs to pass all below criteria, otherwise an + INVALID_ARGUMENT error is returned: + + - At most 30 attributes are allowed. + - The key must be a UTF-8 encoded string with a length + limit of 32 characters. + - The key must match the pattern: + ``[a-zA-Z0-9][a-zA-Z0-9_]*``. For example, key0LikeThis + or KEY_1_LIKE_THIS. + - The attribute values must be of the same type (text or + number). + - Only 1 value is allowed for each attribute. + - For text values, the length limit is 256 UTF-8 + characters. + - The attribute does not support search. The ``searchable`` + field should be unset or set to false. + - The max summed total bytes of custom attribute keys and + values per product is 5MiB. + fulfillment_types (Sequence[str]): + Input only. Supported fulfillment types. Valid fulfillment + type values include commonly used types (such as pickup in + store and same day delivery), and custom types. Customers + have to map custom types to their display names before + rendering UI. + + Supported values: + + - "pickup-in-store" + - "ship-to-store" + - "same-day-delivery" + - "next-day-delivery" + - "custom-type-1" + - "custom-type-2" + - "custom-type-3" + - "custom-type-4" + - "custom-type-5" + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + + All the elements must be distinct. Otherwise, an + INVALID_ARGUMENT error is returned. """ - promotion_id = proto.Field(proto.STRING, number=1,) + place_id = proto.Field( + proto.STRING, + number=1, + ) + price_info = proto.Field( + proto.MESSAGE, + number=2, + message="PriceInfo", + ) + attributes = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=3, + message="CustomAttribute", + ) + fulfillment_types = proto.RepeatedField( + proto.STRING, + number=4, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/retail_v2/types/completion_service.py b/google/cloud/retail_v2/types/completion_service.py index dbb72af5..bdb2a395 100644 --- a/google/cloud/retail_v2/types/completion_service.py +++ b/google/cloud/retail_v2/types/completion_service.py @@ -20,7 +20,10 @@ __protobuf__ = proto.module( package="google.cloud.retail.v2", - manifest={"CompleteQueryRequest", "CompleteQueryResponse",}, + manifest={ + "CompleteQueryRequest", + "CompleteQueryResponse", + }, ) @@ -38,23 +41,24 @@ class CompleteQueryRequest(proto.Message): suggestions. The maximum number of allowed characters is 255. visitor_id (str): - A unique identifier for tracking visitors. For example, this - could be implemented with an HTTP cookie, which should be - able to uniquely identify a visitor on a single device. This - unique identifier should not change if the visitor logs in - or out of the website. + Required field. A unique identifier for tracking visitors. + For example, this could be implemented with an HTTP cookie, + which should be able to uniquely identify a visitor on a + single device. This unique identifier should not change if + the visitor logs in or out of the website. The field must be a UTF-8 encoded string with a length limit of 128 characters. Otherwise, an INVALID_ARGUMENT error is returned. language_codes (Sequence[str]): - The list of languages of the query. This is the BCP-47 - language code, such as "en-US" or "sr-Latn". For more - information, see `Tags for Identifying - Languages `__. - - The maximum number of allowed characters is 255. Only - "en-US" is currently supported. + The language filters applied to the output suggestions. If + set, it should contain the language of the query. If not + set, suggestions are returned without considering language + restrictions. This is the BCP-47 language code, such as + "en-US" or "sr-Latn". For more information, see `Tags for + Identifying + Languages `__. The + maximum number of language codes is 3. device_type (str): The device type context for completion suggestions. It is useful to apply different suggestions on different device @@ -95,13 +99,34 @@ class CompleteQueryRequest(proto.Message): higher, it will be capped by 20. """ - catalog = proto.Field(proto.STRING, number=1,) - query = proto.Field(proto.STRING, number=2,) - visitor_id = proto.Field(proto.STRING, number=7,) - language_codes = proto.RepeatedField(proto.STRING, number=3,) - device_type = proto.Field(proto.STRING, number=4,) - dataset = proto.Field(proto.STRING, number=6,) - max_suggestions = proto.Field(proto.INT32, number=5,) + catalog = proto.Field( + proto.STRING, + number=1, + ) + query = proto.Field( + proto.STRING, + number=2, + ) + visitor_id = proto.Field( + proto.STRING, + number=7, + ) + language_codes = proto.RepeatedField( + proto.STRING, + number=3, + ) + device_type = proto.Field( + proto.STRING, + number=4, + ) + dataset = proto.Field( + proto.STRING, + number=6, + ) + max_suggestions = proto.Field( + proto.INT32, + number=5, + ) class CompleteQueryResponse(proto.Message): @@ -114,9 +139,9 @@ class CompleteQueryResponse(proto.Message): top suggestion. attribution_token (str): A unique complete token. This should be included in the - [SearchRequest][google.cloud.retail.v2.SearchRequest] - resulting from this completion, which enables accurate - attribution of complete model performance. + [UserEvent.completion_detail][google.cloud.retail.v2.UserEvent.completion_detail] + for search events resulting from this completion, which + enables accurate attribution of complete model performance. recent_search_results (Sequence[google.cloud.retail_v2.types.CompleteQueryResponse.RecentSearchResult]): Matched recent searches of this user. The maximum number of recent searches is 10. This field is a restricted feature. @@ -147,13 +172,23 @@ class CompletionResult(proto.Message): suggestion (str): The suggestion for the query. attributes (Sequence[google.cloud.retail_v2.types.CompleteQueryResponse.CompletionResult.AttributesEntry]): - Additional custom attributes ingested through - BigQuery. + Custom attributes for the suggestion term. + + - For "user-data", the attributes are additional custom + attributes ingested through BigQuery. + - For "cloud-retail", the attributes are product attributes + generated by Cloud Retail. """ - suggestion = proto.Field(proto.STRING, number=1,) + suggestion = proto.Field( + proto.STRING, + number=1, + ) attributes = proto.MapField( - proto.STRING, proto.MESSAGE, number=2, message=common.CustomAttribute, + proto.STRING, + proto.MESSAGE, + number=2, + message=common.CustomAttribute, ) class RecentSearchResult(proto.Message): @@ -164,14 +199,24 @@ class RecentSearchResult(proto.Message): The recent search query. """ - recent_search = proto.Field(proto.STRING, number=1,) + recent_search = proto.Field( + proto.STRING, + number=1, + ) completion_results = proto.RepeatedField( - proto.MESSAGE, number=1, message=CompletionResult, + proto.MESSAGE, + number=1, + message=CompletionResult, + ) + attribution_token = proto.Field( + proto.STRING, + number=2, ) - attribution_token = proto.Field(proto.STRING, number=2,) recent_search_results = proto.RepeatedField( - proto.MESSAGE, number=3, message=RecentSearchResult, + proto.MESSAGE, + number=3, + message=RecentSearchResult, ) diff --git a/google/cloud/retail_v2/types/import_config.py b/google/cloud/retail_v2/types/import_config.py index 9df2928e..cda3078a 100644 --- a/google/cloud/retail_v2/types/import_config.py +++ b/google/cloud/retail_v2/types/import_config.py @@ -80,10 +80,25 @@ class GcsSource(proto.Message): [UserEvent][google.cloud.retail.v2.UserEvent] per line. - ``user_event_ga360``: Using https://support.google.com/analytics/answer/3437719. + + Supported values for control imports: + + - 'control' (default): One JSON [Control][] per line. + + Supported values for catalog attribute imports: + + - 'catalog_attribute' (default): One CSV + [CatalogAttribute][] per line. """ - input_uris = proto.RepeatedField(proto.STRING, number=1,) - data_schema = proto.Field(proto.STRING, number=2,) + input_uris = proto.RepeatedField( + proto.STRING, + number=1, + ) + data_schema = proto.Field( + proto.STRING, + number=2, + ) class BigQuerySource(proto.Message): @@ -136,18 +151,47 @@ class BigQuerySource(proto.Message): - ``user_event`` (default): One JSON [UserEvent][google.cloud.retail.v2.UserEvent] per line. - - ``user_event_ga360``: Using + - ``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: + https://support.google.com/analytics/answer/7029846. + + Supported values for auto-completion imports: + + - ``suggestions`` (default): One JSON completion suggestion + per line. + - ``denylist``: One JSON deny suggestion per line. + - ``allowlist``: One JSON allow suggestion per line. """ partition_date = proto.Field( - proto.MESSAGE, number=6, oneof="partition", message=date_pb2.Date, + proto.MESSAGE, + number=6, + oneof="partition", + message=date_pb2.Date, + ) + project_id = proto.Field( + proto.STRING, + number=5, + ) + dataset_id = proto.Field( + proto.STRING, + number=1, + ) + table_id = proto.Field( + proto.STRING, + number=2, + ) + gcs_staging_dir = proto.Field( + proto.STRING, + number=3, + ) + data_schema = proto.Field( + proto.STRING, + number=4, ) - project_id = proto.Field(proto.STRING, number=5,) - dataset_id = proto.Field(proto.STRING, number=1,) - table_id = proto.Field(proto.STRING, number=2,) - gcs_staging_dir = proto.Field(proto.STRING, number=3,) - data_schema = proto.Field(proto.STRING, number=4,) class ProductInlineSource(proto.Message): @@ -162,7 +206,11 @@ class ProductInlineSource(proto.Message): max of 100 items. """ - products = proto.RepeatedField(proto.MESSAGE, number=1, message=product.Product,) + products = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=product.Product, + ) class UserEventInlineSource(proto.Message): @@ -176,7 +224,9 @@ class UserEventInlineSource(proto.Message): """ user_events = proto.RepeatedField( - proto.MESSAGE, number=1, message=user_event.UserEvent, + proto.MESSAGE, + number=1, + message=user_event.UserEvent, ) @@ -187,15 +237,19 @@ class ImportErrorsConfig(proto.Message): Attributes: gcs_prefix (str): - Google Cloud Storage path for import errors. This must be an - empty, existing Cloud Storage bucket. Import errors will be - written to a file in this bucket, one per line, as a - JSON-encoded ``google.rpc.Status`` message. + 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 + line, as a JSON-encoded ``google.rpc.Status`` message. This field is a member of `oneof`_ ``destination``. """ - gcs_prefix = proto.Field(proto.STRING, number=1, oneof="destination",) + gcs_prefix = proto.Field( + proto.STRING, + number=1, + oneof="destination", + ) class ImportProductsRequest(proto.Message): @@ -210,16 +264,7 @@ class ImportProductsRequest(proto.Message): permission. If updateMask is specified, requires products.update permission. request_id (str): - Unique identifier provided by client, within the ancestor - dataset scope. Ensures idempotency and used for request - deduplication. Server-generated if unspecified. Up to 128 - characters long and must match the pattern: - ``[a-zA-Z0-9_]+``. This is returned as [Operation.name][] in - [ImportMetadata][google.cloud.retail.v2.ImportMetadata]. - - Only supported when - [ImportProductsRequest.reconciliation_mode][google.cloud.retail.v2.ImportProductsRequest.reconciliation_mode] - is set to ``FULL``. + Deprecated. This field has no effect. input_config (google.cloud.retail_v2.types.ProductInputConfig): Required. The desired input location of the data. @@ -255,15 +300,38 @@ class ReconciliationMode(proto.Enum): INCREMENTAL = 1 FULL = 2 - parent = proto.Field(proto.STRING, number=1,) - request_id = proto.Field(proto.STRING, number=6,) - input_config = proto.Field(proto.MESSAGE, number=2, message="ProductInputConfig",) - errors_config = proto.Field(proto.MESSAGE, number=3, message="ImportErrorsConfig",) + parent = proto.Field( + proto.STRING, + number=1, + ) + request_id = proto.Field( + proto.STRING, + number=6, + ) + input_config = proto.Field( + proto.MESSAGE, + number=2, + message="ProductInputConfig", + ) + errors_config = proto.Field( + proto.MESSAGE, + number=3, + message="ImportErrorsConfig", + ) update_mask = proto.Field( - proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + proto.MESSAGE, + number=4, + message=field_mask_pb2.FieldMask, + ) + reconciliation_mode = proto.Field( + proto.ENUM, + number=5, + enum=ReconciliationMode, + ) + notification_pubsub_topic = proto.Field( + proto.STRING, + number=7, ) - reconciliation_mode = proto.Field(proto.ENUM, number=5, enum=ReconciliationMode,) - notification_pubsub_topic = proto.Field(proto.STRING, number=7,) class ImportUserEventsRequest(proto.Message): @@ -282,9 +350,20 @@ class ImportUserEventsRequest(proto.Message): event imports. """ - parent = proto.Field(proto.STRING, number=1,) - input_config = proto.Field(proto.MESSAGE, number=2, message="UserEventInputConfig",) - errors_config = proto.Field(proto.MESSAGE, number=3, message="ImportErrorsConfig",) + parent = proto.Field( + proto.STRING, + number=1, + ) + input_config = proto.Field( + proto.MESSAGE, + number=2, + message="UserEventInputConfig", + ) + errors_config = proto.Field( + proto.MESSAGE, + number=3, + message="ImportErrorsConfig", + ) class ImportCompletionDataRequest(proto.Message): @@ -309,11 +388,19 @@ class ImportCompletionDataRequest(proto.Message): ``projects/{project}/topics/{topic}``. """ - parent = proto.Field(proto.STRING, number=1,) + parent = proto.Field( + proto.STRING, + number=1, + ) input_config = proto.Field( - proto.MESSAGE, number=2, message="CompletionDataInputConfig", + proto.MESSAGE, + number=2, + message="CompletionDataInputConfig", + ) + notification_pubsub_topic = proto.Field( + proto.STRING, + number=3, ) - notification_pubsub_topic = proto.Field(proto.STRING, number=3,) class ProductInputConfig(proto.Message): @@ -344,13 +431,22 @@ class ProductInputConfig(proto.Message): """ product_inline_source = proto.Field( - proto.MESSAGE, number=1, oneof="source", message="ProductInlineSource", + proto.MESSAGE, + number=1, + oneof="source", + message="ProductInlineSource", ) gcs_source = proto.Field( - proto.MESSAGE, number=2, oneof="source", message="GcsSource", + proto.MESSAGE, + number=2, + oneof="source", + message="GcsSource", ) big_query_source = proto.Field( - proto.MESSAGE, number=3, oneof="source", message="BigQuerySource", + proto.MESSAGE, + number=3, + oneof="source", + message="BigQuerySource", ) @@ -382,13 +478,22 @@ class UserEventInputConfig(proto.Message): """ user_event_inline_source = proto.Field( - proto.MESSAGE, number=1, oneof="source", message="UserEventInlineSource", + proto.MESSAGE, + number=1, + oneof="source", + message="UserEventInlineSource", ) gcs_source = proto.Field( - proto.MESSAGE, number=2, oneof="source", message="GcsSource", + proto.MESSAGE, + number=2, + oneof="source", + message="GcsSource", ) big_query_source = proto.Field( - proto.MESSAGE, number=3, oneof="source", message="BigQuerySource", + proto.MESSAGE, + number=3, + oneof="source", + message="BigQuerySource", ) @@ -410,7 +515,10 @@ class CompletionDataInputConfig(proto.Message): """ big_query_source = proto.Field( - proto.MESSAGE, number=1, oneof="source", message="BigQuerySource", + proto.MESSAGE, + number=1, + oneof="source", + message="BigQuerySource", ) @@ -432,9 +540,7 @@ class ImportMetadata(proto.Message): Count of entries that encountered errors while processing. request_id (str): - Id of the request / operation. This is - parroting back the requestId that was passed in - the request. + 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 @@ -444,12 +550,32 @@ class ImportMetadata(proto.Message): ``projects/{project}/topics/{topic}``. """ - create_time = proto.Field(proto.MESSAGE, number=1, message=timestamp_pb2.Timestamp,) - update_time = proto.Field(proto.MESSAGE, number=2, message=timestamp_pb2.Timestamp,) - success_count = proto.Field(proto.INT64, number=3,) - failure_count = proto.Field(proto.INT64, number=4,) - request_id = proto.Field(proto.STRING, number=5,) - notification_pubsub_topic = proto.Field(proto.STRING, number=6,) + create_time = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + update_time = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + success_count = proto.Field( + proto.INT64, + number=3, + ) + failure_count = proto.Field( + proto.INT64, + number=4, + ) + request_id = proto.Field( + proto.STRING, + number=5, + ) + notification_pubsub_topic = proto.Field( + proto.STRING, + number=6, + ) class ImportProductsResponse(proto.Message): @@ -469,9 +595,15 @@ class ImportProductsResponse(proto.Message): """ error_samples = proto.RepeatedField( - proto.MESSAGE, number=1, message=status_pb2.Status, + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + errors_config = proto.Field( + proto.MESSAGE, + number=2, + message="ImportErrorsConfig", ) - errors_config = proto.Field(proto.MESSAGE, number=2, message="ImportErrorsConfig",) class ImportUserEventsResponse(proto.Message): @@ -493,11 +625,19 @@ class ImportUserEventsResponse(proto.Message): """ error_samples = proto.RepeatedField( - proto.MESSAGE, number=1, message=status_pb2.Status, + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + errors_config = proto.Field( + proto.MESSAGE, + number=2, + message="ImportErrorsConfig", ) - errors_config = proto.Field(proto.MESSAGE, number=2, message="ImportErrorsConfig",) import_summary = proto.Field( - proto.MESSAGE, number=3, message="UserEventImportSummary", + proto.MESSAGE, + number=3, + message="UserEventImportSummary", ) @@ -515,8 +655,14 @@ class UserEventImportSummary(proto.Message): catalog. """ - joined_events_count = proto.Field(proto.INT64, number=1,) - unjoined_events_count = proto.Field(proto.INT64, number=2,) + joined_events_count = proto.Field( + proto.INT64, + number=1, + ) + unjoined_events_count = proto.Field( + proto.INT64, + number=2, + ) class ImportCompletionDataResponse(proto.Message): @@ -533,7 +679,9 @@ class ImportCompletionDataResponse(proto.Message): """ error_samples = proto.RepeatedField( - proto.MESSAGE, number=1, message=status_pb2.Status, + proto.MESSAGE, + number=1, + message=status_pb2.Status, ) diff --git a/google/cloud/retail_v2/types/prediction_service.py b/google/cloud/retail_v2/types/prediction_service.py index d220a14f..06676589 100644 --- a/google/cloud/retail_v2/types/prediction_service.py +++ b/google/cloud/retail_v2/types/prediction_service.py @@ -20,7 +20,11 @@ __protobuf__ = proto.module( - package="google.cloud.retail.v2", manifest={"PredictRequest", "PredictResponse",}, + package="google.cloud.retail.v2", + manifest={ + "PredictRequest", + "PredictResponse", + }, ) @@ -81,10 +85,13 @@ class PredictRequest(proto.Message): - filterOutOfStockItems tag=(-"promotional") - filterOutOfStockItems - If your filter blocks all prediction results, nothing will - be returned. If you want generic (unfiltered) popular - products to be returned instead, set ``strictFiltering`` to - false in ``PredictRequest.params``. + If your filter blocks all prediction results, the API will + return generic (unfiltered) popular products. If you only + want results strictly matching the filters, set + ``strictFiltering`` to True in ``PredictRequest.params`` to + receive empty results instead. Note that the API will never + return items with storageStatus of "EXPIRED" or "DELETED" + regardless of filter choices. validate_only (bool): Use validate only mode for this prediction query. If set to true, a dummy model will be @@ -144,16 +151,42 @@ class PredictRequest(proto.Message): for more details. """ - placement = proto.Field(proto.STRING, number=1,) - user_event = proto.Field(proto.MESSAGE, number=2, message=gcr_user_event.UserEvent,) - page_size = proto.Field(proto.INT32, number=3,) - page_token = proto.Field(proto.STRING, number=4,) - filter = proto.Field(proto.STRING, number=5,) - validate_only = proto.Field(proto.BOOL, number=6,) + placement = proto.Field( + proto.STRING, + number=1, + ) + user_event = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_user_event.UserEvent, + ) + page_size = proto.Field( + proto.INT32, + number=3, + ) + page_token = proto.Field( + proto.STRING, + number=4, + ) + filter = proto.Field( + proto.STRING, + number=5, + ) + validate_only = proto.Field( + proto.BOOL, + number=6, + ) params = proto.MapField( - proto.STRING, proto.MESSAGE, number=7, message=struct_pb2.Value, + proto.STRING, + proto.MESSAGE, + number=7, + message=struct_pb2.Value, + ) + labels = proto.MapField( + proto.STRING, + proto.STRING, + number=8, ) - labels = proto.MapField(proto.STRING, proto.STRING, number=8,) class PredictResponse(proto.Message): @@ -197,15 +230,34 @@ class PredictionResult(proto.Message): ``PredictRequest.params``. """ - id = proto.Field(proto.STRING, number=1,) + id = proto.Field( + proto.STRING, + number=1, + ) metadata = proto.MapField( - proto.STRING, proto.MESSAGE, number=2, message=struct_pb2.Value, + proto.STRING, + proto.MESSAGE, + number=2, + message=struct_pb2.Value, ) - results = proto.RepeatedField(proto.MESSAGE, number=1, message=PredictionResult,) - attribution_token = proto.Field(proto.STRING, number=2,) - missing_ids = proto.RepeatedField(proto.STRING, number=3,) - validate_only = proto.Field(proto.BOOL, number=4,) + results = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=PredictionResult, + ) + attribution_token = proto.Field( + proto.STRING, + number=2, + ) + missing_ids = proto.RepeatedField( + proto.STRING, + number=3, + ) + validate_only = proto.Field( + proto.BOOL, + number=4, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/retail_v2/types/product.py b/google/cloud/retail_v2/types/product.py index ca8586c7..86eb75c7 100644 --- a/google/cloud/retail_v2/types/product.py +++ b/google/cloud/retail_v2/types/product.py @@ -16,13 +16,19 @@ import proto # type: ignore from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import promotion from google.protobuf import duration_pb2 # type: ignore from google.protobuf import field_mask_pb2 # type: ignore from google.protobuf import timestamp_pb2 # type: ignore from google.protobuf import wrappers_pb2 # type: ignore -__protobuf__ = proto.module(package="google.cloud.retail.v2", manifest={"Product",},) +__protobuf__ = proto.module( + package="google.cloud.retail.v2", + manifest={ + "Product", + }, +) class Product(proto.Message): @@ -58,7 +64,7 @@ class Product(proto.Message): [publish_time][google.cloud.retail.v2.Product.publish_time], otherwise an INVALID_ARGUMENT error is thrown. - Google Merchant Center property + Corresponding properties: Google Merchant Center property `expiration_date `__. This field is a member of `oneof`_ ``expiration``. @@ -99,9 +105,9 @@ class Product(proto.Message): limit of 128 characters. Otherwise, an INVALID_ARGUMENT error is returned. - Google Merchant Center property + Corresponding properties: Google Merchant Center property `id `__. - Schema.org Property + Schema.org property `Product.sku `__. type_ (google.cloud.retail_v2.types.Product.Type): Immutable. The type of the product. Default to @@ -126,21 +132,25 @@ class Product(proto.Message): [Product][google.cloud.retail.v2.Product]. Otherwise, an INVALID_ARGUMENT error is returned. - Google Merchant Center Property + Corresponding properties: Google Merchant Center property `item_group_id `__. - Schema.org Property + Schema.org property `Product.inProductGroupWithID `__. - - This field must be enabled before it can be used. `Learn - more `__. collection_member_ids (Sequence[str]): The [id][google.cloud.retail.v2.Product.id] of the collection members when [type][google.cloud.retail.v2.Product.type] is [Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION]. - Should not set it for other types. A maximum of 1000 values - are allowed. Otherwise, an INVALID_ARGUMENT error is return. + Non-existent product ids are allowed. The + [type][google.cloud.retail.v2.Product.type] of the members + must be either + [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + or + [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT] + otherwise and 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): The Global Trade Item Number (GTIN) of the product. @@ -151,13 +161,13 @@ class Product(proto.Message): This field must be a Unigram. Otherwise, an INVALID_ARGUMENT error is returned. - Google Merchant Center property + Corresponding properties: Google Merchant Center property `gtin `__. Schema.org property - `Product.isbn `__ or - `Product.gtin8 `__ or - `Product.gtin12 `__ or - `Product.gtin13 `__ or + `Product.isbn `__, + `Product.gtin8 `__, + `Product.gtin12 `__, + `Product.gtin13 `__, or `Product.gtin14 `__. If the value is not a valid GTIN, an INVALID_ARGUMENT error @@ -194,7 +204,7 @@ class Product(proto.Message): a length limit of 5,000 characters. Otherwise, an INVALID_ARGUMENT error is returned. - Google Merchant Center property + Corresponding properties: Google Merchant Center property `google_product_category `__. Schema.org property [Product.category] (https://schema.org/category). @@ -205,7 +215,7 @@ class Product(proto.Message): limit of 1,000 characters. Otherwise, an INVALID_ARGUMENT error is returned. - Google Merchant Center property + Corresponding properties: Google Merchant Center property `title `__. Schema.org property `Product.name `__. @@ -217,7 +227,7 @@ class Product(proto.Message): characters. Otherwise, an INVALID_ARGUMENT error is returned. - Google Merchant Center property + Corresponding properties: Google Merchant Center property `brand `__. Schema.org property `Product.brand `__. @@ -228,14 +238,14 @@ class Product(proto.Message): limit of 5,000 characters. Otherwise, an INVALID_ARGUMENT error is returned. - Google Merchant Center property + Corresponding properties: Google Merchant Center property `description `__. - schema.org property + Schema.org property `Product.description `__. language_code (str): Language of the title/description and other string - attributes. Use language tags defined by [BCP - 47][https://www.rfc-editor.org/rfc/bcp/bcp47.txt]. + attributes. Use language tags defined by `BCP + 47 `__. For product prediction, this field is ignored and the model automatically detects the text language. The @@ -272,8 +282,13 @@ class Product(proto.Message): - The key must be a UTF-8 encoded string with a length limit of 128 characters. - For indexable attribute, the key must match the pattern: - ``[a-zA-Z0-9][a-zA-Z0-9_]*``. For example, key0LikeThis - or KEY_1_LIKE_THIS. + ``[a-zA-Z0-9][a-zA-Z0-9_]*``. For example, + ``key0LikeThis`` or ``KEY_1_LIKE_THIS``. + - For text attributes, at most 400 values are allowed. + Empty values are not allowed. Each value must be a + non-empty UTF-8 encoded string with a length limit of 256 + characters. + - For number attributes, at most 400 values are allowed. tags (Sequence[str]): Custom tags associated with the product. @@ -287,12 +302,12 @@ class Product(proto.Message): passing the tag as part of the [PredictRequest.filter][google.cloud.retail.v2.PredictRequest.filter]. - Google Merchant Center property + Corresponding properties: Google Merchant Center property `custom_label_0–4 `__. price_info (google.cloud.retail_v2.types.PriceInfo): Product price and cost information. - Google Merchant Center property + Corresponding properties: Google Merchant Center property `price `__. rating (google.cloud.retail_v2.types.Rating): The rating of this product. @@ -306,9 +321,9 @@ class Product(proto.Message): [Product][google.cloud.retail.v2.Product]. Default to [Availability.IN_STOCK][google.cloud.retail.v2.Product.Availability.IN_STOCK]. - Google Merchant Center Property + Corresponding properties: Google Merchant Center property `availability `__. - Schema.org Property + Schema.org property `Offer.availability `__. available_quantity (google.protobuf.wrappers_pb2.Int32Value): The available quantity of the item. @@ -330,16 +345,16 @@ class Product(proto.Message): limit of 5,000 characters. Otherwise, an INVALID_ARGUMENT error is returned. - Google Merchant Center property + Corresponding properties: Google Merchant Center property `link `__. Schema.org property `Offer.url `__. images (Sequence[google.cloud.retail_v2.types.Image]): - Product images for the product.Highly recommended to put the - main image to the first. + Product images for the product. We highly recommend putting + the main image first. A maximum of 300 images are allowed. - Google Merchant Center property + Corresponding properties: Google Merchant Center property `image_link `__. Schema.org property `Product.image `__. @@ -350,7 +365,7 @@ class Product(proto.Message): color_info (google.cloud.retail_v2.types.ColorInfo): The color of the product. - Google Merchant Center property + Corresponding properties: Google Merchant Center property `color `__. Schema.org property `Product.color `__. @@ -372,9 +387,9 @@ class Product(proto.Message): characters. Otherwise, an INVALID_ARGUMENT error is returned. - Google Merchant Center property + Corresponding properties: Google Merchant Center property `size `__, - `size_type `__ + `size_type `__, and `size_system `__. Schema.org property @@ -384,10 +399,10 @@ class Product(proto.Message): "wooden". A maximum of 20 values are allowed. Each value must be a - UTF-8 encoded string with a length limit of 128 characters. + UTF-8 encoded string with a length limit of 200 characters. Otherwise, an INVALID_ARGUMENT error is returned. - Google Merchant Center property + Corresponding properties: Google Merchant Center property `material `__. Schema.org property `Product.material `__. @@ -401,7 +416,7 @@ class Product(proto.Message): characters. Otherwise, an INVALID_ARGUMENT error is returned. - Google Merchant Center property + Corresponding properties: Google Merchant Center property `pattern `__. Schema.org property `Product.pattern `__. @@ -409,20 +424,22 @@ class Product(proto.Message): The condition of the product. Strongly encouraged to use the standard values: "new", "refurbished", "used". - A maximum of 5 values are allowed per + A maximum of 1 value is allowed per [Product][google.cloud.retail.v2.Product]. Each value must be a UTF-8 encoded string with a length limit of 128 characters. Otherwise, an INVALID_ARGUMENT error is returned. - Google Merchant Center property + Corresponding properties: Google Merchant Center property `condition `__. Schema.org property `Offer.itemCondition `__. promotions (Sequence[google.cloud.retail_v2.types.Promotion]): The promotions applied to the product. A maximum of 10 values are allowed per - [Product][google.cloud.retail.v2.Product]. + [Product][google.cloud.retail.v2.Product]. Only + [Promotion.promotion_id][google.cloud.retail.v2.Promotion.promotion_id] + will be used, other fields will be ignored if set. publish_time (google.protobuf.timestamp_pb2.Timestamp): The timestamp when the product is published by the retailer for the first time, which indicates the freshness of the @@ -529,56 +546,157 @@ class Availability(proto.Enum): BACKORDER = 4 expire_time = proto.Field( - proto.MESSAGE, number=16, oneof="expiration", message=timestamp_pb2.Timestamp, + proto.MESSAGE, + number=16, + oneof="expiration", + message=timestamp_pb2.Timestamp, ) ttl = proto.Field( - proto.MESSAGE, number=17, oneof="expiration", message=duration_pb2.Duration, - ) - name = proto.Field(proto.STRING, number=1,) - id = proto.Field(proto.STRING, number=2,) - type_ = proto.Field(proto.ENUM, number=3, enum=Type,) - primary_product_id = proto.Field(proto.STRING, number=4,) - collection_member_ids = proto.RepeatedField(proto.STRING, number=5,) - gtin = proto.Field(proto.STRING, number=6,) - categories = proto.RepeatedField(proto.STRING, number=7,) - title = proto.Field(proto.STRING, number=8,) - brands = proto.RepeatedField(proto.STRING, number=9,) - description = proto.Field(proto.STRING, number=10,) - language_code = proto.Field(proto.STRING, number=11,) + proto.MESSAGE, + number=17, + oneof="expiration", + message=duration_pb2.Duration, + ) + name = proto.Field( + proto.STRING, + number=1, + ) + id = proto.Field( + proto.STRING, + number=2, + ) + type_ = proto.Field( + proto.ENUM, + number=3, + enum=Type, + ) + primary_product_id = proto.Field( + proto.STRING, + number=4, + ) + collection_member_ids = proto.RepeatedField( + proto.STRING, + number=5, + ) + gtin = proto.Field( + proto.STRING, + number=6, + ) + categories = proto.RepeatedField( + proto.STRING, + number=7, + ) + title = proto.Field( + proto.STRING, + number=8, + ) + brands = proto.RepeatedField( + proto.STRING, + number=9, + ) + description = proto.Field( + proto.STRING, + number=10, + ) + language_code = proto.Field( + proto.STRING, + number=11, + ) attributes = proto.MapField( - proto.STRING, proto.MESSAGE, number=12, message=common.CustomAttribute, + proto.STRING, + proto.MESSAGE, + number=12, + message=common.CustomAttribute, + ) + tags = proto.RepeatedField( + proto.STRING, + number=13, + ) + price_info = proto.Field( + proto.MESSAGE, + number=14, + message=common.PriceInfo, + ) + rating = proto.Field( + proto.MESSAGE, + number=15, + message=common.Rating, ) - tags = proto.RepeatedField(proto.STRING, number=13,) - price_info = proto.Field(proto.MESSAGE, number=14, message=common.PriceInfo,) - rating = proto.Field(proto.MESSAGE, number=15, message=common.Rating,) available_time = proto.Field( - proto.MESSAGE, number=18, message=timestamp_pb2.Timestamp, + proto.MESSAGE, + number=18, + message=timestamp_pb2.Timestamp, + ) + availability = proto.Field( + proto.ENUM, + number=19, + enum=Availability, ) - availability = proto.Field(proto.ENUM, number=19, enum=Availability,) available_quantity = proto.Field( - proto.MESSAGE, number=20, message=wrappers_pb2.Int32Value, + proto.MESSAGE, + number=20, + message=wrappers_pb2.Int32Value, ) fulfillment_info = proto.RepeatedField( - proto.MESSAGE, number=21, message=common.FulfillmentInfo, - ) - uri = proto.Field(proto.STRING, number=22,) - images = proto.RepeatedField(proto.MESSAGE, number=23, message=common.Image,) - audience = proto.Field(proto.MESSAGE, number=24, message=common.Audience,) - color_info = proto.Field(proto.MESSAGE, number=25, message=common.ColorInfo,) - sizes = proto.RepeatedField(proto.STRING, number=26,) - materials = proto.RepeatedField(proto.STRING, number=27,) - patterns = proto.RepeatedField(proto.STRING, number=28,) - conditions = proto.RepeatedField(proto.STRING, number=29,) + proto.MESSAGE, + number=21, + message=common.FulfillmentInfo, + ) + uri = proto.Field( + proto.STRING, + number=22, + ) + images = proto.RepeatedField( + proto.MESSAGE, + number=23, + message=common.Image, + ) + audience = proto.Field( + proto.MESSAGE, + number=24, + message=common.Audience, + ) + color_info = proto.Field( + proto.MESSAGE, + number=25, + message=common.ColorInfo, + ) + sizes = proto.RepeatedField( + proto.STRING, + number=26, + ) + materials = proto.RepeatedField( + proto.STRING, + number=27, + ) + patterns = proto.RepeatedField( + proto.STRING, + number=28, + ) + conditions = proto.RepeatedField( + proto.STRING, + number=29, + ) promotions = proto.RepeatedField( - proto.MESSAGE, number=34, message=common.Promotion, + proto.MESSAGE, + number=34, + message=promotion.Promotion, ) publish_time = proto.Field( - proto.MESSAGE, number=33, message=timestamp_pb2.Timestamp, + proto.MESSAGE, + number=33, + message=timestamp_pb2.Timestamp, ) retrievable_fields = proto.Field( - proto.MESSAGE, number=30, message=field_mask_pb2.FieldMask, + proto.MESSAGE, + number=30, + message=field_mask_pb2.FieldMask, + ) + variants = proto.RepeatedField( + proto.MESSAGE, + number=31, + message="Product", ) - variants = proto.RepeatedField(proto.MESSAGE, number=31, message="Product",) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/retail_v2/types/product_service.py b/google/cloud/retail_v2/types/product_service.py index e85576d7..2681119d 100644 --- a/google/cloud/retail_v2/types/product_service.py +++ b/google/cloud/retail_v2/types/product_service.py @@ -15,6 +15,7 @@ # import proto # type: ignore +from google.cloud.retail_v2.types import common from google.cloud.retail_v2.types import product as gcr_product from google.protobuf import field_mask_pb2 # type: ignore from google.protobuf import timestamp_pb2 # type: ignore @@ -35,6 +36,12 @@ "AddFulfillmentPlacesRequest", "AddFulfillmentPlacesMetadata", "AddFulfillmentPlacesResponse", + "AddLocalInventoriesRequest", + "AddLocalInventoriesMetadata", + "AddLocalInventoriesResponse", + "RemoveLocalInventoriesRequest", + "RemoveLocalInventoriesMetadata", + "RemoveLocalInventoriesResponse", "RemoveFulfillmentPlacesRequest", "RemoveFulfillmentPlacesMetadata", "RemoveFulfillmentPlacesResponse", @@ -73,9 +80,19 @@ class CreateProductRequest(proto.Message): error is returned. """ - parent = proto.Field(proto.STRING, number=1,) - product = proto.Field(proto.MESSAGE, number=2, message=gcr_product.Product,) - product_id = proto.Field(proto.STRING, number=3,) + parent = proto.Field( + proto.STRING, + number=1, + ) + product = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_product.Product, + ) + product_id = proto.Field( + proto.STRING, + number=3, + ) class GetProductRequest(proto.Message): @@ -96,7 +113,10 @@ class GetProductRequest(proto.Message): does not exist, a NOT_FOUND error is returned. """ - name = proto.Field(proto.STRING, number=1,) + name = proto.Field( + proto.STRING, + number=1, + ) class UpdateProductRequest(proto.Message): @@ -131,11 +151,20 @@ class UpdateProductRequest(proto.Message): created. In this situation, ``update_mask`` is ignored. """ - product = proto.Field(proto.MESSAGE, number=1, message=gcr_product.Product,) + product = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_product.Product, + ) update_mask = proto.Field( - proto.MESSAGE, number=2, message=field_mask_pb2.FieldMask, + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + allow_missing = proto.Field( + proto.BOOL, + number=3, ) - allow_missing = proto.Field(proto.BOOL, number=3,) class DeleteProductRequest(proto.Message): @@ -168,7 +197,10 @@ class DeleteProductRequest(proto.Message): [Product][google.cloud.retail.v2.Product] will be deleted. """ - name = proto.Field(proto.STRING, number=1,) + name = proto.Field( + proto.STRING, + number=1, + ) class ListProductsRequest(proto.Message): @@ -258,11 +290,27 @@ class ListProductsRequest(proto.Message): INVALID_ARGUMENT error is returned. """ - parent = proto.Field(proto.STRING, number=1,) - page_size = proto.Field(proto.INT32, number=2,) - page_token = proto.Field(proto.STRING, number=3,) - filter = proto.Field(proto.STRING, number=4,) - read_mask = proto.Field(proto.MESSAGE, number=5, message=field_mask_pb2.FieldMask,) + parent = proto.Field( + proto.STRING, + number=1, + ) + page_size = proto.Field( + proto.INT32, + number=2, + ) + page_token = proto.Field( + proto.STRING, + number=3, + ) + filter = proto.Field( + proto.STRING, + number=4, + ) + read_mask = proto.Field( + proto.MESSAGE, + number=5, + message=field_mask_pb2.FieldMask, + ) class ListProductsResponse(proto.Message): @@ -285,9 +333,14 @@ def raw_page(self): return self products = proto.RepeatedField( - proto.MESSAGE, number=1, message=gcr_product.Product, + proto.MESSAGE, + number=1, + message=gcr_product.Product, + ) + next_page_token = proto.Field( + proto.STRING, + number=2, ) - next_page_token = proto.Field(proto.STRING, number=2,) class SetInventoryRequest(proto.Message): @@ -325,6 +378,26 @@ class SetInventoryRequest(proto.Message): value for [SetInventoryRequest.set_time][google.cloud.retail.v2.SetInventoryRequest.set_time]. + The caller can replace place IDs for a subset of fulfillment + types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types and + corresponding place IDs to update in + [SetInventoryRequest.inventory.fulfillment_info][] + + The caller can clear all place IDs from a subset of + fulfillment types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types to clear in + [SetInventoryRequest.inventory.fulfillment_info][] + - Checks that only the desired fulfillment info types have + empty + [SetInventoryRequest.inventory.fulfillment_info.place_ids][] + The last update time is recorded for the following inventory fields: @@ -338,9 +411,9 @@ class SetInventoryRequest(proto.Message): instead. set_mask (google.protobuf.field_mask_pb2.FieldMask): Indicates which inventory fields in the provided - [Product][google.cloud.retail.v2.Product] to update. If not - set or set with empty paths, all inventory fields will be - updated. + [Product][google.cloud.retail.v2.Product] to update. + + At least one field must be provided. If an unsupported or unknown field is provided, an INVALID_ARGUMENT error is returned and the entire update @@ -361,10 +434,25 @@ class SetInventoryRequest(proto.Message): [Product][google.cloud.retail.v2.Product] is not found. """ - inventory = proto.Field(proto.MESSAGE, number=1, message=gcr_product.Product,) - set_mask = proto.Field(proto.MESSAGE, number=2, message=field_mask_pb2.FieldMask,) - set_time = proto.Field(proto.MESSAGE, number=3, message=timestamp_pb2.Timestamp,) - allow_missing = proto.Field(proto.BOOL, number=4,) + inventory = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_product.Product, + ) + set_mask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + set_time = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + allow_missing = proto.Field( + proto.BOOL, + number=4, + ) class SetInventoryMetadata(proto.Message): @@ -450,11 +538,27 @@ class AddFulfillmentPlacesRequest(proto.Message): [Product][google.cloud.retail.v2.Product] is not found. """ - product = proto.Field(proto.STRING, number=1,) - type_ = proto.Field(proto.STRING, number=2,) - place_ids = proto.RepeatedField(proto.STRING, number=3,) - add_time = proto.Field(proto.MESSAGE, number=4, message=timestamp_pb2.Timestamp,) - allow_missing = proto.Field(proto.BOOL, number=5,) + product = proto.Field( + proto.STRING, + number=1, + ) + type_ = proto.Field( + proto.STRING, + number=2, + ) + place_ids = proto.RepeatedField( + proto.STRING, + number=3, + ) + add_time = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + allow_missing = proto.Field( + proto.BOOL, + number=5, + ) class AddFulfillmentPlacesMetadata(proto.Message): @@ -473,6 +577,166 @@ class AddFulfillmentPlacesResponse(proto.Message): """ +class AddLocalInventoriesRequest(proto.Message): + r"""Request message for [AddLocalInventories][] method. + + Attributes: + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + local_inventories (Sequence[google.cloud.retail_v2.types.LocalInventory]): + Required. A list of inventory information at + difference places. Each place is identified by + its place ID. At most 3000 inventories are + allowed per request. + add_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which inventory fields in the provided list of + [LocalInventory][google.cloud.retail.v2.LocalInventory] to + update. The field is updated to the provided value. + + If a field is set while the place does not have a previous + local inventory, the local inventory at that store is + created. + + If a field is set while the value of that field is not + provided, the original field value, if it exists, is + deleted. + + If the mask is not set or set with empty paths, all + inventory fields will be updated. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned and the entire update + will be ignored. + add_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the inventory updates are + issued. Used to prevent out-of-order updates on + local inventory fields. If not provided, the + internal system time will be used. + allow_missing (bool): + If set to true, and the + [Product][google.cloud.retail.v2.Product] is not found, the + local inventory will still be processed and retained for at + most 1 day and processed once the + [Product][google.cloud.retail.v2.Product] is created. If set + to false, a NOT_FOUND error is returned if the + [Product][google.cloud.retail.v2.Product] is not found. + """ + + product = proto.Field( + proto.STRING, + number=1, + ) + local_inventories = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=common.LocalInventory, + ) + add_mask = proto.Field( + proto.MESSAGE, + number=4, + message=field_mask_pb2.FieldMask, + ) + add_time = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + allow_missing = proto.Field( + proto.BOOL, + number=6, + ) + + +class AddLocalInventoriesMetadata(proto.Message): + r"""Metadata related to the progress of the AddLocalInventories + operation. Currently empty because there is no meaningful metadata + populated from the [AddLocalInventories][] method. + + """ + + +class AddLocalInventoriesResponse(proto.Message): + r"""Response of the [AddLocalInventories][] API. Currently empty because + there is no meaningful response populated from the + [AddLocalInventories][] method. + + """ + + +class RemoveLocalInventoriesRequest(proto.Message): + r"""Request message for [RemoveLocalInventories][] method. + + Attributes: + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + place_ids (Sequence[str]): + Required. A list of place IDs to have their + inventory deleted. At most 3000 place IDs are + allowed per request. + remove_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the inventory deletions are + issued. Used to prevent out-of-order updates and + deletions on local inventory fields. If not + provided, the internal system time will be used. + allow_missing (bool): + If set to true, and the + [Product][google.cloud.retail.v2.Product] is not found, the + local inventory removal request will still be processed and + retained for at most 1 day and processed once the + [Product][google.cloud.retail.v2.Product] is created. If set + to false, a NOT_FOUND error is returned if the + [Product][google.cloud.retail.v2.Product] is not found. + """ + + product = proto.Field( + proto.STRING, + number=1, + ) + place_ids = proto.RepeatedField( + proto.STRING, + number=2, + ) + remove_time = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + allow_missing = proto.Field( + proto.BOOL, + number=3, + ) + + +class RemoveLocalInventoriesMetadata(proto.Message): + r"""Metadata related to the progress of the RemoveLocalInventories + operation. Currently empty because there is no meaningful metadata + populated from the [RemoveLocalInventories][] method. + + """ + + +class RemoveLocalInventoriesResponse(proto.Message): + r"""Response of the [RemoveLocalInventories][] API. Currently empty + because there is no meaningful response populated from the + [RemoveLocalInventories][] method. + + """ + + class RemoveFulfillmentPlacesRequest(proto.Message): r"""Request message for [RemoveFulfillmentPlaces][] method. @@ -535,11 +799,27 @@ class RemoveFulfillmentPlacesRequest(proto.Message): [Product][google.cloud.retail.v2.Product] is not found. """ - product = proto.Field(proto.STRING, number=1,) - type_ = proto.Field(proto.STRING, number=2,) - place_ids = proto.RepeatedField(proto.STRING, number=3,) - remove_time = proto.Field(proto.MESSAGE, number=4, message=timestamp_pb2.Timestamp,) - allow_missing = proto.Field(proto.BOOL, number=5,) + product = proto.Field( + proto.STRING, + number=1, + ) + type_ = proto.Field( + proto.STRING, + number=2, + ) + place_ids = proto.RepeatedField( + proto.STRING, + number=3, + ) + remove_time = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + allow_missing = proto.Field( + proto.BOOL, + number=5, + ) class RemoveFulfillmentPlacesMetadata(proto.Message): diff --git a/google/cloud/retail_v2/types/promotion.py b/google/cloud/retail_v2/types/promotion.py new file mode 100644 index 00000000..9aa7065c --- /dev/null +++ b/google/cloud/retail_v2/types/promotion.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. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.cloud.retail.v2", + manifest={ + "Promotion", + }, +) + + +class Promotion(proto.Message): + r"""Promotion information. + + Attributes: + promotion_id (str): + ID of the promotion. For example, "free gift". + + The value must be a UTF-8 encoded string with a length limit + of 128 characters, and match the pattern: + ``[a-zA-Z][a-zA-Z0-9_]*``. For example, id0LikeThis or + ID_1_LIKE_THIS. Otherwise, an INVALID_ARGUMENT error is + returned. + + Google Merchant Center property + `promotion `__. + """ + + promotion_id = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/retail_v2/types/purge_config.py b/google/cloud/retail_v2/types/purge_config.py index a425d629..8d3156a3 100644 --- a/google/cloud/retail_v2/types/purge_config.py +++ b/google/cloud/retail_v2/types/purge_config.py @@ -18,7 +18,11 @@ __protobuf__ = proto.module( package="google.cloud.retail.v2", - manifest={"PurgeMetadata", "PurgeUserEventsRequest", "PurgeUserEventsResponse",}, + manifest={ + "PurgeMetadata", + "PurgeUserEventsRequest", + "PurgeUserEventsResponse", + }, ) @@ -69,9 +73,18 @@ class PurgeUserEventsRequest(proto.Message): deleting any user events. """ - parent = proto.Field(proto.STRING, number=1,) - filter = proto.Field(proto.STRING, number=2,) - force = proto.Field(proto.BOOL, number=3,) + parent = proto.Field( + proto.STRING, + number=1, + ) + filter = proto.Field( + proto.STRING, + number=2, + ) + force = proto.Field( + proto.BOOL, + number=3, + ) class PurgeUserEventsResponse(proto.Message): @@ -85,7 +98,10 @@ class PurgeUserEventsResponse(proto.Message): of the operation. """ - purged_events_count = proto.Field(proto.INT64, number=1,) + purged_events_count = proto.Field( + proto.INT64, + number=1, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/retail_v2/types/search_service.py b/google/cloud/retail_v2/types/search_service.py index 47c6517f..0381e999 100644 --- a/google/cloud/retail_v2/types/search_service.py +++ b/google/cloud/retail_v2/types/search_service.py @@ -22,7 +22,11 @@ __protobuf__ = proto.module( - package="google.cloud.retail.v2", manifest={"SearchRequest", "SearchResponse",}, + package="google.cloud.retail.v2", + manifest={ + "SearchRequest", + "SearchResponse", + }, ) @@ -35,7 +39,7 @@ class SearchRequest(proto.Message): placement (str): Required. The resource name of the search engine placement, such as - ``projects/*/locations/global/catalogs/default_catalog/placements/default_search``. + ``projects/*/locations/global/catalogs/default_catalog/placements/default_search`` This field is used to identify the serving configuration name and the set of models that will be used to make the search. @@ -54,6 +58,9 @@ class SearchRequest(proto.Message): single device. This unique identifier should not change if the visitor logs in or out of the website. + This should be the same identifier as + [UserEvent.visitor_id][google.cloud.retail.v2.UserEvent.visitor_id]. + The field must be a UTF-8 encoded string with a length limit of 128 characters. Otherwise, an INVALID_ARGUMENT error is returned. @@ -97,6 +104,9 @@ class SearchRequest(proto.Message): If this field is unrecognizable, an INVALID_ARGUMENT is returned. canonical_filter (str): + The default filter that is applied when a user performs a + search without checking any filters on the search page. + The filter applied to every search request when quality improvement such as query expansion is needed. For example, if a query does not have enough results, an expanded query @@ -126,12 +136,12 @@ class SearchRequest(proto.Message): A maximum of 100 values are allowed. Otherwise, an INVALID_ARGUMENT error is returned. dynamic_facet_spec (google.cloud.retail_v2.types.SearchRequest.DynamicFacetSpec): + Deprecated. Refer to + https://cloud.google.com/retail/docs/configs#dynamic + to enable dynamic facets. Do not set this field. The specification for dynamically generated facets. Notice that only textual facets can be dynamically generated. - This feature requires additional allowlisting. - Contact Retail Search support team if you are - interested in using dynamic facet feature. boost_spec (google.cloud.retail_v2.types.SearchRequest.BoostSpec): Boost specification to boost certain products. See more details at this `user @@ -151,14 +161,15 @@ class SearchRequest(proto.Message): variant_rollup_keys (Sequence[str]): The keys to fetch and rollup the matching [variant][google.cloud.retail.v2.Product.Type.VARIANT] - [Product][google.cloud.retail.v2.Product]s attributes. The - attributes from all the matching - [variant][google.cloud.retail.v2.Product.Type.VARIANT] - [Product][google.cloud.retail.v2.Product]s are merged and - de-duplicated. Notice that rollup + [Product][google.cloud.retail.v2.Product]s attributes, + [FulfillmentInfo][google.cloud.retail.v2.FulfillmentInfo] or + [LocalInventory][google.cloud.retail.v2.LocalInventory]s + attributes. The attributes from all the matching [variant][google.cloud.retail.v2.Product.Type.VARIANT] - [Product][google.cloud.retail.v2.Product]s attributes will - lead to extra query latency. Maximum number of keys is 10. + [Product][google.cloud.retail.v2.Product]s or + [LocalInventory][google.cloud.retail.v2.LocalInventory]s are + merged and de-duplicated. Notice that rollup attributes will + lead to extra query latency. Maximum number of keys is 30. For [FulfillmentInfo][google.cloud.retail.v2.FulfillmentInfo], a @@ -175,6 +186,7 @@ class SearchRequest(proto.Message): - discount - variantId - inventory(place_id,price) + - inventory(place_id,original_price) - inventory(place_id,attributes.key), where key is any key in the [Product.inventories.attributes][] map. - attributes.key, where key is any key in the @@ -246,6 +258,8 @@ class SearchRequest(proto.Message): The search mode of the search request. If not specified, a single search request triggers both product search and faceted search. + personalization_spec (google.cloud.retail_v2.types.SearchRequest.PersonalizationSpec): + The specification for personalization. """ class SearchMode(proto.Enum): @@ -370,6 +384,7 @@ class FacetKey(proto.Message): - "ratingCount" - "attributes.key" - "inventory(place_id,price)" + - "inventory(place_id,original_price)" - "inventory(place_id,attributes.key)". intervals (Sequence[google.cloud.retail_v2.types.Interval]): Set only if values should be bucketized into @@ -463,22 +478,53 @@ class FacetKey(proto.Message): both in stock and ship to store "123". """ - key = proto.Field(proto.STRING, number=1,) + key = proto.Field( + proto.STRING, + number=1, + ) intervals = proto.RepeatedField( - proto.MESSAGE, number=2, message=common.Interval, + proto.MESSAGE, + number=2, + message=common.Interval, + ) + restricted_values = proto.RepeatedField( + proto.STRING, + number=3, + ) + prefixes = proto.RepeatedField( + proto.STRING, + number=8, + ) + contains = proto.RepeatedField( + proto.STRING, + number=9, + ) + order_by = proto.Field( + proto.STRING, + number=4, + ) + query = proto.Field( + proto.STRING, + number=5, ) - restricted_values = proto.RepeatedField(proto.STRING, number=3,) - prefixes = proto.RepeatedField(proto.STRING, number=8,) - contains = proto.RepeatedField(proto.STRING, number=9,) - order_by = proto.Field(proto.STRING, number=4,) - query = proto.Field(proto.STRING, number=5,) facet_key = proto.Field( - proto.MESSAGE, number=1, message="SearchRequest.FacetSpec.FacetKey", + proto.MESSAGE, + number=1, + message="SearchRequest.FacetSpec.FacetKey", + ) + limit = proto.Field( + proto.INT32, + number=2, + ) + excluded_filter_keys = proto.RepeatedField( + proto.STRING, + number=3, + ) + enable_dynamic_position = proto.Field( + proto.BOOL, + number=4, ) - limit = proto.Field(proto.INT32, number=2,) - excluded_filter_keys = proto.RepeatedField(proto.STRING, number=3,) - enable_dynamic_position = proto.Field(proto.BOOL, number=4,) class DynamicFacetSpec(proto.Message): r"""The specifications of dynamically generated facets. @@ -497,7 +543,9 @@ class Mode(proto.Enum): ENABLED = 2 mode = proto.Field( - proto.ENUM, number=1, enum="SearchRequest.DynamicFacetSpec.Mode", + proto.ENUM, + number=1, + enum="SearchRequest.DynamicFacetSpec.Mode", ) class BoostSpec(proto.Message): @@ -511,6 +559,15 @@ class BoostSpec(proto.Message): specifications are all applied and combined in a non-linear way. Maximum number of specifications is 10. + skip_boost_spec_validation (bool): + Whether to skip boostspec validation. If this field is set + to true, invalid + [BoostSpec.condition_boost_specs][google.cloud.retail.v2.SearchRequest.BoostSpec.condition_boost_specs] + will be ignored and valid + [BoostSpec.condition_boost_specs][google.cloud.retail.v2.SearchRequest.BoostSpec.condition_boost_specs] + will still be applied. + + This field is a member of `oneof`_ ``_skip_boost_spec_validation``. """ class ConditionBoostSpec(proto.Message): @@ -552,14 +609,25 @@ class ConditionBoostSpec(proto.Message): condition is ignored. """ - condition = proto.Field(proto.STRING, number=1,) - boost = proto.Field(proto.FLOAT, number=2,) + condition = proto.Field( + proto.STRING, + number=1, + ) + boost = proto.Field( + proto.FLOAT, + number=2, + ) condition_boost_specs = proto.RepeatedField( proto.MESSAGE, number=1, message="SearchRequest.BoostSpec.ConditionBoostSpec", ) + skip_boost_spec_validation = proto.Field( + proto.BOOL, + number=2, + optional=True, + ) class QueryExpansionSpec(proto.Message): r"""Specification to determine under which conditions query @@ -586,32 +654,119 @@ class Condition(proto.Enum): AUTO = 3 condition = proto.Field( - proto.ENUM, number=1, enum="SearchRequest.QueryExpansionSpec.Condition", + proto.ENUM, + number=1, + enum="SearchRequest.QueryExpansionSpec.Condition", ) - pin_unexpanded_results = proto.Field(proto.BOOL, number=2,) - - placement = proto.Field(proto.STRING, number=1,) - branch = proto.Field(proto.STRING, number=2,) - query = proto.Field(proto.STRING, number=3,) - visitor_id = proto.Field(proto.STRING, number=4,) - user_info = proto.Field(proto.MESSAGE, number=5, message=common.UserInfo,) - page_size = proto.Field(proto.INT32, number=7,) - page_token = proto.Field(proto.STRING, number=8,) - offset = proto.Field(proto.INT32, number=9,) - filter = proto.Field(proto.STRING, number=10,) - canonical_filter = proto.Field(proto.STRING, number=28,) - order_by = proto.Field(proto.STRING, number=11,) - facet_specs = proto.RepeatedField(proto.MESSAGE, number=12, message=FacetSpec,) + pin_unexpanded_results = proto.Field( + proto.BOOL, + number=2, + ) + + class PersonalizationSpec(proto.Message): + r"""The specification for personalization. + + Attributes: + mode (google.cloud.retail_v2.types.SearchRequest.PersonalizationSpec.Mode): + Defaults to + [Mode.AUTO][google.cloud.retail.v2.SearchRequest.PersonalizationSpec.Mode.AUTO]. + """ + + class Mode(proto.Enum): + r"""The personalization mode of each search request.""" + MODE_UNSPECIFIED = 0 + AUTO = 1 + DISABLED = 2 + + mode = proto.Field( + proto.ENUM, + number=1, + enum="SearchRequest.PersonalizationSpec.Mode", + ) + + placement = proto.Field( + proto.STRING, + number=1, + ) + branch = proto.Field( + proto.STRING, + number=2, + ) + query = proto.Field( + proto.STRING, + number=3, + ) + visitor_id = proto.Field( + proto.STRING, + number=4, + ) + user_info = proto.Field( + proto.MESSAGE, + number=5, + message=common.UserInfo, + ) + page_size = proto.Field( + proto.INT32, + number=7, + ) + page_token = proto.Field( + proto.STRING, + number=8, + ) + offset = proto.Field( + proto.INT32, + number=9, + ) + filter = proto.Field( + proto.STRING, + number=10, + ) + canonical_filter = proto.Field( + proto.STRING, + number=28, + ) + order_by = proto.Field( + proto.STRING, + number=11, + ) + facet_specs = proto.RepeatedField( + proto.MESSAGE, + number=12, + message=FacetSpec, + ) dynamic_facet_spec = proto.Field( - proto.MESSAGE, number=21, message=DynamicFacetSpec, + proto.MESSAGE, + number=21, + message=DynamicFacetSpec, + ) + boost_spec = proto.Field( + proto.MESSAGE, + number=13, + message=BoostSpec, ) - boost_spec = proto.Field(proto.MESSAGE, number=13, message=BoostSpec,) query_expansion_spec = proto.Field( - proto.MESSAGE, number=14, message=QueryExpansionSpec, + proto.MESSAGE, + number=14, + message=QueryExpansionSpec, + ) + variant_rollup_keys = proto.RepeatedField( + proto.STRING, + number=17, + ) + page_categories = proto.RepeatedField( + proto.STRING, + number=23, + ) + search_mode = proto.Field( + proto.ENUM, + number=31, + enum=SearchMode, + ) + personalization_spec = proto.Field( + proto.MESSAGE, + number=32, + message=PersonalizationSpec, ) - variant_rollup_keys = proto.RepeatedField(proto.STRING, number=17,) - page_categories = proto.RepeatedField(proto.STRING, number=23,) - search_mode = proto.Field(proto.ENUM, number=31, enum=SearchMode,) class SearchResponse(proto.Message): @@ -655,6 +810,13 @@ class SearchResponse(proto.Message): and [attribution_token][google.cloud.retail.v2.SearchResponse.attribution_token] will be set in the response. + applied_controls (Sequence[str]): + The fully qualified resource name of applied + `controls `__. + invalid_condition_boost_specs (Sequence[google.cloud.retail_v2.types.SearchRequest.BoostSpec.ConditionBoostSpec]): + The invalid + [SearchRequest.BoostSpec.condition_boost_specs][google.cloud.retail.v2.SearchRequest.BoostSpec.condition_boost_specs] + that are not applied during serving. """ class SearchResult(proto.Message): @@ -738,14 +900,30 @@ class SearchResult(proto.Message): in the store "store1". """ - id = proto.Field(proto.STRING, number=1,) - product = proto.Field(proto.MESSAGE, number=2, message=gcr_product.Product,) - matching_variant_count = proto.Field(proto.INT32, number=3,) + id = proto.Field( + proto.STRING, + number=1, + ) + product = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_product.Product, + ) + matching_variant_count = proto.Field( + proto.INT32, + number=3, + ) matching_variant_fields = proto.MapField( - proto.STRING, proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + proto.STRING, + proto.MESSAGE, + number=4, + message=field_mask_pb2.FieldMask, ) variant_rollup_values = proto.MapField( - proto.STRING, proto.MESSAGE, number=5, message=struct_pb2.Value, + proto.STRING, + proto.MESSAGE, + number=5, + message=struct_pb2.Value, ) class Facet(proto.Message): @@ -786,17 +964,35 @@ class FacetValue(proto.Message): Number of items that have this facet value. """ - value = proto.Field(proto.STRING, number=1, oneof="facet_value",) + value = proto.Field( + proto.STRING, + number=1, + oneof="facet_value", + ) interval = proto.Field( - proto.MESSAGE, number=2, oneof="facet_value", message=common.Interval, + proto.MESSAGE, + number=2, + oneof="facet_value", + message=common.Interval, + ) + count = proto.Field( + proto.INT64, + number=3, ) - count = proto.Field(proto.INT64, number=3,) - key = proto.Field(proto.STRING, number=1,) + key = proto.Field( + proto.STRING, + number=1, + ) values = proto.RepeatedField( - proto.MESSAGE, number=2, message="SearchResponse.Facet.FacetValue", + proto.MESSAGE, + number=2, + message="SearchResponse.Facet.FacetValue", + ) + dynamic_facet = proto.Field( + proto.BOOL, + number=3, ) - dynamic_facet = proto.Field(proto.BOOL, number=3,) class QueryExpansionInfo(proto.Message): r"""Information describing query expansion including whether @@ -813,23 +1009,63 @@ class QueryExpansionInfo(proto.Message): is set to true. """ - expanded_query = proto.Field(proto.BOOL, number=1,) - pinned_result_count = proto.Field(proto.INT64, number=2,) + expanded_query = proto.Field( + proto.BOOL, + number=1, + ) + pinned_result_count = proto.Field( + proto.INT64, + number=2, + ) @property def raw_page(self): return self - results = proto.RepeatedField(proto.MESSAGE, number=1, message=SearchResult,) - facets = proto.RepeatedField(proto.MESSAGE, number=2, message=Facet,) - total_size = proto.Field(proto.INT32, number=3,) - corrected_query = proto.Field(proto.STRING, number=4,) - attribution_token = proto.Field(proto.STRING, number=5,) - next_page_token = proto.Field(proto.STRING, number=6,) + results = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=SearchResult, + ) + facets = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=Facet, + ) + total_size = proto.Field( + proto.INT32, + number=3, + ) + corrected_query = proto.Field( + proto.STRING, + number=4, + ) + attribution_token = proto.Field( + proto.STRING, + number=5, + ) + next_page_token = proto.Field( + proto.STRING, + number=6, + ) query_expansion_info = proto.Field( - proto.MESSAGE, number=7, message=QueryExpansionInfo, + proto.MESSAGE, + number=7, + message=QueryExpansionInfo, + ) + redirect_uri = proto.Field( + proto.STRING, + number=10, + ) + applied_controls = proto.RepeatedField( + proto.STRING, + number=12, + ) + invalid_condition_boost_specs = proto.RepeatedField( + proto.MESSAGE, + number=14, + message="SearchRequest.BoostSpec.ConditionBoostSpec", ) - redirect_uri = proto.Field(proto.STRING, number=10,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/retail_v2/types/user_event.py b/google/cloud/retail_v2/types/user_event.py index 4fea4a6d..5cc02a94 100644 --- a/google/cloud/retail_v2/types/user_event.py +++ b/google/cloud/retail_v2/types/user_event.py @@ -23,7 +23,12 @@ __protobuf__ = proto.module( package="google.cloud.retail.v2", - manifest={"UserEvent", "ProductDetail", "CompletionDetail", "PurchaseTransaction",}, + manifest={ + "UserEvent", + "ProductDetail", + "CompletionDetail", + "PurchaseTransaction", + }, ) @@ -38,7 +43,6 @@ class UserEvent(proto.Message): - ``add-to-cart``: Products being added to cart. - ``category-page-view``: Special pages such as sale or promotion pages viewed. - - ``completion``: Completion query result showed/clicked. - ``detail-page-view``: Products detail page viewed. - ``home-page-view``: Homepage viewed. - ``promotion-offered``: Promotion is offered to a user. @@ -118,6 +122,7 @@ class UserEvent(proto.Message): - ``add-to-cart`` - ``detail-page-view`` - ``purchase-complete`` + - ``search`` In a ``search`` event, this field represents the products returned to the end user on the current page (the end user @@ -129,25 +134,38 @@ class UserEvent(proto.Message): is desired. The end user may have not finished browsing the whole page yet. completion_detail (google.cloud.retail_v2.types.CompletionDetail): - The main completion details related to the event. + The main auto-completion details related to the event. - In a ``completion`` event, this field represents the - completions returned to the end user and the clicked - completion by the end user. In a ``search`` event, it - represents the search event happens after clicking - completion. + This field should be set for ``search`` event when + autocomplete function is enabled and the user clicks a + suggestion for search. attributes (Sequence[google.cloud.retail_v2.types.UserEvent.AttributesEntry]): Extra user event features to include in the recommendation model. - The key must be a UTF-8 encoded string with a length limit - of 5,000 characters. Otherwise, an INVALID_ARGUMENT error is - returned. - - For product recommendation, an example of extra user - information is traffic_channel, i.e. how user arrives at the - site. Users can arrive at the site by coming to the site - directly, or coming through Google search, and etc. + If you provide custom attributes for ingested user events, + also include them in the user events that you associate with + prediction requests. Custom attribute formatting must be + consistent between imported events and events provided with + prediction requests. This lets the Retail API use those + custom attributes when training models and serving + predictions, which helps improve recommendation quality. + + This field needs to pass all below criteria, otherwise an + INVALID_ARGUMENT error is returned: + + - The key must be a UTF-8 encoded string with a length + limit of 5,000 characters. + - For text attributes, at most 400 values are allowed. + Empty values are not allowed. Each value must be a UTF-8 + encoded string with a length limit of 256 characters. + - For number attributes, at most 400 values are allowed. + + For product recommendations, an example of extra user + information is traffic_channel, which is how a user arrives + at the site. Users can arrive at the site by coming to the + site directly, coming through Google search, or in other + ways. cart_id (str): The ID or name of the associated shopping cart. This ID is used to associate multiple items added or present in the @@ -268,34 +286,93 @@ class UserEvent(proto.Message): automatically. """ - event_type = proto.Field(proto.STRING, number=1,) - visitor_id = proto.Field(proto.STRING, number=2,) - session_id = proto.Field(proto.STRING, number=21,) - event_time = proto.Field(proto.MESSAGE, number=3, message=timestamp_pb2.Timestamp,) - experiment_ids = proto.RepeatedField(proto.STRING, number=4,) - attribution_token = proto.Field(proto.STRING, number=5,) + event_type = proto.Field( + proto.STRING, + number=1, + ) + visitor_id = proto.Field( + proto.STRING, + number=2, + ) + session_id = proto.Field( + proto.STRING, + number=21, + ) + event_time = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + experiment_ids = proto.RepeatedField( + proto.STRING, + number=4, + ) + attribution_token = proto.Field( + proto.STRING, + number=5, + ) product_details = proto.RepeatedField( - proto.MESSAGE, number=6, message="ProductDetail", + proto.MESSAGE, + number=6, + message="ProductDetail", ) completion_detail = proto.Field( - proto.MESSAGE, number=22, message="CompletionDetail", + proto.MESSAGE, + number=22, + message="CompletionDetail", ) attributes = proto.MapField( - proto.STRING, proto.MESSAGE, number=7, message=common.CustomAttribute, + proto.STRING, + proto.MESSAGE, + number=7, + message=common.CustomAttribute, + ) + cart_id = proto.Field( + proto.STRING, + number=8, ) - cart_id = proto.Field(proto.STRING, number=8,) purchase_transaction = proto.Field( - proto.MESSAGE, number=9, message="PurchaseTransaction", + proto.MESSAGE, + number=9, + message="PurchaseTransaction", + ) + search_query = proto.Field( + proto.STRING, + number=10, + ) + filter = proto.Field( + proto.STRING, + number=16, + ) + order_by = proto.Field( + proto.STRING, + number=17, + ) + offset = proto.Field( + proto.INT32, + number=18, + ) + page_categories = proto.RepeatedField( + proto.STRING, + number=11, + ) + user_info = proto.Field( + proto.MESSAGE, + number=12, + message=common.UserInfo, + ) + uri = proto.Field( + proto.STRING, + number=13, + ) + referrer_uri = proto.Field( + proto.STRING, + number=14, + ) + page_view_id = proto.Field( + proto.STRING, + number=15, ) - search_query = proto.Field(proto.STRING, number=10,) - filter = proto.Field(proto.STRING, number=16,) - order_by = proto.Field(proto.STRING, number=17,) - offset = proto.Field(proto.INT32, number=18,) - page_categories = proto.RepeatedField(proto.STRING, number=11,) - user_info = proto.Field(proto.MESSAGE, number=12, message=common.UserInfo,) - uri = proto.Field(proto.STRING, number=13,) - referrer_uri = proto.Field(proto.STRING, number=14,) - page_view_id = proto.Field(proto.STRING, number=15,) class ProductDetail(proto.Message): @@ -330,8 +407,16 @@ class ProductDetail(proto.Message): types. """ - product = proto.Field(proto.MESSAGE, number=1, message=gcr_product.Product,) - quantity = proto.Field(proto.MESSAGE, number=2, message=wrappers_pb2.Int32Value,) + product = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_product.Product, + ) + quantity = proto.Field( + proto.MESSAGE, + number=2, + message=wrappers_pb2.Int32Value, + ) class CompletionDetail(proto.Message): @@ -351,9 +436,18 @@ class CompletionDetail(proto.Message): position, starting from 0. """ - completion_attribution_token = proto.Field(proto.STRING, number=1,) - selected_suggestion = proto.Field(proto.STRING, number=2,) - selected_position = proto.Field(proto.INT32, number=3,) + completion_attribution_token = proto.Field( + proto.STRING, + number=1, + ) + selected_suggestion = proto.Field( + proto.STRING, + number=2, + ) + selected_position = proto.Field( + proto.INT32, + number=3, + ) class PurchaseTransaction(proto.Message): @@ -386,11 +480,26 @@ class PurchaseTransaction(proto.Message): ISO-4217 code. """ - id = proto.Field(proto.STRING, number=1,) - revenue = proto.Field(proto.FLOAT, number=2,) - tax = proto.Field(proto.FLOAT, number=3,) - cost = proto.Field(proto.FLOAT, number=4,) - currency_code = proto.Field(proto.STRING, number=5,) + id = proto.Field( + proto.STRING, + number=1, + ) + revenue = proto.Field( + proto.FLOAT, + number=2, + ) + tax = proto.Field( + proto.FLOAT, + number=3, + ) + cost = proto.Field( + proto.FLOAT, + number=4, + ) + currency_code = proto.Field( + proto.STRING, + number=5, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/retail_v2/types/user_event_service.py b/google/cloud/retail_v2/types/user_event_service.py index 22e0295c..66eba6c3 100644 --- a/google/cloud/retail_v2/types/user_event_service.py +++ b/google/cloud/retail_v2/types/user_event_service.py @@ -41,8 +41,15 @@ class WriteUserEventRequest(proto.Message): Required. User event to write. """ - parent = proto.Field(proto.STRING, number=1,) - user_event = proto.Field(proto.MESSAGE, number=2, message=gcr_user_event.UserEvent,) + parent = proto.Field( + proto.STRING, + number=1, + ) + user_event = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_user_event.UserEvent, + ) class CollectUserEventRequest(proto.Message): @@ -68,10 +75,22 @@ class CollectUserEventRequest(proto.Message): the payload bytes. """ - parent = proto.Field(proto.STRING, number=1,) - user_event = proto.Field(proto.STRING, number=2,) - uri = proto.Field(proto.STRING, number=3,) - ets = proto.Field(proto.INT64, number=4,) + parent = proto.Field( + proto.STRING, + number=1, + ) + user_event = proto.Field( + proto.STRING, + number=2, + ) + uri = proto.Field( + proto.STRING, + number=3, + ) + ets = proto.Field( + proto.INT64, + number=4, + ) class RejoinUserEventsRequest(proto.Message): @@ -102,9 +121,14 @@ class UserEventRejoinScope(proto.Enum): JOINED_EVENTS = 1 UNJOINED_EVENTS = 2 - parent = proto.Field(proto.STRING, number=1,) + parent = proto.Field( + proto.STRING, + number=1, + ) user_event_rejoin_scope = proto.Field( - proto.ENUM, number=2, enum=UserEventRejoinScope, + proto.ENUM, + number=2, + enum=UserEventRejoinScope, ) @@ -117,12 +141,14 @@ class RejoinUserEventsResponse(proto.Message): latest product catalog. """ - rejoined_user_events_count = proto.Field(proto.INT64, number=1,) + rejoined_user_events_count = proto.Field( + proto.INT64, + number=1, + ) class RejoinUserEventsMetadata(proto.Message): - r"""Metadata for RejoinUserEvents method. - """ + r"""Metadata for RejoinUserEvents method.""" __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/noxfile.py b/noxfile.py index 2a2001c4..3addb4ed 100644 --- a/noxfile.py +++ b/noxfile.py @@ -24,7 +24,7 @@ import nox -BLACK_VERSION = "black==19.10b0" +BLACK_VERSION = "black==22.3.0" BLACK_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] DEFAULT_PYTHON_VERSION = "3.8" @@ -57,7 +57,9 @@ def lint(session): """ session.install("flake8", BLACK_VERSION) session.run( - "black", "--check", *BLACK_PATHS, + "black", + "--check", + *BLACK_PATHS, ) session.run("flake8", "google", "tests") @@ -67,7 +69,8 @@ def blacken(session): """Run black. Format code to uniform standard.""" session.install(BLACK_VERSION) session.run( - "black", *BLACK_PATHS, + "black", + *BLACK_PATHS, ) diff --git a/samples/generated_samples/retail_v2_generated_product_service_add_local_inventories_async.py b/samples/generated_samples/retail_v2_generated_product_service_add_local_inventories_async.py new file mode 100644 index 00000000..6155d5ce --- /dev/null +++ b/samples/generated_samples/retail_v2_generated_product_service_add_local_inventories_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 AddLocalInventories +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2_generated_ProductService_AddLocalInventories_async] +from google.cloud import retail_v2 + + +async def sample_add_local_inventories(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.AddLocalInventoriesRequest( + product="product_value", + ) + + # Make the request + operation = client.add_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_AddLocalInventories_async] diff --git a/samples/generated_samples/retail_v2_generated_product_service_add_local_inventories_sync.py b/samples/generated_samples/retail_v2_generated_product_service_add_local_inventories_sync.py new file mode 100644 index 00000000..b57dce2f --- /dev/null +++ b/samples/generated_samples/retail_v2_generated_product_service_add_local_inventories_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 AddLocalInventories +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2_generated_ProductService_AddLocalInventories_sync] +from google.cloud import retail_v2 + + +def sample_add_local_inventories(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2.AddLocalInventoriesRequest( + product="product_value", + ) + + # Make the request + operation = client.add_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_AddLocalInventories_sync] diff --git a/samples/generated_samples/retail_v2_generated_product_service_remove_local_inventories_async.py b/samples/generated_samples/retail_v2_generated_product_service_remove_local_inventories_async.py new file mode 100644 index 00000000..762dab6d --- /dev/null +++ b/samples/generated_samples/retail_v2_generated_product_service_remove_local_inventories_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 RemoveLocalInventories +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2_generated_ProductService_RemoveLocalInventories_async] +from google.cloud import retail_v2 + + +async def sample_remove_local_inventories(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.RemoveLocalInventoriesRequest( + product="product_value", + place_ids=['place_ids_value_1', 'place_ids_value_2'], + ) + + # Make the request + operation = client.remove_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = await operation.result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_RemoveLocalInventories_async] diff --git a/samples/generated_samples/retail_v2_generated_product_service_remove_local_inventories_sync.py b/samples/generated_samples/retail_v2_generated_product_service_remove_local_inventories_sync.py new file mode 100644 index 00000000..7aa52d5d --- /dev/null +++ b/samples/generated_samples/retail_v2_generated_product_service_remove_local_inventories_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 RemoveLocalInventories +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-retail + + +# [START retail_v2_generated_ProductService_RemoveLocalInventories_sync] +from google.cloud import retail_v2 + + +def sample_remove_local_inventories(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2.RemoveLocalInventoriesRequest( + product="product_value", + place_ids=['place_ids_value_1', 'place_ids_value_2'], + ) + + # Make the request + operation = client.remove_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_RemoveLocalInventories_sync] diff --git a/samples/generated_samples/snippet_metadata_retail_v2.json b/samples/generated_samples/snippet_metadata_retail_v2.json index 60964e77..eecfa415 100644 --- a/samples/generated_samples/snippet_metadata_retail_v2.json +++ b/samples/generated_samples/snippet_metadata_retail_v2.json @@ -708,6 +708,95 @@ } ] }, + { + "clientMethod": { + "async": true, + "method": { + "service": { + "shortName": "ProductService" + }, + "shortName": "AddLocalInventories" + } + }, + "file": "retail_v2_generated_product_service_add_local_inventories_async.py", + "regionTag": "retail_v2_generated_ProductService_AddLocalInventories_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" + } + ] + }, + { + "clientMethod": { + "method": { + "service": { + "shortName": "ProductService" + }, + "shortName": "AddLocalInventories" + } + }, + "file": "retail_v2_generated_product_service_add_local_inventories_sync.py", + "regionTag": "retail_v2_generated_ProductService_AddLocalInventories_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" + } + ] + }, { "clientMethod": { "async": true, @@ -1238,6 +1327,95 @@ } ] }, + { + "clientMethod": { + "async": true, + "method": { + "service": { + "shortName": "ProductService" + }, + "shortName": "RemoveLocalInventories" + } + }, + "file": "retail_v2_generated_product_service_remove_local_inventories_async.py", + "regionTag": "retail_v2_generated_ProductService_RemoveLocalInventories_async", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 39, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 46, + "start": 40, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "start": 47, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "method": { + "service": { + "shortName": "ProductService" + }, + "shortName": "RemoveLocalInventories" + } + }, + "file": "retail_v2_generated_product_service_remove_local_inventories_sync.py", + "regionTag": "retail_v2_generated_ProductService_RemoveLocalInventories_sync", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 39, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 46, + "start": 40, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "start": 47, + "type": "RESPONSE_HANDLING" + } + ] + }, { "clientMethod": { "async": true, diff --git a/samples/interactive-tutorials/README.md b/samples/interactive-tutorials/README.md index 42052666..e1abc308 100644 --- a/samples/interactive-tutorials/README.md +++ b/samples/interactive-tutorials/README.md @@ -43,44 +43,69 @@ If, for some reason, you have decided to proceed with these code samples without ### Select your project and enable the Retail API Google Cloud organizes resources into projects. This lets you -collect all the related resources for a single application in one place. +collect all related resources for a single application in one place. If you don't have a Google Cloud project yet or you're not the owner of an existing one, you can [create a new project](https://console.cloud.google.com/projectcreate). -After the project is created, set your PROJECT_ID to a ```project``` variable. -1. Run the following command in Terminal: +After the project is created, set your PROJECT_ID to a ```project``` variable: + +1. Run the following command in the Terminal: + ```bash gcloud config set project ``` -1. To check that the Retail API is enabled for your Project, go to the [Admin Console](https://console.cloud.google.com/ai/retail/). +1. Ensure that the Retail API is enabled for your project in the [API & Services page](https://console.cloud.google.com/apis/api/retail.googleapis.com/). + +1. Log in with your user credentials to run a code sample from the Cloud Shell: + + ```bash + gcloud auth login + ``` + +1. Type `Y` and press **Enter**. Click the link in the Terminal. A browser window + should appear asking you to log in using your Gmail account. + +1. Provide the Google Auth Library with access to your credentials and paste + the code from the browser to the Terminal. + +## Prepare your work environment + +To prepare the work environment you should perform the following steps: +- Create a service account. +- Create service account key and set it to authorize your calls to the Retail API. +- Install Google Cloud Retail library. ### Create service account -To access the Retail API, you must create a service account. +To access the Retail API, you must create a service account. Check that you are an owner of your Google Cloud project on the [IAM page](https://console.cloud.google.com/iam-admin/iam). -1. To create a service account, follow this [instruction](https://cloud.google.com/retail/docs/setting-up#service-account) +1. To create a service account, perform the following command: -1. Find your service account on the [IAM page](https://console.cloud.google.com/iam-admin/iam), - click `Edit` icon, add the 'Storage Admin' and 'BigQuery Admin' roles. It may take some time for changes to apply. + ```bash + gcloud iam service-accounts create + ``` -1. Copy the service account email in the Principal field. +1. Assign the needed roles to your service account: -### Set up authentication + ```bash + for role in {retail.admin,storage.admin,bigquery.admin} + do gcloud projects add-iam-policy-binding --member="serviceAccount:@.iam.gserviceaccount.com" --role="roles/${role}" + done + ``` -To run a code sample from the Cloud Shell, you need to be authenticated using the service account credentials. +1. Use the following command to print out the service account email: -1. Login with your user credentials. ```bash - gcloud auth login + gcloud iam service-accounts list|grep ``` -1. Type `Y` and press **Enter**. Click the link in a Terminal. A browser window should appear asking you to log in using your Gmail account. + Copy the service account email. -1. Provide the Google Auth Library with access to your credentials and paste the code from the browser to the Terminal. -1. Upload your service account key JSON file and use it to activate the service account: +1. Upload your service account key JSON file and use it to activate the service + account: ```bash gcloud iam service-accounts keys create ~/key.json --iam-account @@ -90,7 +115,9 @@ To run a code sample from the Cloud Shell, you need to be authenticated using th gcloud auth activate-service-account --key-file ~/key.json ``` -1. To request the Retail API, set your service account key JSON file as the GOOGLE_APPLICATION_CREDENTIALS environment variable : +1. Set the key as the GOOGLE_APPLICATION_CREDENTIALS environment variable to + use it for sending requests to the Retail API. + ```bash export GOOGLE_APPLICATION_CREDENTIALS=~/key.json ``` @@ -100,12 +127,14 @@ To run a code sample from the Cloud Shell, you need to be authenticated using th To run Python code samples for the Retail API tutorial, you need to set up your virtual environment. 1. Run the following commands in a Terminal to create an isolated Python environment: + ```bash - pip install virtualenv - virtualenv myenv + virtualenv -p python3 myenv source myenv/bin/activate ``` + 1. Next, install Google packages: + ```bash pip install google pip install google-cloud-retail @@ -114,30 +143,42 @@ To run Python code samples for the Retail API tutorial, you need to set up your ``` -## Import Catalog Data +## Import catalog data -This step is required if this is the first Retail API Tutorial you run. -Otherwise, you can skip it. +There is a python-retail/samples/interactive-tutorials/resources/products.json file with valid products prepared in the `resources` directory. + +The other file, python-retail/samples/interactive-tutorials/resources/products_some_invalid.json, contains both valid and invalid products. You will use it to check the error handling. ### Upload catalog data to Cloud Storage -There is a JSON file with valid products prepared in the `product` directory: -`product/resources/products.json`. +In your own project you need to create a Cloud Storage bucket and put the JSON file there. +The bucket name must be unique. For convenience, you can name it `_`. -Another file, `product/resources/products_some_invalid.json`, contains both valid and invalid products, and you will use it to check the error handling. +1. The code samples for each of the Retail services are stored in different directories. -In your own project, create a Cloud Storage bucket and put the JSON file there. -The bucket name must be unique. For convenience, you can name it `_`. + Go to the code samples directory, your starting point to run more commands. -1. To create the bucket and upload the JSON file, run the following command in the Terminal: + ```bash + cd python-retail/samples/interactive-tutorials + ``` + +1. To create the bucket and upload the JSON file, open python-retail/samples/interactive-tutorials/product/setup_product/products_create_gcs_bucket.py file + +1. Go to the **product** directory and run the following command in the Terminal: ```bash - python product/setup_product/create_gcs_bucket.py + python setup_product/products_create_gcs_bucket.py ``` Now you can see the bucket is created in the [Cloud Storage](https://console.cloud.google.com/storage/browser), and the files are uploaded. -1. The name of the created Retail Search bucket is printed in the Terminal. Copy the name and set it as the environment variable `BUCKET_NAME`: +1. The name of the created Cloud Storage bucket is printed in the Terminal. + + ``` + The gcs bucket _ was created + ``` + + Copy the name and set it as the environment variable `BUCKET_NAME`: ```bash export BUCKET_NAME= @@ -145,10 +186,10 @@ The bucket name must be unique. For convenience, you can name it ` None: def _get_repo_root() -> Optional[str]: - """ Returns the root folder of the project. """ + """Returns the root folder of the project.""" # Get root of this repository. Assume we don't have directories nested deeper than 10 items. p = Path(os.getcwd()) for i in range(10): diff --git a/samples/interactive-tutorials/events/purge_user_event.py b/samples/interactive-tutorials/events/purge_user_event.py index 256ecde1..1be1d4b3 100644 --- a/samples/interactive-tutorials/events/purge_user_event.py +++ b/samples/interactive-tutorials/events/purge_user_event.py @@ -24,9 +24,8 @@ project_id = google.auth.default()[1] -default_catalog = "projects/{0}/locations/global/catalogs/default_catalog".format( - project_id -) +default_catalog = f"projects/{project_id}/locations/global/catalogs/default_catalog" + visitor_id = "test_visitor_id" @@ -34,7 +33,7 @@ def get_purge_user_event_request(): purge_user_event_request = PurgeUserEventsRequest() # TO CHECK ERROR HANDLING SET INVALID FILTER HERE: - purge_user_event_request.filter = 'visitorId="{}"'.format(visitor_id) + purge_user_event_request.filter = f'visitorId="{visitor_id}"' purge_user_event_request.parent = default_catalog purge_user_event_request.force = True print("---purge user events request---") diff --git a/samples/interactive-tutorials/events/rejoin_user_event.py b/samples/interactive-tutorials/events/rejoin_user_event.py index 67e4caa5..598955e9 100644 --- a/samples/interactive-tutorials/events/rejoin_user_event.py +++ b/samples/interactive-tutorials/events/rejoin_user_event.py @@ -24,16 +24,15 @@ project_id = google.auth.default()[1] -default_catalog = "projects/{0}/locations/global/catalogs/default_catalog".format( - project_id -) +default_catalog = f"projects/{project_id}/locations/global/catalogs/default_catalog" + visitor_id = "test_visitor_id" # get rejoin user event request def get_rejoin_user_event_request(): # TO CHECK THE ERROR HANDLING TRY TO PASS INVALID CATALOG: - # default_catalog = "projects/{0}/locations/global/catalogs/invalid_catalog".format(project_number) + # default_catalog = f"projects/{project_id}/locations/global/catalogs/invalid_catalog" rejoin_user_event_request = RejoinUserEventsRequest() rejoin_user_event_request.parent = default_catalog rejoin_user_event_request.user_event_rejoin_scope = ( diff --git a/samples/interactive-tutorials/events/requirements-test.txt b/samples/interactive-tutorials/events/requirements-test.txt index 3ab16c90..5ca83a52 100644 --- a/samples/interactive-tutorials/events/requirements-test.txt +++ b/samples/interactive-tutorials/events/requirements-test.txt @@ -1,3 +1,3 @@ -pytest==7.0.1 +pytest==7.1.1 pytest-xdist==2.5.0 google-cloud-testutils==1.3.1 diff --git a/samples/interactive-tutorials/events/requirements.txt b/samples/interactive-tutorials/events/requirements.txt index 16861b22..5b95ab21 100644 --- a/samples/interactive-tutorials/events/requirements.txt +++ b/samples/interactive-tutorials/events/requirements.txt @@ -1,4 +1,4 @@ google==3.0.0 -google-cloud-retail==1.4.0 -google-cloud-storage==2.1.0 -google-cloud-bigquery==2.34.1 +google-cloud-retail==1.4.1 +google-cloud-storage==2.2.1 +google-cloud-bigquery==2.34.3 diff --git a/samples/interactive-tutorials/events/setup_events/events_create_gcs_bucket.py b/samples/interactive-tutorials/events/setup_events/events_create_gcs_bucket.py index 0ccf6785..07b30763 100644 --- a/samples/interactive-tutorials/events/setup_events/events_create_gcs_bucket.py +++ b/samples/interactive-tutorials/events/setup_events/events_create_gcs_bucket.py @@ -20,10 +20,10 @@ project_id = google.auth.default()[1] timestamp_ = datetime.datetime.now().timestamp().__round__() -bucket_name = "{}_events_{}".format(project_id, timestamp_) +bucket_name = f"{project_id}_events_{timestamp_}" create_bucket(bucket_name) upload_blob(bucket_name, "../resources/user_events.json") upload_blob(bucket_name, "../resources/user_events_some_invalid.json") -print("\nThe gcs bucket {} was created".format(bucket_name)) +print(f"\nThe gcs bucket {bucket_name} was created") diff --git a/samples/interactive-tutorials/events/setup_events/setup_cleanup.py b/samples/interactive-tutorials/events/setup_events/setup_cleanup.py index 53dd775c..4c4f843a 100644 --- a/samples/interactive-tutorials/events/setup_events/setup_cleanup.py +++ b/samples/interactive-tutorials/events/setup_events/setup_cleanup.py @@ -31,8 +31,7 @@ from google.protobuf.timestamp_pb2 import Timestamp project_id = google.auth.default()[1] -default_catalog = "projects/{0}/locations/global/catalogs/default_catalog".format( - project_id) +default_catalog = f"projects/{project_id}/locations/global/catalogs/default_catalog" # get user event @@ -71,7 +70,7 @@ def write_user_event(visitor_id): # purge user event def purge_user_event(visitor_id): purge_user_event_request = PurgeUserEventsRequest() - purge_user_event_request.filter = 'visitorId="{}"'.format(visitor_id) + purge_user_event_request.filter = f'visitorId="{visitor_id}"' purge_user_event_request.parent = default_catalog purge_user_event_request.force = True purge_operation = UserEventServiceClient().purge_user_events( @@ -93,17 +92,14 @@ def create_bucket(bucket_name: str): print("Creating new bucket:" + bucket_name) buckets_in_your_project = list_buckets() if bucket_name in buckets_in_your_project: - print("Bucket {} already exists".format(bucket_name)) + print(f"Bucket {bucket_name} already exists") else: storage_client = storage.Client() bucket = storage_client.bucket(bucket_name) bucket.storage_class = "STANDARD" new_bucket = storage_client.create_bucket(bucket, location="us") print( - "Created bucket {} in {} with storage class {}".format( - new_bucket.name, new_bucket.location, new_bucket.storage_class - ) - ) + f"Created bucket {new_bucket.name} in {new_bucket.location} with storage class {new_bucket.storage_class}") return new_bucket @@ -118,9 +114,9 @@ def delete_bucket(bucket_name: str): blob.delete() bucket = storage_client.get_bucket(bucket_name) bucket.delete() - print("Bucket {} is deleted".format(bucket.name)) + print(f"Bucket {bucket.name} is deleted") else: - print("Bucket {} is not found".format(bucket_name)) + print(f"Bucket {bucket_name} is not found") def list_buckets(): @@ -137,17 +133,14 @@ def upload_blob(bucket_name, source_file_name): """Uploads a file to the bucket.""" # The path to your file to upload # source_file_name = "local/path/to/file" - print("Uploading data form {} to the bucket {}".format(source_file_name, - bucket_name)) + print(f"Uploading data from {source_file_name} to the bucket {bucket_name}") storage_client = storage.Client() bucket = storage_client.bucket(bucket_name) object_name = re.search('resources/(.*?)$', source_file_name).group(1) blob = bucket.blob(object_name) blob.upload_from_filename(source_file_name) print( - "File {} uploaded to {}.".format( - source_file_name, object_name - ) + f"File {source_file_name} uploaded to {object_name}." ) @@ -171,24 +164,26 @@ def create_bq_table(dataset, table_name, schema_file_path): """Create a BigQuery table""" full_table_id = f"{project_id}.{dataset}.{table_name}" bq = bigquery.Client() - print(f"Creating BigQuery table {full_table_id}") + print(f"Check if BQ table {full_table_id} exists") try: bq.get_table(full_table_id) - print(f"table {full_table_id} already exists") + print(f"table {full_table_id} exists and will be deleted") + delete_bq_table(dataset, table_name) except NotFound: - # Construct a Table object to send to the API. - with open(schema_file_path, "rb") as schema: - schema_dict = json.load(schema) - table = bigquery.Table(full_table_id, schema=schema_dict) - bq.create_table(table) - print("table is created") + print(f"table {full_table_id} does not exist") + # Construct a Table object to send to the API. + with open(schema_file_path, "rb") as schema: + schema_dict = json.load(schema) + table = bigquery.Table(full_table_id, schema=schema_dict) + bq.create_table(table) + print(f"table {full_table_id} is created") def delete_bq_table(dataset, table_name): full_table_id = f"{project_id}.{dataset}.{table_name}" bq = bigquery.Client() bq.delete_table(full_table_id, not_found_ok=True) - print("Table '{}' is deleted.".format(full_table_id)) + print(f"Table '{full_table_id}' is deleted.") def upload_data_to_bq_table(dataset, table_name, source, schema_file_path): diff --git a/samples/interactive-tutorials/events/setup_events/update_user_events_json.py b/samples/interactive-tutorials/events/setup_events/update_user_events_json.py index f04b352e..b0e79950 100644 --- a/samples/interactive-tutorials/events/setup_events/update_user_events_json.py +++ b/samples/interactive-tutorials/events/setup_events/update_user_events_json.py @@ -21,4 +21,4 @@ def update_events_timestamp(json_file): # Write the file out again with open(json_file, 'w') as file: file.write(filedata) - print("The {} is updated".format(json_file)) + print(f"The {json_file} is updated") diff --git a/samples/interactive-tutorials/events/write_user_event.py b/samples/interactive-tutorials/events/write_user_event.py index cd02d7c9..50e8dca0 100644 --- a/samples/interactive-tutorials/events/write_user_event.py +++ b/samples/interactive-tutorials/events/write_user_event.py @@ -28,9 +28,8 @@ project_id = google.auth.default()[1] -default_catalog = "projects/{0}/locations/global/catalogs/default_catalog".format( - project_id -) +default_catalog = f"projects/{project_id}/locations/global/catalogs/default_catalog" + visitor_id = "test_visitor_id" @@ -51,8 +50,7 @@ def get_user_event(): # get write user event request def get_write_event_request(user_event): # TO CHECK THE ERROR HANDLING TRY TO PASS INVALID CATALOG: - # default_catalog = "projects/{0}/locations/global/catalogs/invalid_catalog" - # .format(project_number) + # default_catalog = f"projects/{project_id}/locations/global/catalogs/invalid_catalog" write_user_event_request = WriteUserEventRequest() write_user_event_request.user_event = user_event write_user_event_request.parent = default_catalog diff --git a/samples/interactive-tutorials/noxfile.py b/samples/interactive-tutorials/noxfile.py index 1e30748a..53ca3ad2 100644 --- a/samples/interactive-tutorials/noxfile.py +++ b/samples/interactive-tutorials/noxfile.py @@ -28,7 +28,7 @@ # WARNING - WARNING - WARNING - WARNING - WARNING # WARNING - WARNING - WARNING - WARNING - WARNING -BLACK_VERSION = "black==19.10b0" +BLACK_VERSION = "black==22.3.0" # Copy `noxfile_config.py` to your directory and modify it instead. @@ -64,7 +64,7 @@ sys.path.append(".") from noxfile_config import TEST_CONFIG_OVERRIDE except ImportError as e: - print("No user noxfile_config found: detail: {}".format(e)) + print(f"No user noxfile_config found: detail: {e}") TEST_CONFIG_OVERRIDE = {} # Update the TEST_CONFIG with the user supplied values. @@ -222,9 +222,7 @@ def py(session: nox.sessions.Session) -> None: if session.python in TESTED_VERSIONS: _session_tests(session) else: - session.skip( - "SKIPPED: {} tests are disabled for this sample.".format(session.python) - ) + session.skip(f"SKIPPED: {session.python} tests are disabled for this sample.") # @@ -233,7 +231,7 @@ def py(session: nox.sessions.Session) -> None: def _get_repo_root() -> Optional[str]: - """ Returns the root folder of the project. """ + """Returns the root folder of the project.""" # Get root of this repository. Assume we don't have directories nested deeper than 10 items. p = Path(os.getcwd()) for i in range(10): diff --git a/samples/interactive-tutorials/product/add_fulfillment_places.py b/samples/interactive-tutorials/product/add_fulfillment_places.py index e062701d..3f2eb8cd 100644 --- a/samples/interactive-tutorials/product/add_fulfillment_places.py +++ b/samples/interactive-tutorials/product/add_fulfillment_places.py @@ -34,7 +34,6 @@ # The request timestamp current_date = datetime.datetime.now() -outdated_date = datetime.datetime.now() - datetime.timedelta(days=1) # add fulfillment request @@ -63,18 +62,15 @@ def add_fulfillment_places(product_name: str, timestamp, place_id): # This is a long running operation and its result is not immediately present with get operations, # thus we simulate wait with sleep method. - print("---add fulfillment places, wait 40 seconds :---") - time.sleep(40) + print("---add fulfillment places, wait 90 seconds :---") + time.sleep(90) # [END retail_add_fulfillment_places] create_product(product_id) -print("------add fulfilment places with current date: {}-----".format(current_date)) +print(f"------add fulfilment places with current date: {current_date}-----") add_fulfillment_places(product_name, current_date, "store2") get_product(product_name) -print("------add outdated fulfilment places: {}-----".format(outdated_date)) -add_fulfillment_places(product_name, outdated_date, "store3") -get_product(product_name) delete_product(product_name) diff --git a/samples/interactive-tutorials/product/crud_product.py b/samples/interactive-tutorials/product/crud_product.py index 72637194..45f58e53 100644 --- a/samples/interactive-tutorials/product/crud_product.py +++ b/samples/interactive-tutorials/product/crud_product.py @@ -38,7 +38,7 @@ + "/locations/global/catalogs/default_catalog/branches/default_branch" ) product_id = "".join(random.sample(string.ascii_lowercase, 8)) -product_name = "{}/products/{}".format(default_branch_name, product_id) +product_name = f"{default_branch_name}/products/{product_id}" # generate product for create diff --git a/samples/interactive-tutorials/product/noxfile.py b/samples/interactive-tutorials/product/noxfile.py index 85f5836d..25f87a21 100644 --- a/samples/interactive-tutorials/product/noxfile.py +++ b/samples/interactive-tutorials/product/noxfile.py @@ -29,7 +29,7 @@ # WARNING - WARNING - WARNING - WARNING - WARNING # WARNING - WARNING - WARNING - WARNING - WARNING -BLACK_VERSION = "black==19.10b0" +BLACK_VERSION = "black==22.3.0" # Copy `noxfile_config.py` to your directory and modify it instead. @@ -253,7 +253,7 @@ def py(session: nox.sessions.Session) -> None: def _get_repo_root() -> Optional[str]: - """ Returns the root folder of the project. """ + """Returns the root folder of the project.""" # Get root of this repository. Assume we don't have directories nested deeper than 10 items. p = Path(os.getcwd()) for i in range(10): diff --git a/samples/interactive-tutorials/product/remove_fulfillment_places.py b/samples/interactive-tutorials/product/remove_fulfillment_places.py index 8a124521..1397f560 100644 --- a/samples/interactive-tutorials/product/remove_fulfillment_places.py +++ b/samples/interactive-tutorials/product/remove_fulfillment_places.py @@ -34,7 +34,6 @@ # The request timestamp current_date = datetime.datetime.now() -outdated_date = datetime.datetime.now() - datetime.timedelta(days=1) # remove fulfillment request @@ -63,18 +62,15 @@ def remove_fulfillment_places(product_name: str, timestamp, store_id): # This is a long running operation and its result is not immediately present with get operations, # thus we simulate wait with sleep method. - print("---remove fulfillment places, wait 40 seconds:---") - time.sleep(40) + print("---remove fulfillment places, wait 90 seconds:---") + time.sleep(90) # [END retail_remove_fulfillment_places] create_product(product_id) -print("------remove fulfilment places with current date: {}-----".format(current_date)) +print(f"------remove fulfilment places with current date: {current_date}-----") remove_fulfillment_places(product_name, current_date, "store0") get_product(product_name) -print("------remove outdated fulfilment places: {}-----".format(outdated_date)) -remove_fulfillment_places(product_name, outdated_date, "store1") -get_product(product_name) delete_product(product_name) diff --git a/samples/interactive-tutorials/product/requirements-test.txt b/samples/interactive-tutorials/product/requirements-test.txt index 3ab16c90..5ca83a52 100644 --- a/samples/interactive-tutorials/product/requirements-test.txt +++ b/samples/interactive-tutorials/product/requirements-test.txt @@ -1,3 +1,3 @@ -pytest==7.0.1 +pytest==7.1.1 pytest-xdist==2.5.0 google-cloud-testutils==1.3.1 diff --git a/samples/interactive-tutorials/product/requirements.txt b/samples/interactive-tutorials/product/requirements.txt index 8f64bc7a..829efe7c 100644 --- a/samples/interactive-tutorials/product/requirements.txt +++ b/samples/interactive-tutorials/product/requirements.txt @@ -1,4 +1,4 @@ google==3.0.0 -google-cloud-retail==1.4.0 -google-cloud-storage==2.1.0 -google-cloud-bigquery==2.34.1 \ No newline at end of file +google-cloud-retail==1.4.1 +google-cloud-storage==2.2.1 +google-cloud-bigquery==2.34.3 \ No newline at end of file diff --git a/samples/interactive-tutorials/product/set_inventory.py b/samples/interactive-tutorials/product/set_inventory.py index 4a51f987..58dc8350 100644 --- a/samples/interactive-tutorials/product/set_inventory.py +++ b/samples/interactive-tutorials/product/set_inventory.py @@ -44,7 +44,7 @@ def get_product_with_inventory_info(product_name: str) -> Product: price_info = PriceInfo() price_info.price = 15.0 - price_info.original_price = 20.0 + price_info.original_price = 60.0 price_info.cost = 8.0 price_info.currency_code = "USD" @@ -65,8 +65,6 @@ def get_product_with_inventory_info(product_name: str) -> Product: def get_set_inventory_request(product_name: str) -> SetInventoryRequest: # The request timestamp request_time = datetime.datetime.now() - # The out-of-order request timestamp - # request_time = datetime.datetime.now() - datetime.timedelta(days=1) set_mask = FieldMask( paths=["price_info", "availability", "fulfillment_info", "available_quantity"] ) @@ -90,8 +88,8 @@ def set_inventory(product_name: str): # This is a long running operation and its result is not immediately present with get operations, # thus we simulate wait with sleep method. - print("---set inventory, wait 60 seconds:---") - time.sleep(60) + print("---set inventory, wait 90 seconds:---") + time.sleep(90) create_product(product_id) diff --git a/samples/interactive-tutorials/product/setup_product/products_create_gcs_bucket.py b/samples/interactive-tutorials/product/setup_product/products_create_gcs_bucket.py index 3d84635b..fe976d7a 100644 --- a/samples/interactive-tutorials/product/setup_product/products_create_gcs_bucket.py +++ b/samples/interactive-tutorials/product/setup_product/products_create_gcs_bucket.py @@ -20,10 +20,10 @@ project_id = google.auth.default()[1] timestamp_ = datetime.datetime.now().timestamp().__round__() -bucket_name = "{}_products_{}".format(project_id, timestamp_) +bucket_name = f"{project_id}_products_{timestamp_}" create_bucket(bucket_name) upload_blob(bucket_name, "../resources/products.json") upload_blob(bucket_name, "../resources/products_some_invalid.json") -print("\nThe gcs bucket {} was created".format(bucket_name)) +print(f"\nThe gcs bucket {bucket_name} was created") diff --git a/samples/interactive-tutorials/product/setup_product/setup_cleanup.py b/samples/interactive-tutorials/product/setup_product/setup_cleanup.py index c0232c74..31a6a4f9 100644 --- a/samples/interactive-tutorials/product/setup_product/setup_cleanup.py +++ b/samples/interactive-tutorials/product/setup_product/setup_cleanup.py @@ -101,16 +101,14 @@ def create_bucket(bucket_name: str): print("Creating new bucket:" + bucket_name) buckets_in_your_project = list_buckets() if bucket_name in buckets_in_your_project: - print("Bucket {} already exists".format(bucket_name)) + print(f"Bucket {bucket_name} already exists") else: storage_client = storage.Client() bucket = storage_client.bucket(bucket_name) bucket.storage_class = "STANDARD" new_bucket = storage_client.create_bucket(bucket, location="us") print( - "Created bucket {} in {} with storage class {}".format( - new_bucket.name, new_bucket.location, new_bucket.storage_class - ) + f"Created bucket {new_bucket.name} in {new_bucket.location} with storage class {new_bucket.storage_class}" ) return new_bucket @@ -126,9 +124,9 @@ def delete_bucket(bucket_name: str): blob.delete() bucket = storage_client.get_bucket(bucket_name) bucket.delete() - print("Bucket {} is deleted".format(bucket.name)) + print(f"Bucket {bucket.name} is deleted") else: - print("Bucket {} is not found".format(bucket_name)) + print(f"Bucket {bucket_name} is not found") def list_buckets(): @@ -145,8 +143,7 @@ def upload_blob(bucket_name, source_file_name): """Uploads a file to the bucket.""" # The path to your file to upload # source_file_name = "local/path/to/file" - print("Uploading data from {} to the bucket {}".format(source_file_name, - bucket_name)) + print(f"Uploading data from {source_file_name} to the bucket {bucket_name}") storage_client = storage.Client() bucket = storage_client.bucket(bucket_name) object_name = re.search('resources/(.*?)$', source_file_name).group(1) @@ -154,9 +151,7 @@ def upload_blob(bucket_name, source_file_name): blob.upload_from_filename(source_file_name) print( - "File {} uploaded to {}.".format( - source_file_name, object_name - ) + f"File {source_file_name} uploaded to {object_name}." ) @@ -180,24 +175,26 @@ def create_bq_table(dataset, table_name, schema_file_path): """Create a BigQuery table""" full_table_id = f"{project_id}.{dataset}.{table_name}" bq = bigquery.Client() - print(f"Creating BigQuery table {full_table_id}") + print(f"Check if BQ table {full_table_id} exists") try: bq.get_table(full_table_id) - print(f"table {full_table_id} already exists") + print(f"table {full_table_id} exists and will be deleted") + delete_bq_table(dataset, table_name) except NotFound: - # Construct a Table object to send to the API. - with open(schema_file_path, "rb") as schema: - schema_dict = json.load(schema) - table = bigquery.Table(full_table_id, schema=schema_dict) - bq.create_table(table) - print("table is created") + print(f"table {full_table_id} does not exist") + # Construct a Table object to send to the API. + with open(schema_file_path, "rb") as schema: + schema_dict = json.load(schema) + table = bigquery.Table(full_table_id, schema=schema_dict) + bq.create_table(table) + print(f"table {full_table_id} is created") def delete_bq_table(dataset, table_name): full_table_id = f"{project_id}.{dataset}.{table_name}" bq = bigquery.Client() bq.delete_table(full_table_id, not_found_ok=True) - print("Table '{}' is deleted.".format(full_table_id)) + print(f"Table '{full_table_id}' is deleted.") def upload_data_to_bq_table(dataset, table_name, source, schema_file_path): diff --git a/samples/interactive-tutorials/product/update_product.py b/samples/interactive-tutorials/product/update_product.py index 9a10153a..e3abef98 100644 --- a/samples/interactive-tutorials/product/update_product.py +++ b/samples/interactive-tutorials/product/update_product.py @@ -30,10 +30,6 @@ from setup_product.setup_cleanup import create_product, delete_product -# from google.protobuf.field_mask_pb2 import FieldMask -# from google.protobuf.field_mask_pb2 import FieldMask - - project_id = google.auth.default()[1] default_branch_name = ( "projects/" diff --git a/samples/interactive-tutorials/search/noxfile.py b/samples/interactive-tutorials/search/noxfile.py index 85f5836d..25f87a21 100644 --- a/samples/interactive-tutorials/search/noxfile.py +++ b/samples/interactive-tutorials/search/noxfile.py @@ -29,7 +29,7 @@ # WARNING - WARNING - WARNING - WARNING - WARNING # WARNING - WARNING - WARNING - WARNING - WARNING -BLACK_VERSION = "black==19.10b0" +BLACK_VERSION = "black==22.3.0" # Copy `noxfile_config.py` to your directory and modify it instead. @@ -253,7 +253,7 @@ def py(session: nox.sessions.Session) -> None: def _get_repo_root() -> Optional[str]: - """ Returns the root folder of the project. """ + """Returns the root folder of the project.""" # Get root of this repository. Assume we don't have directories nested deeper than 10 items. p = Path(os.getcwd()) for i in range(10): diff --git a/samples/interactive-tutorials/search/requirements-test.txt b/samples/interactive-tutorials/search/requirements-test.txt index 15960cd4..8f3c5c3d 100644 --- a/samples/interactive-tutorials/search/requirements-test.txt +++ b/samples/interactive-tutorials/search/requirements-test.txt @@ -1,2 +1,2 @@ -pytest==7.0.1 +pytest==7.1.1 pytest-xdist==2.5.0 diff --git a/samples/interactive-tutorials/search/requirements.txt b/samples/interactive-tutorials/search/requirements.txt index 8f64bc7a..829efe7c 100644 --- a/samples/interactive-tutorials/search/requirements.txt +++ b/samples/interactive-tutorials/search/requirements.txt @@ -1,4 +1,4 @@ google==3.0.0 -google-cloud-retail==1.4.0 -google-cloud-storage==2.1.0 -google-cloud-bigquery==2.34.1 \ No newline at end of file +google-cloud-retail==1.4.1 +google-cloud-storage==2.2.1 +google-cloud-bigquery==2.34.3 \ No newline at end of file diff --git a/samples/interactive-tutorials/test_resources_recovery/create_test_resources.py b/samples/interactive-tutorials/test_resources_recovery/create_test_resources.py index b81f84b3..756bb4fe 100644 --- a/samples/interactive-tutorials/test_resources_recovery/create_test_resources.py +++ b/samples/interactive-tutorials/test_resources_recovery/create_test_resources.py @@ -50,16 +50,14 @@ def create_bucket(bucket_name: str) -> Bucket: print("Creating new bucket:" + bucket_name) bucket_exists = check_if_bucket_exists(bucket_name) if bucket_exists: - print("Bucket {} already exists".format(bucket_name)) + print(f"Bucket {bucket_name} already exists") return storage_client.bucket(bucket_name) else: bucket = storage_client.bucket(bucket_name) bucket.storage_class = "STANDARD" new_bucket = storage_client.create_bucket(bucket, location="us") print( - "Created bucket {} in {} with storage class {}".format( - new_bucket.name, new_bucket.location, new_bucket.storage_class - ) + f"Created bucket {new_bucket.name} in {new_bucket.location} with storage class {new_bucket.storage_class}" ) return new_bucket @@ -79,17 +77,16 @@ def upload_data_to_bucket(bucket: Bucket): """Upload data to a GCS bucket""" blob = bucket.blob(object_name) blob.upload_from_filename(product_resource_file) - print("Data from {} has being uploaded to {}".format(product_resource_file, - bucket.name)) + print(f"Data from {product_resource_file} has being uploaded to {bucket.name}") def get_import_products_gcs_request(): """Get import products from gcs request""" - gcs_bucket = "gs://{}".format(products_bucket_name) - gcs_errors_bucket = "{}/error".format(gcs_bucket) + gcs_bucket = f"gs://{products_bucket_name}" + gcs_errors_bucket = f"{gcs_bucket}/error" gcs_source = GcsSource() - gcs_source.input_uris = ["{0}/{1}".format(gcs_bucket, object_name)] + gcs_source.input_uris = [f"{gcs_bucket}/{object_name}"] input_config = ProductInputConfig() input_config.gcs_source = gcs_source @@ -115,7 +112,7 @@ def import_products_from_gcs(): gcs_operation = ProductServiceClient().import_products( import_gcs_request) print( - "Import operation is started: {}".format(gcs_operation.operation.name)) + f"Import operation is started: {gcs_operation.operation.name}") while not gcs_operation.done(): print("Please wait till operation is completed") @@ -137,13 +134,12 @@ def import_products_from_gcs(): def create_bq_dataset(dataset_name): """Create a BigQuery dataset""" - print("Creating dataset {}".format(dataset_name)) + print(f"Creating dataset {dataset_name}") try: list_bq_dataset(project_id, dataset_name) - print("dataset {} already exists".format(dataset_name)) + print(f"dataset {dataset_name} already exists") except subprocess.CalledProcessError: - create_dataset_command = 'bq --location=US mk -d --default_table_expiration 3600 --description "This is my dataset." {}:{}'.format( - project_id, dataset_name) + create_dataset_command = f'bq --location=US mk -d --default_table_expiration 3600 --description "This is my dataset." {project_id}:{dataset_name}' subprocess.check_output(shlex.split(create_dataset_command)) print("dataset is created") @@ -157,32 +153,27 @@ def list_bq_dataset(project_id: str, dataset_name: str): def create_bq_table(dataset, table_name, schema): """Create a BigQuery table""" - print("Creating BigQuery table {}".format(table_name)) + print(f"Creating BigQuery table {table_name}") if table_name not in list_bq_tables(dataset): - create_table_command = "bq mk --table {}:{}.{} {}".format( - project_id, - dataset, - table_name, schema) + create_table_command = f"bq mk --table {project_id}:{dataset}.{table_name} {schema}" output = subprocess.check_output(shlex.split(create_table_command)) print(output) print("table is created") else: - print("table {} already exists".format(table_name)) + print(f"table {table_name} already exists") def list_bq_tables(dataset): """List BigQuery tables in the dataset""" - list_tables_command = "bq ls {}:{}".format(project_id, dataset) + list_tables_command = f"bq ls {project_id}:{dataset}" tables = subprocess.check_output(shlex.split(list_tables_command)) return str(tables) def upload_data_to_bq_table(dataset, table_name, source, schema): """Upload data to the table from specified source file""" - print("Uploading data from {} to the table {}.{}".format(source, dataset, - table_name)) - upload_data_command = "bq load --source_format=NEWLINE_DELIMITED_JSON {}:{}.{} {} {}".format( - project_id, dataset, table_name, source, schema) + print(f"Uploading data from {source} to the table {dataset}.{table_name}") + upload_data_command = f"bq load --source_format=NEWLINE_DELIMITED_JSON {project_id}:{dataset}.{table_name} {source} {schema}" output = subprocess.check_output(shlex.split(upload_data_command)) print(output) diff --git a/samples/interactive-tutorials/test_resources_recovery/remove_test_resources.py b/samples/interactive-tutorials/test_resources_recovery/remove_test_resources.py index 0d2247de..63e6d64f 100644 --- a/samples/interactive-tutorials/test_resources_recovery/remove_test_resources.py +++ b/samples/interactive-tutorials/test_resources_recovery/remove_test_resources.py @@ -41,11 +41,11 @@ def delete_bucket(bucket_name): try: bucket = storage_client.get_bucket(bucket_name) except NotFound: - print("Bucket {} does not exists".format(bucket_name)) + print(f"Bucket {bucket_name} does not exists") else: delete_object_from_bucket(bucket) bucket.delete() - print("bucket {} is deleted".format(bucket_name)) + print(f"bucket {bucket_name} is deleted") def delete_object_from_bucket(bucket: Bucket): @@ -53,7 +53,7 @@ def delete_object_from_bucket(bucket: Bucket): blobs = bucket.list_blobs() for blob in blobs: blob.delete() - print("all objects are deleted from GCS bucket {}".format(bucket.name)) + print(f"all objects are deleted from GCS bucket {bucket.name}") def delete_all_products(): @@ -78,7 +78,7 @@ def delete_all_products(): def delete_bq_dataset_with_tables(dataset): """Delete a BigQuery dataset with all tables""" - delete_dataset_command = "bq rm -r -d -f {}".format(dataset) + delete_dataset_command = f"bq rm -r -d -f {dataset}" output = subprocess.check_output(shlex.split(delete_dataset_command)) print(output) diff --git a/samples/interactive-tutorials/user_environment_setup.sh b/samples/interactive-tutorials/user_environment_setup.sh new file mode 100644 index 00000000..93c746a0 --- /dev/null +++ b/samples/interactive-tutorials/user_environment_setup.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +# Copyright 2022 Google Inc. All Rights Reserved. +# +# 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. + +# set the Google Cloud project Id +project_id=$1 +echo Project ID: $project_id +gcloud config set project project_id + +timestamp=$(date +%s) + +service_account_id="service-acc-"$timestamp +echo Service Account: $service_account_id + +# create service account (your project_id+timestamp) +gcloud iam service-accounts create $service_account_id + +# assign needed roles to your new service account +for role in {retail.admin,editor,bigquery.admin} + do + gcloud projects add-iam-policy-binding $project_id --member="serviceAccount:"$service_account_id"@"$project_id".iam.gserviceaccount.com" --role="roles/${role}" +done + +echo Wait 70 seconds to be sure the appropriate roles have been assigned to your service account +sleep 70 + +# upload your service account key file +service_acc_email=$service_account_id"@"$project_id".iam.gserviceaccount.com" +gcloud iam service-accounts keys create ~/key.json --iam-account $service_acc_email + +# activate the service account using the key +gcloud auth activate-service-account --key-file ~/key.json + +# install needed Google client libraries +virtualenv -p python3 myenv +source myenv/bin/activate +sleep 2 + +pip install google +pip install google-cloud-retail +pip install google-cloud.storage +pip install google-cloud.bigquery + +echo ======================================== +echo "The Google Cloud setup is completed." +echo "Please proceed with the Tutorial steps" +echo ======================================== \ No newline at end of file diff --git a/samples/interactive-tutorials/user_import_data_to_catalog.sh b/samples/interactive-tutorials/user_import_data_to_catalog.sh new file mode 100644 index 00000000..af423656 --- /dev/null +++ b/samples/interactive-tutorials/user_import_data_to_catalog.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# Copyright 2022 Google Inc. All Rights Reserved. +# +# 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. + +# set the service account key as a GOOGLE_APPLICATION_CREDENTIALS +export GOOGLE_APPLICATION_CREDENTIALS=~/key.json + +# activate the python virtual env +source ~/cloudshell_open/myenv/bin/activate + +# Create a GCS bucket and upload the product data to the bucket +output=$(python ~/cloudshell_open/python-retail/samples/interactive-tutorials/product/setup_product/products_create_gcs_bucket.py) + +# Get the bucket name and store it in the env variable BUCKET_NAME +temp="${output#*The gcs bucket }" +bucket_name="${temp% was created*}" +export BUCKET_NAME=$bucket_name + +# Import products to the Retail catalog +python ~/cloudshell_open/python-retail/samples/interactive-tutorials/product/import_products_gcs.py + +echo ===================================== +echo "Your Retail catalog is ready to use!" +echo ===================================== \ No newline at end of file diff --git a/scripts/fixup_retail_v2_keywords.py b/scripts/fixup_retail_v2_keywords.py index 4452e8a4..e4946a58 100644 --- a/scripts/fixup_retail_v2_keywords.py +++ b/scripts/fixup_retail_v2_keywords.py @@ -40,6 +40,7 @@ class retailCallTransformer(cst.CSTTransformer): CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { 'add_fulfillment_places': ('product', 'type_', 'place_ids', 'add_time', 'allow_missing', ), + 'add_local_inventories': ('product', 'local_inventories', 'add_mask', 'add_time', 'allow_missing', ), 'collect_user_event': ('parent', 'user_event', 'uri', 'ets', ), 'complete_query': ('catalog', 'query', 'visitor_id', 'language_codes', 'device_type', 'dataset', 'max_suggestions', ), 'create_product': ('parent', 'product', 'product_id', ), @@ -55,8 +56,9 @@ class retailCallTransformer(cst.CSTTransformer): 'purge_user_events': ('parent', 'filter', 'force', ), 'rejoin_user_events': ('parent', 'user_event_rejoin_scope', ), 'remove_fulfillment_places': ('product', 'type_', 'place_ids', 'remove_time', 'allow_missing', ), - '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', ), - 'set_default_branch': ('catalog', 'branch_id', 'note', ), + 'remove_local_inventories': ('product', 'place_ids', 'remove_time', 'allow_missing', ), + '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', ), + 'set_default_branch': ('catalog', 'branch_id', 'note', 'force', ), 'set_inventory': ('inventory', 'set_mask', 'set_time', 'allow_missing', ), 'update_catalog': ('catalog', 'update_mask', ), 'update_product': ('product', 'update_mask', 'allow_missing', ), diff --git a/setup.py b/setup.py index c1a43a25..aaedad21 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ import os import setuptools # type: ignore -version = "1.4.1" +version = "1.5.0" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -48,7 +48,9 @@ "proto-plus >= 1.15.0", ), python_requires=">=3.6", - scripts=["scripts/fixup_retail_v2_keywords.py",], + scripts=[ + "scripts/fixup_retail_v2_keywords.py", + ], classifiers=[ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", diff --git a/tests/unit/gapic/retail_v2/test_catalog_service.py b/tests/unit/gapic/retail_v2/test_catalog_service.py index 9700caab..4550effa 100644 --- a/tests/unit/gapic/retail_v2/test_catalog_service.py +++ b/tests/unit/gapic/retail_v2/test_catalog_service.py @@ -89,7 +89,11 @@ def test__get_default_mtls_endpoint(): @pytest.mark.parametrize( - "client_class", [CatalogServiceClient, CatalogServiceAsyncClient,] + "client_class", + [ + CatalogServiceClient, + CatalogServiceAsyncClient, + ], ) def test_catalog_service_client_from_service_account_info(client_class): creds = ga_credentials.AnonymousCredentials() @@ -131,7 +135,11 @@ def test_catalog_service_client_service_account_always_use_jwt( @pytest.mark.parametrize( - "client_class", [CatalogServiceClient, CatalogServiceAsyncClient,] + "client_class", + [ + CatalogServiceClient, + CatalogServiceAsyncClient, + ], ) def test_catalog_service_client_from_service_account_file(client_class): creds = ga_credentials.AnonymousCredentials() @@ -495,7 +503,9 @@ def test_catalog_service_client_client_options_scopes( client_class, transport_class, transport_name ): # Check the case scopes are provided. - options = client_options.ClientOptions(scopes=["1", "2"],) + 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) @@ -635,10 +645,17 @@ def test_catalog_service_client_create_channel_credentials_file( ) -@pytest.mark.parametrize("request_type", [catalog_service.ListCatalogsRequest, dict,]) +@pytest.mark.parametrize( + "request_type", + [ + catalog_service.ListCatalogsRequest, + dict, + ], +) def test_list_catalogs(request_type, transport: str = "grpc"): client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -667,7 +684,8 @@ def test_list_catalogs_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", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -683,7 +701,8 @@ async def test_list_catalogs_async( transport: str = "grpc_asyncio", request_type=catalog_service.ListCatalogsRequest ): client = CatalogServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -716,7 +735,9 @@ async def test_list_catalogs_async_from_dict(): def test_list_catalogs_field_headers(): - client = CatalogServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + 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. @@ -736,7 +757,10 @@ def test_list_catalogs_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "parent=parent/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -765,11 +789,16 @@ async def test_list_catalogs_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "parent=parent/value", + ) in kw["metadata"] def test_list_catalogs_flattened(): - client = CatalogServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.list_catalogs), "__call__") as call: @@ -777,7 +806,9 @@ def test_list_catalogs_flattened(): call.return_value = catalog_service.ListCatalogsResponse() # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. - client.list_catalogs(parent="parent_value",) + client.list_catalogs( + parent="parent_value", + ) # Establish that the underlying call was made with the expected # request object values. @@ -789,13 +820,16 @@ def test_list_catalogs_flattened(): def test_list_catalogs_flattened_error(): - client = CatalogServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = CatalogServiceClient( + 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_catalogs( - catalog_service.ListCatalogsRequest(), parent="parent_value", + catalog_service.ListCatalogsRequest(), + parent="parent_value", ) @@ -815,7 +849,9 @@ async def test_list_catalogs_flattened_async(): ) # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. - response = await client.list_catalogs(parent="parent_value",) + response = await client.list_catalogs( + parent="parent_value", + ) # Establish that the underlying call was made with the expected # request object values. @@ -836,13 +872,15 @@ async def test_list_catalogs_flattened_error_async(): # fields is an error. with pytest.raises(ValueError): await client.list_catalogs( - catalog_service.ListCatalogsRequest(), parent="parent_value", + catalog_service.ListCatalogsRequest(), + parent="parent_value", ) def test_list_catalogs_pager(transport_name: str = "grpc"): client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials, transport=transport_name, + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, ) # Mock the actual call within the gRPC stub, and fake the request. @@ -850,15 +888,28 @@ def test_list_catalogs_pager(transport_name: str = "grpc"): # Set the response to a series of pages. call.side_effect = ( catalog_service.ListCatalogsResponse( - catalogs=[catalog.Catalog(), catalog.Catalog(), catalog.Catalog(),], + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + catalog.Catalog(), + ], next_page_token="abc", ), - catalog_service.ListCatalogsResponse(catalogs=[], next_page_token="def",), catalog_service.ListCatalogsResponse( - catalogs=[catalog.Catalog(),], next_page_token="ghi", + catalogs=[], + next_page_token="def", + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + ], + next_page_token="ghi", ), catalog_service.ListCatalogsResponse( - catalogs=[catalog.Catalog(), catalog.Catalog(),], + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], ), RuntimeError, ) @@ -878,7 +929,8 @@ def test_list_catalogs_pager(transport_name: str = "grpc"): def test_list_catalogs_pages(transport_name: str = "grpc"): client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials, transport=transport_name, + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, ) # Mock the actual call within the gRPC stub, and fake the request. @@ -886,15 +938,28 @@ def test_list_catalogs_pages(transport_name: str = "grpc"): # Set the response to a series of pages. call.side_effect = ( catalog_service.ListCatalogsResponse( - catalogs=[catalog.Catalog(), catalog.Catalog(), catalog.Catalog(),], + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + catalog.Catalog(), + ], next_page_token="abc", ), - catalog_service.ListCatalogsResponse(catalogs=[], next_page_token="def",), catalog_service.ListCatalogsResponse( - catalogs=[catalog.Catalog(),], next_page_token="ghi", + catalogs=[], + next_page_token="def", ), catalog_service.ListCatalogsResponse( - catalogs=[catalog.Catalog(), catalog.Catalog(),], + catalogs=[ + catalog.Catalog(), + ], + next_page_token="ghi", + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], ), RuntimeError, ) @@ -905,7 +970,9 @@ def test_list_catalogs_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_catalogs_async_pager(): - client = CatalogServiceAsyncClient(credentials=ga_credentials.AnonymousCredentials,) + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( @@ -914,19 +981,34 @@ async def test_list_catalogs_async_pager(): # Set the response to a series of pages. call.side_effect = ( catalog_service.ListCatalogsResponse( - catalogs=[catalog.Catalog(), catalog.Catalog(), catalog.Catalog(),], + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + catalog.Catalog(), + ], next_page_token="abc", ), - catalog_service.ListCatalogsResponse(catalogs=[], next_page_token="def",), catalog_service.ListCatalogsResponse( - catalogs=[catalog.Catalog(),], next_page_token="ghi", + catalogs=[], + next_page_token="def", + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + ], + next_page_token="ghi", ), catalog_service.ListCatalogsResponse( - catalogs=[catalog.Catalog(), catalog.Catalog(),], + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], ), RuntimeError, ) - async_pager = await client.list_catalogs(request={},) + async_pager = await client.list_catalogs( + request={}, + ) assert async_pager.next_page_token == "abc" responses = [] async for response in async_pager: @@ -938,7 +1020,9 @@ async def test_list_catalogs_async_pager(): @pytest.mark.asyncio async def test_list_catalogs_async_pages(): - client = CatalogServiceAsyncClient(credentials=ga_credentials.AnonymousCredentials,) + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( @@ -947,15 +1031,28 @@ async def test_list_catalogs_async_pages(): # Set the response to a series of pages. call.side_effect = ( catalog_service.ListCatalogsResponse( - catalogs=[catalog.Catalog(), catalog.Catalog(), catalog.Catalog(),], + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + catalog.Catalog(), + ], next_page_token="abc", ), - catalog_service.ListCatalogsResponse(catalogs=[], next_page_token="def",), catalog_service.ListCatalogsResponse( - catalogs=[catalog.Catalog(),], next_page_token="ghi", + catalogs=[], + next_page_token="def", + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + ], + next_page_token="ghi", ), catalog_service.ListCatalogsResponse( - catalogs=[catalog.Catalog(), catalog.Catalog(),], + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], ), RuntimeError, ) @@ -966,10 +1063,17 @@ async def test_list_catalogs_async_pages(): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize("request_type", [catalog_service.UpdateCatalogRequest, dict,]) +@pytest.mark.parametrize( + "request_type", + [ + catalog_service.UpdateCatalogRequest, + dict, + ], +) def test_update_catalog(request_type, transport: str = "grpc"): client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -980,7 +1084,8 @@ def test_update_catalog(request_type, transport: str = "grpc"): with mock.patch.object(type(client.transport.update_catalog), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = gcr_catalog.Catalog( - name="name_value", display_name="display_name_value", + name="name_value", + display_name="display_name_value", ) response = client.update_catalog(request) @@ -999,7 +1104,8 @@ def test_update_catalog_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", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1015,7 +1121,8 @@ async def test_update_catalog_async( transport: str = "grpc_asyncio", request_type=catalog_service.UpdateCatalogRequest ): client = CatalogServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1026,7 +1133,10 @@ async def test_update_catalog_async( with mock.patch.object(type(client.transport.update_catalog), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - gcr_catalog.Catalog(name="name_value", display_name="display_name_value",) + gcr_catalog.Catalog( + name="name_value", + display_name="display_name_value", + ) ) response = await client.update_catalog(request) @@ -1047,7 +1157,9 @@ async def test_update_catalog_async_from_dict(): def test_update_catalog_field_headers(): - client = CatalogServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + 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. @@ -1067,9 +1179,10 @@ def test_update_catalog_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "catalog.name=catalog.name/value",) in kw[ - "metadata" - ] + assert ( + "x-goog-request-params", + "catalog.name=catalog.name/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -1096,13 +1209,16 @@ async def test_update_catalog_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "catalog.name=catalog.name/value",) in kw[ - "metadata" - ] + assert ( + "x-goog-request-params", + "catalog.name=catalog.name/value", + ) in kw["metadata"] def test_update_catalog_flattened(): - client = CatalogServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.update_catalog), "__call__") as call: @@ -1128,7 +1244,9 @@ def test_update_catalog_flattened(): def test_update_catalog_flattened_error(): - client = CatalogServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) # Attempting to call a method with both a request object and flattened # fields is an error. @@ -1188,11 +1306,16 @@ async def test_update_catalog_flattened_error_async(): @pytest.mark.parametrize( - "request_type", [catalog_service.SetDefaultBranchRequest, dict,] + "request_type", + [ + catalog_service.SetDefaultBranchRequest, + dict, + ], ) def test_set_default_branch(request_type, transport: str = "grpc"): client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1220,7 +1343,8 @@ def test_set_default_branch_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", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1239,7 +1363,8 @@ async def test_set_default_branch_async( request_type=catalog_service.SetDefaultBranchRequest, ): client = CatalogServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1269,7 +1394,9 @@ async def test_set_default_branch_async_from_dict(): def test_set_default_branch_field_headers(): - client = CatalogServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + 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. @@ -1291,7 +1418,10 @@ def test_set_default_branch_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "catalog=catalog/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "catalog=catalog/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -1320,11 +1450,16 @@ async def test_set_default_branch_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "catalog=catalog/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "catalog=catalog/value", + ) in kw["metadata"] def test_set_default_branch_flattened(): - client = CatalogServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( @@ -1334,7 +1469,9 @@ def test_set_default_branch_flattened(): call.return_value = None # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. - client.set_default_branch(catalog="catalog_value",) + client.set_default_branch( + catalog="catalog_value", + ) # Establish that the underlying call was made with the expected # request object values. @@ -1346,13 +1483,16 @@ def test_set_default_branch_flattened(): def test_set_default_branch_flattened_error(): - client = CatalogServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = CatalogServiceClient( + 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.set_default_branch( - catalog_service.SetDefaultBranchRequest(), catalog="catalog_value", + catalog_service.SetDefaultBranchRequest(), + catalog="catalog_value", ) @@ -1372,7 +1512,9 @@ async def test_set_default_branch_flattened_async(): 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.set_default_branch(catalog="catalog_value",) + response = await client.set_default_branch( + catalog="catalog_value", + ) # Establish that the underlying call was made with the expected # request object values. @@ -1393,16 +1535,22 @@ async def test_set_default_branch_flattened_error_async(): # fields is an error. with pytest.raises(ValueError): await client.set_default_branch( - catalog_service.SetDefaultBranchRequest(), catalog="catalog_value", + catalog_service.SetDefaultBranchRequest(), + catalog="catalog_value", ) @pytest.mark.parametrize( - "request_type", [catalog_service.GetDefaultBranchRequest, dict,] + "request_type", + [ + catalog_service.GetDefaultBranchRequest, + dict, + ], ) def test_get_default_branch(request_type, transport: str = "grpc"): client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1415,7 +1563,8 @@ def test_get_default_branch(request_type, transport: str = "grpc"): ) as call: # Designate an appropriate return value for the call. call.return_value = catalog_service.GetDefaultBranchResponse( - branch="branch_value", note="note_value", + branch="branch_value", + note="note_value", ) response = client.get_default_branch(request) @@ -1434,7 +1583,8 @@ def test_get_default_branch_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", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1453,7 +1603,8 @@ async def test_get_default_branch_async( request_type=catalog_service.GetDefaultBranchRequest, ): client = CatalogServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1467,7 +1618,8 @@ async def test_get_default_branch_async( # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( catalog_service.GetDefaultBranchResponse( - branch="branch_value", note="note_value", + branch="branch_value", + note="note_value", ) ) response = await client.get_default_branch(request) @@ -1489,7 +1641,9 @@ async def test_get_default_branch_async_from_dict(): def test_get_default_branch_field_headers(): - client = CatalogServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + 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. @@ -1511,7 +1665,10 @@ def test_get_default_branch_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "catalog=catalog/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "catalog=catalog/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -1542,11 +1699,16 @@ async def test_get_default_branch_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "catalog=catalog/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "catalog=catalog/value", + ) in kw["metadata"] def test_get_default_branch_flattened(): - client = CatalogServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( @@ -1556,7 +1718,9 @@ def test_get_default_branch_flattened(): call.return_value = catalog_service.GetDefaultBranchResponse() # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. - client.get_default_branch(catalog="catalog_value",) + client.get_default_branch( + catalog="catalog_value", + ) # Establish that the underlying call was made with the expected # request object values. @@ -1568,13 +1732,16 @@ def test_get_default_branch_flattened(): def test_get_default_branch_flattened_error(): - client = CatalogServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): client.get_default_branch( - catalog_service.GetDefaultBranchRequest(), catalog="catalog_value", + catalog_service.GetDefaultBranchRequest(), + catalog="catalog_value", ) @@ -1596,7 +1763,9 @@ async def test_get_default_branch_flattened_async(): ) # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. - response = await client.get_default_branch(catalog="catalog_value",) + response = await client.get_default_branch( + catalog="catalog_value", + ) # Establish that the underlying call was made with the expected # request object values. @@ -1617,7 +1786,8 @@ async def test_get_default_branch_flattened_error_async(): # fields is an error. with pytest.raises(ValueError): await client.get_default_branch( - catalog_service.GetDefaultBranchRequest(), catalog="catalog_value", + catalog_service.GetDefaultBranchRequest(), + catalog="catalog_value", ) @@ -1628,7 +1798,8 @@ def test_credentials_transport_error(): ) with pytest.raises(ValueError): client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # It is an error to provide a credentials file and a transport instance. @@ -1648,7 +1819,10 @@ def test_credentials_transport_error(): options = client_options.ClientOptions() options.api_key = "api_key" with pytest.raises(ValueError): - client = CatalogServiceClient(client_options=options, transport=transport,) + client = CatalogServiceClient( + client_options=options, + transport=transport, + ) # It is an error to provide an api_key and a credential. options = mock.Mock() @@ -1664,7 +1838,8 @@ def test_credentials_transport_error(): ) with pytest.raises(ValueError): client = CatalogServiceClient( - client_options={"scopes": ["1", "2"]}, transport=transport, + client_options={"scopes": ["1", "2"]}, + transport=transport, ) @@ -1709,8 +1884,13 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. - client = CatalogServiceClient(credentials=ga_credentials.AnonymousCredentials(),) - assert isinstance(client.transport, transports.CatalogServiceGrpcTransport,) + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.CatalogServiceGrpcTransport, + ) def test_catalog_service_base_transport_error(): @@ -1758,7 +1938,8 @@ def test_catalog_service_base_transport_with_credentials_file(): Transport.return_value = None load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.CatalogServiceTransport( - credentials_file="credentials.json", quota_project_id="octopus", + credentials_file="credentials.json", + quota_project_id="octopus", ) load_creds.assert_called_once_with( "credentials.json", @@ -1916,7 +2097,8 @@ def test_catalog_service_grpc_transport_channel(): # Check that channel is used if provided. transport = transports.CatalogServiceGrpcTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" @@ -1928,7 +2110,8 @@ def test_catalog_service_grpc_asyncio_transport_channel(): # Check that channel is used if provided. transport = transports.CatalogServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" @@ -2041,7 +2224,10 @@ def test_branch_path(): catalog = "whelk" branch = "octopus" expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format( - project=project, location=location, catalog=catalog, branch=branch, + project=project, + location=location, + catalog=catalog, + branch=branch, ) actual = CatalogServiceClient.branch_path(project, location, catalog, branch) assert expected == actual @@ -2066,7 +2252,9 @@ def test_catalog_path(): location = "nautilus" catalog = "scallop" expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format( - project=project, location=location, catalog=catalog, + project=project, + location=location, + catalog=catalog, ) actual = CatalogServiceClient.catalog_path(project, location, catalog) assert expected == actual @@ -2107,7 +2295,9 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): folder = "oyster" - expected = "folders/{folder}".format(folder=folder,) + expected = "folders/{folder}".format( + folder=folder, + ) actual = CatalogServiceClient.common_folder_path(folder) assert expected == actual @@ -2125,7 +2315,9 @@ def test_parse_common_folder_path(): def test_common_organization_path(): organization = "cuttlefish" - expected = "organizations/{organization}".format(organization=organization,) + expected = "organizations/{organization}".format( + organization=organization, + ) actual = CatalogServiceClient.common_organization_path(organization) assert expected == actual @@ -2143,7 +2335,9 @@ def test_parse_common_organization_path(): def test_common_project_path(): project = "winkle" - expected = "projects/{project}".format(project=project,) + expected = "projects/{project}".format( + project=project, + ) actual = CatalogServiceClient.common_project_path(project) assert expected == actual @@ -2163,7 +2357,8 @@ def test_common_location_path(): project = "scallop" location = "abalone" expected = "projects/{project}/locations/{location}".format( - project=project, location=location, + project=project, + location=location, ) actual = CatalogServiceClient.common_location_path(project, location) assert expected == actual @@ -2188,7 +2383,8 @@ def test_client_with_default_client_info(): transports.CatalogServiceTransport, "_prep_wrapped_messages" ) as prep: client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -2197,7 +2393,8 @@ def test_client_with_default_client_info(): ) as prep: transport_class = CatalogServiceClient.get_transport_class() transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -2205,7 +2402,8 @@ def test_client_with_default_client_info(): @pytest.mark.asyncio async def test_transport_close_async(): client = CatalogServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", ) with mock.patch.object( type(getattr(client.transport, "grpc_channel")), "close" diff --git a/tests/unit/gapic/retail_v2/test_completion_service.py b/tests/unit/gapic/retail_v2/test_completion_service.py index adfd469f..0661b182 100644 --- a/tests/unit/gapic/retail_v2/test_completion_service.py +++ b/tests/unit/gapic/retail_v2/test_completion_service.py @@ -94,7 +94,11 @@ def test__get_default_mtls_endpoint(): @pytest.mark.parametrize( - "client_class", [CompletionServiceClient, CompletionServiceAsyncClient,] + "client_class", + [ + CompletionServiceClient, + CompletionServiceAsyncClient, + ], ) def test_completion_service_client_from_service_account_info(client_class): creds = ga_credentials.AnonymousCredentials() @@ -136,7 +140,11 @@ def test_completion_service_client_service_account_always_use_jwt( @pytest.mark.parametrize( - "client_class", [CompletionServiceClient, CompletionServiceAsyncClient,] + "client_class", + [ + CompletionServiceClient, + CompletionServiceAsyncClient, + ], ) def test_completion_service_client_from_service_account_file(client_class): creds = ga_credentials.AnonymousCredentials() @@ -510,7 +518,9 @@ def test_completion_service_client_client_options_scopes( client_class, transport_class, transport_name ): # Check the case scopes are provided. - options = client_options.ClientOptions(scopes=["1", "2"],) + 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) @@ -651,11 +661,16 @@ def test_completion_service_client_create_channel_credentials_file( @pytest.mark.parametrize( - "request_type", [completion_service.CompleteQueryRequest, dict,] + "request_type", + [ + completion_service.CompleteQueryRequest, + dict, + ], ) def test_complete_query(request_type, transport: str = "grpc"): client = CompletionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -684,7 +699,8 @@ def test_complete_query_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 = CompletionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -701,7 +717,8 @@ async def test_complete_query_async( request_type=completion_service.CompleteQueryRequest, ): client = CompletionServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -734,7 +751,9 @@ async def test_complete_query_async_from_dict(): def test_complete_query_field_headers(): - client = CompletionServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = CompletionServiceClient( + 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. @@ -754,7 +773,10 @@ def test_complete_query_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "catalog=catalog/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "catalog=catalog/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -783,15 +805,23 @@ async def test_complete_query_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "catalog=catalog/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "catalog=catalog/value", + ) in kw["metadata"] @pytest.mark.parametrize( - "request_type", [import_config.ImportCompletionDataRequest, dict,] + "request_type", + [ + import_config.ImportCompletionDataRequest, + dict, + ], ) def test_import_completion_data(request_type, transport: str = "grpc"): client = CompletionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -819,7 +849,8 @@ def test_import_completion_data_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 = CompletionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -838,7 +869,8 @@ async def test_import_completion_data_async( request_type=import_config.ImportCompletionDataRequest, ): client = CompletionServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -870,7 +902,9 @@ async def test_import_completion_data_async_from_dict(): def test_import_completion_data_field_headers(): - client = CompletionServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = CompletionServiceClient( + 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. @@ -892,7 +926,10 @@ def test_import_completion_data_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "parent=parent/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -923,7 +960,10 @@ async def test_import_completion_data_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "parent=parent/value", + ) in kw["metadata"] def test_credentials_transport_error(): @@ -933,7 +973,8 @@ def test_credentials_transport_error(): ) with pytest.raises(ValueError): client = CompletionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # It is an error to provide a credentials file and a transport instance. @@ -953,7 +994,10 @@ def test_credentials_transport_error(): options = client_options.ClientOptions() options.api_key = "api_key" with pytest.raises(ValueError): - client = CompletionServiceClient(client_options=options, transport=transport,) + client = CompletionServiceClient( + client_options=options, + transport=transport, + ) # It is an error to provide an api_key and a credential. options = mock.Mock() @@ -969,7 +1013,8 @@ def test_credentials_transport_error(): ) with pytest.raises(ValueError): client = CompletionServiceClient( - client_options={"scopes": ["1", "2"]}, transport=transport, + client_options={"scopes": ["1", "2"]}, + transport=transport, ) @@ -1014,8 +1059,13 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. - client = CompletionServiceClient(credentials=ga_credentials.AnonymousCredentials(),) - assert isinstance(client.transport, transports.CompletionServiceGrpcTransport,) + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.CompletionServiceGrpcTransport, + ) def test_completion_service_base_transport_error(): @@ -1066,7 +1116,8 @@ def test_completion_service_base_transport_with_credentials_file(): Transport.return_value = None load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.CompletionServiceTransport( - credentials_file="credentials.json", quota_project_id="octopus", + credentials_file="credentials.json", + quota_project_id="octopus", ) load_creds.assert_called_once_with( "credentials.json", @@ -1224,7 +1275,8 @@ def test_completion_service_grpc_transport_channel(): # Check that channel is used if provided. transport = transports.CompletionServiceGrpcTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" @@ -1236,7 +1288,8 @@ def test_completion_service_grpc_asyncio_transport_channel(): # Check that channel is used if provided. transport = transports.CompletionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" @@ -1345,12 +1398,16 @@ def test_completion_service_transport_channel_mtls_with_adc(transport_class): def test_completion_service_grpc_lro_client(): client = CompletionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + 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,) + 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 @@ -1358,12 +1415,16 @@ def test_completion_service_grpc_lro_client(): def test_completion_service_grpc_lro_async_client(): client = CompletionServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", + 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,) + 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 @@ -1374,7 +1435,9 @@ def test_catalog_path(): location = "clam" catalog = "whelk" expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format( - project=project, location=location, catalog=catalog, + project=project, + location=location, + catalog=catalog, ) actual = CompletionServiceClient.catalog_path(project, location, catalog) assert expected == actual @@ -1415,7 +1478,9 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): folder = "winkle" - expected = "folders/{folder}".format(folder=folder,) + expected = "folders/{folder}".format( + folder=folder, + ) actual = CompletionServiceClient.common_folder_path(folder) assert expected == actual @@ -1433,7 +1498,9 @@ def test_parse_common_folder_path(): def test_common_organization_path(): organization = "scallop" - expected = "organizations/{organization}".format(organization=organization,) + expected = "organizations/{organization}".format( + organization=organization, + ) actual = CompletionServiceClient.common_organization_path(organization) assert expected == actual @@ -1451,7 +1518,9 @@ def test_parse_common_organization_path(): def test_common_project_path(): project = "squid" - expected = "projects/{project}".format(project=project,) + expected = "projects/{project}".format( + project=project, + ) actual = CompletionServiceClient.common_project_path(project) assert expected == actual @@ -1471,7 +1540,8 @@ def test_common_location_path(): project = "whelk" location = "octopus" expected = "projects/{project}/locations/{location}".format( - project=project, location=location, + project=project, + location=location, ) actual = CompletionServiceClient.common_location_path(project, location) assert expected == actual @@ -1496,7 +1566,8 @@ def test_client_with_default_client_info(): transports.CompletionServiceTransport, "_prep_wrapped_messages" ) as prep: client = CompletionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -1505,7 +1576,8 @@ def test_client_with_default_client_info(): ) as prep: transport_class = CompletionServiceClient.get_transport_class() transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -1513,7 +1585,8 @@ def test_client_with_default_client_info(): @pytest.mark.asyncio async def test_transport_close_async(): client = CompletionServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", ) with mock.patch.object( type(getattr(client.transport, "grpc_channel")), "close" diff --git a/tests/unit/gapic/retail_v2/test_prediction_service.py b/tests/unit/gapic/retail_v2/test_prediction_service.py index ff5cdafc..ce468029 100644 --- a/tests/unit/gapic/retail_v2/test_prediction_service.py +++ b/tests/unit/gapic/retail_v2/test_prediction_service.py @@ -39,6 +39,7 @@ from google.cloud.retail_v2.types import common from google.cloud.retail_v2.types import prediction_service from google.cloud.retail_v2.types import product +from google.cloud.retail_v2.types import promotion from google.cloud.retail_v2.types import user_event from google.oauth2 import service_account from google.protobuf import duration_pb2 # type: ignore @@ -95,7 +96,11 @@ def test__get_default_mtls_endpoint(): @pytest.mark.parametrize( - "client_class", [PredictionServiceClient, PredictionServiceAsyncClient,] + "client_class", + [ + PredictionServiceClient, + PredictionServiceAsyncClient, + ], ) def test_prediction_service_client_from_service_account_info(client_class): creds = ga_credentials.AnonymousCredentials() @@ -137,7 +142,11 @@ def test_prediction_service_client_service_account_always_use_jwt( @pytest.mark.parametrize( - "client_class", [PredictionServiceClient, PredictionServiceAsyncClient,] + "client_class", + [ + PredictionServiceClient, + PredictionServiceAsyncClient, + ], ) def test_prediction_service_client_from_service_account_file(client_class): creds = ga_credentials.AnonymousCredentials() @@ -511,7 +520,9 @@ def test_prediction_service_client_client_options_scopes( client_class, transport_class, transport_name ): # Check the case scopes are provided. - options = client_options.ClientOptions(scopes=["1", "2"],) + 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) @@ -651,10 +662,17 @@ def test_prediction_service_client_create_channel_credentials_file( ) -@pytest.mark.parametrize("request_type", [prediction_service.PredictRequest, dict,]) +@pytest.mark.parametrize( + "request_type", + [ + prediction_service.PredictRequest, + dict, + ], +) def test_predict(request_type, transport: str = "grpc"): client = PredictionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -687,7 +705,8 @@ def test_predict_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 = PredictionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -703,7 +722,8 @@ async def test_predict_async( transport: str = "grpc_asyncio", request_type=prediction_service.PredictRequest ): client = PredictionServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -740,7 +760,9 @@ async def test_predict_async_from_dict(): def test_predict_field_headers(): - client = PredictionServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = PredictionServiceClient( + 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. @@ -760,7 +782,10 @@ def test_predict_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "placement=placement/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "placement=placement/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -789,7 +814,10 @@ async def test_predict_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "placement=placement/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "placement=placement/value", + ) in kw["metadata"] def test_credentials_transport_error(): @@ -799,7 +827,8 @@ def test_credentials_transport_error(): ) with pytest.raises(ValueError): client = PredictionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # It is an error to provide a credentials file and a transport instance. @@ -819,7 +848,10 @@ def test_credentials_transport_error(): options = client_options.ClientOptions() options.api_key = "api_key" with pytest.raises(ValueError): - client = PredictionServiceClient(client_options=options, transport=transport,) + client = PredictionServiceClient( + client_options=options, + transport=transport, + ) # It is an error to provide an api_key and a credential. options = mock.Mock() @@ -835,7 +867,8 @@ def test_credentials_transport_error(): ) with pytest.raises(ValueError): client = PredictionServiceClient( - client_options={"scopes": ["1", "2"]}, transport=transport, + client_options={"scopes": ["1", "2"]}, + transport=transport, ) @@ -880,8 +913,13 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. - client = PredictionServiceClient(credentials=ga_credentials.AnonymousCredentials(),) - assert isinstance(client.transport, transports.PredictionServiceGrpcTransport,) + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.PredictionServiceGrpcTransport, + ) def test_prediction_service_base_transport_error(): @@ -924,7 +962,8 @@ def test_prediction_service_base_transport_with_credentials_file(): Transport.return_value = None load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.PredictionServiceTransport( - credentials_file="credentials.json", quota_project_id="octopus", + credentials_file="credentials.json", + quota_project_id="octopus", ) load_creds.assert_called_once_with( "credentials.json", @@ -1082,7 +1121,8 @@ def test_prediction_service_grpc_transport_channel(): # Check that channel is used if provided. transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" @@ -1094,7 +1134,8 @@ def test_prediction_service_grpc_asyncio_transport_channel(): # Check that channel is used if provided. transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" @@ -1257,7 +1298,9 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): folder = "squid" - expected = "folders/{folder}".format(folder=folder,) + expected = "folders/{folder}".format( + folder=folder, + ) actual = PredictionServiceClient.common_folder_path(folder) assert expected == actual @@ -1275,7 +1318,9 @@ def test_parse_common_folder_path(): def test_common_organization_path(): organization = "whelk" - expected = "organizations/{organization}".format(organization=organization,) + expected = "organizations/{organization}".format( + organization=organization, + ) actual = PredictionServiceClient.common_organization_path(organization) assert expected == actual @@ -1293,7 +1338,9 @@ def test_parse_common_organization_path(): def test_common_project_path(): project = "oyster" - expected = "projects/{project}".format(project=project,) + expected = "projects/{project}".format( + project=project, + ) actual = PredictionServiceClient.common_project_path(project) assert expected == actual @@ -1313,7 +1360,8 @@ def test_common_location_path(): project = "cuttlefish" location = "mussel" expected = "projects/{project}/locations/{location}".format( - project=project, location=location, + project=project, + location=location, ) actual = PredictionServiceClient.common_location_path(project, location) assert expected == actual @@ -1338,7 +1386,8 @@ def test_client_with_default_client_info(): transports.PredictionServiceTransport, "_prep_wrapped_messages" ) as prep: client = PredictionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -1347,7 +1396,8 @@ def test_client_with_default_client_info(): ) as prep: transport_class = PredictionServiceClient.get_transport_class() transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -1355,7 +1405,8 @@ def test_client_with_default_client_info(): @pytest.mark.asyncio async def test_transport_close_async(): client = PredictionServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", ) with mock.patch.object( type(getattr(client.transport, "grpc_channel")), "close" diff --git a/tests/unit/gapic/retail_v2/test_product_service.py b/tests/unit/gapic/retail_v2/test_product_service.py index 8a8251f2..5d9c4490 100644 --- a/tests/unit/gapic/retail_v2/test_product_service.py +++ b/tests/unit/gapic/retail_v2/test_product_service.py @@ -44,6 +44,7 @@ from google.cloud.retail_v2.types import product from google.cloud.retail_v2.types import product as gcr_product from google.cloud.retail_v2.types import product_service +from google.cloud.retail_v2.types import promotion from google.longrunning import operations_pb2 from google.oauth2 import service_account from google.protobuf import duration_pb2 # type: ignore @@ -99,7 +100,11 @@ def test__get_default_mtls_endpoint(): @pytest.mark.parametrize( - "client_class", [ProductServiceClient, ProductServiceAsyncClient,] + "client_class", + [ + ProductServiceClient, + ProductServiceAsyncClient, + ], ) def test_product_service_client_from_service_account_info(client_class): creds = ga_credentials.AnonymousCredentials() @@ -141,7 +146,11 @@ def test_product_service_client_service_account_always_use_jwt( @pytest.mark.parametrize( - "client_class", [ProductServiceClient, ProductServiceAsyncClient,] + "client_class", + [ + ProductServiceClient, + ProductServiceAsyncClient, + ], ) def test_product_service_client_from_service_account_file(client_class): creds = ga_credentials.AnonymousCredentials() @@ -505,7 +514,9 @@ def test_product_service_client_client_options_scopes( client_class, transport_class, transport_name ): # Check the case scopes are provided. - options = client_options.ClientOptions(scopes=["1", "2"],) + 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) @@ -645,10 +656,17 @@ def test_product_service_client_create_channel_credentials_file( ) -@pytest.mark.parametrize("request_type", [product_service.CreateProductRequest, dict,]) +@pytest.mark.parametrize( + "request_type", + [ + product_service.CreateProductRequest, + dict, + ], +) def test_create_product(request_type, transport: str = "grpc"): client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -712,7 +730,8 @@ def test_create_product_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 = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -728,7 +747,8 @@ async def test_create_product_async( transport: str = "grpc_asyncio", request_type=product_service.CreateProductRequest ): client = ProductServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -795,7 +815,9 @@ async def test_create_product_async_from_dict(): def test_create_product_field_headers(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + 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. @@ -815,7 +837,10 @@ def test_create_product_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "parent=parent/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -842,11 +867,16 @@ async def test_create_product_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "parent=parent/value", + ) in kw["metadata"] def test_create_product_flattened(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.create_product), "__call__") as call: @@ -878,7 +908,9 @@ def test_create_product_flattened(): def test_create_product_flattened_error(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) # Attempting to call a method with both a request object and flattened # fields is an error. @@ -949,10 +981,17 @@ async def test_create_product_flattened_error_async(): ) -@pytest.mark.parametrize("request_type", [product_service.GetProductRequest, dict,]) +@pytest.mark.parametrize( + "request_type", + [ + product_service.GetProductRequest, + dict, + ], +) def test_get_product(request_type, transport: str = "grpc"): client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1016,7 +1055,8 @@ def test_get_product_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 = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1032,7 +1072,8 @@ async def test_get_product_async( transport: str = "grpc_asyncio", request_type=product_service.GetProductRequest ): client = ProductServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1099,7 +1140,9 @@ async def test_get_product_async_from_dict(): def test_get_product_field_headers(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + 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. @@ -1119,7 +1162,10 @@ def test_get_product_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "name=name/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "name=name/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -1146,11 +1192,16 @@ async def test_get_product_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "name=name/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "name=name/value", + ) in kw["metadata"] def test_get_product_flattened(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.get_product), "__call__") as call: @@ -1158,7 +1209,9 @@ def test_get_product_flattened(): call.return_value = product.Product() # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. - client.get_product(name="name_value",) + client.get_product( + name="name_value", + ) # Establish that the underlying call was made with the expected # request object values. @@ -1170,13 +1223,16 @@ def test_get_product_flattened(): def test_get_product_flattened_error(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): client.get_product( - product_service.GetProductRequest(), name="name_value", + product_service.GetProductRequest(), + name="name_value", ) @@ -1194,7 +1250,9 @@ async def test_get_product_flattened_async(): call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product.Product()) # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. - response = await client.get_product(name="name_value",) + response = await client.get_product( + name="name_value", + ) # Establish that the underlying call was made with the expected # request object values. @@ -1215,14 +1273,22 @@ async def test_get_product_flattened_error_async(): # fields is an error. with pytest.raises(ValueError): await client.get_product( - product_service.GetProductRequest(), name="name_value", + product_service.GetProductRequest(), + name="name_value", ) -@pytest.mark.parametrize("request_type", [product_service.ListProductsRequest, dict,]) +@pytest.mark.parametrize( + "request_type", + [ + product_service.ListProductsRequest, + dict, + ], +) def test_list_products(request_type, transport: str = "grpc"): client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1251,7 +1317,8 @@ def test_list_products_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 = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1267,7 +1334,8 @@ async def test_list_products_async( transport: str = "grpc_asyncio", request_type=product_service.ListProductsRequest ): client = ProductServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1300,7 +1368,9 @@ async def test_list_products_async_from_dict(): def test_list_products_field_headers(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + 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. @@ -1320,7 +1390,10 @@ def test_list_products_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "parent=parent/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -1349,11 +1422,16 @@ async def test_list_products_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "parent=parent/value", + ) in kw["metadata"] def test_list_products_flattened(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.list_products), "__call__") as call: @@ -1361,7 +1439,9 @@ def test_list_products_flattened(): call.return_value = product_service.ListProductsResponse() # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. - client.list_products(parent="parent_value",) + client.list_products( + parent="parent_value", + ) # Establish that the underlying call was made with the expected # request object values. @@ -1373,13 +1453,16 @@ def test_list_products_flattened(): def test_list_products_flattened_error(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + 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_products( - product_service.ListProductsRequest(), parent="parent_value", + product_service.ListProductsRequest(), + parent="parent_value", ) @@ -1399,7 +1482,9 @@ async def test_list_products_flattened_async(): ) # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. - response = await client.list_products(parent="parent_value",) + response = await client.list_products( + parent="parent_value", + ) # Establish that the underlying call was made with the expected # request object values. @@ -1420,13 +1505,15 @@ async def test_list_products_flattened_error_async(): # fields is an error. with pytest.raises(ValueError): await client.list_products( - product_service.ListProductsRequest(), parent="parent_value", + product_service.ListProductsRequest(), + parent="parent_value", ) def test_list_products_pager(transport_name: str = "grpc"): client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials, transport=transport_name, + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1434,15 +1521,28 @@ def test_list_products_pager(transport_name: str = "grpc"): # Set the response to a series of pages. call.side_effect = ( product_service.ListProductsResponse( - products=[product.Product(), product.Product(), product.Product(),], + products=[ + product.Product(), + product.Product(), + product.Product(), + ], next_page_token="abc", ), - product_service.ListProductsResponse(products=[], next_page_token="def",), product_service.ListProductsResponse( - products=[product.Product(),], next_page_token="ghi", + products=[], + next_page_token="def", + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + ], + next_page_token="ghi", ), product_service.ListProductsResponse( - products=[product.Product(), product.Product(),], + products=[ + product.Product(), + product.Product(), + ], ), RuntimeError, ) @@ -1462,7 +1562,8 @@ def test_list_products_pager(transport_name: str = "grpc"): def test_list_products_pages(transport_name: str = "grpc"): client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials, transport=transport_name, + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1470,15 +1571,28 @@ def test_list_products_pages(transport_name: str = "grpc"): # Set the response to a series of pages. call.side_effect = ( product_service.ListProductsResponse( - products=[product.Product(), product.Product(), product.Product(),], + products=[ + product.Product(), + product.Product(), + product.Product(), + ], next_page_token="abc", ), - product_service.ListProductsResponse(products=[], next_page_token="def",), product_service.ListProductsResponse( - products=[product.Product(),], next_page_token="ghi", + products=[], + next_page_token="def", + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + ], + next_page_token="ghi", ), product_service.ListProductsResponse( - products=[product.Product(), product.Product(),], + products=[ + product.Product(), + product.Product(), + ], ), RuntimeError, ) @@ -1489,7 +1603,9 @@ def test_list_products_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_products_async_pager(): - client = ProductServiceAsyncClient(credentials=ga_credentials.AnonymousCredentials,) + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( @@ -1498,19 +1614,34 @@ async def test_list_products_async_pager(): # Set the response to a series of pages. call.side_effect = ( product_service.ListProductsResponse( - products=[product.Product(), product.Product(), product.Product(),], + products=[ + product.Product(), + product.Product(), + product.Product(), + ], next_page_token="abc", ), - product_service.ListProductsResponse(products=[], next_page_token="def",), product_service.ListProductsResponse( - products=[product.Product(),], next_page_token="ghi", + products=[], + next_page_token="def", + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + ], + next_page_token="ghi", ), product_service.ListProductsResponse( - products=[product.Product(), product.Product(),], + products=[ + product.Product(), + product.Product(), + ], ), RuntimeError, ) - async_pager = await client.list_products(request={},) + async_pager = await client.list_products( + request={}, + ) assert async_pager.next_page_token == "abc" responses = [] async for response in async_pager: @@ -1522,7 +1653,9 @@ async def test_list_products_async_pager(): @pytest.mark.asyncio async def test_list_products_async_pages(): - client = ProductServiceAsyncClient(credentials=ga_credentials.AnonymousCredentials,) + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( @@ -1531,15 +1664,28 @@ async def test_list_products_async_pages(): # Set the response to a series of pages. call.side_effect = ( product_service.ListProductsResponse( - products=[product.Product(), product.Product(), product.Product(),], + products=[ + product.Product(), + product.Product(), + product.Product(), + ], next_page_token="abc", ), - product_service.ListProductsResponse(products=[], next_page_token="def",), product_service.ListProductsResponse( - products=[product.Product(),], next_page_token="ghi", + products=[], + next_page_token="def", + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + ], + next_page_token="ghi", ), product_service.ListProductsResponse( - products=[product.Product(), product.Product(),], + products=[ + product.Product(), + product.Product(), + ], ), RuntimeError, ) @@ -1550,10 +1696,17 @@ async def test_list_products_async_pages(): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize("request_type", [product_service.UpdateProductRequest, dict,]) +@pytest.mark.parametrize( + "request_type", + [ + product_service.UpdateProductRequest, + dict, + ], +) def test_update_product(request_type, transport: str = "grpc"): client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1617,7 +1770,8 @@ def test_update_product_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 = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1633,7 +1787,8 @@ async def test_update_product_async( transport: str = "grpc_asyncio", request_type=product_service.UpdateProductRequest ): client = ProductServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1700,7 +1855,9 @@ async def test_update_product_async_from_dict(): def test_update_product_field_headers(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + 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. @@ -1720,9 +1877,10 @@ def test_update_product_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "product.name=product.name/value",) in kw[ - "metadata" - ] + assert ( + "x-goog-request-params", + "product.name=product.name/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -1749,13 +1907,16 @@ async def test_update_product_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "product.name=product.name/value",) in kw[ - "metadata" - ] + assert ( + "x-goog-request-params", + "product.name=product.name/value", + ) in kw["metadata"] def test_update_product_flattened(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.update_product), "__call__") as call: @@ -1783,7 +1944,9 @@ def test_update_product_flattened(): def test_update_product_flattened_error(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) # Attempting to call a method with both a request object and flattened # fields is an error. @@ -1848,10 +2011,17 @@ async def test_update_product_flattened_error_async(): ) -@pytest.mark.parametrize("request_type", [product_service.DeleteProductRequest, dict,]) +@pytest.mark.parametrize( + "request_type", + [ + product_service.DeleteProductRequest, + dict, + ], +) def test_delete_product(request_type, transport: str = "grpc"): client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1877,7 +2047,8 @@ def test_delete_product_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 = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1893,7 +2064,8 @@ async def test_delete_product_async( transport: str = "grpc_asyncio", request_type=product_service.DeleteProductRequest ): client = ProductServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1921,7 +2093,9 @@ async def test_delete_product_async_from_dict(): def test_delete_product_field_headers(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + 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. @@ -1941,7 +2115,10 @@ def test_delete_product_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "name=name/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "name=name/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -1968,11 +2145,16 @@ async def test_delete_product_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "name=name/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "name=name/value", + ) in kw["metadata"] def test_delete_product_flattened(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.delete_product), "__call__") as call: @@ -1980,7 +2162,9 @@ def test_delete_product_flattened(): call.return_value = None # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. - client.delete_product(name="name_value",) + client.delete_product( + name="name_value", + ) # Establish that the underlying call was made with the expected # request object values. @@ -1992,13 +2176,16 @@ def test_delete_product_flattened(): def test_delete_product_flattened_error(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + 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_product( - product_service.DeleteProductRequest(), name="name_value", + product_service.DeleteProductRequest(), + name="name_value", ) @@ -2016,7 +2203,9 @@ async def test_delete_product_flattened_async(): 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_product(name="name_value",) + response = await client.delete_product( + name="name_value", + ) # Establish that the underlying call was made with the expected # request object values. @@ -2037,14 +2226,22 @@ async def test_delete_product_flattened_error_async(): # fields is an error. with pytest.raises(ValueError): await client.delete_product( - product_service.DeleteProductRequest(), name="name_value", + product_service.DeleteProductRequest(), + name="name_value", ) -@pytest.mark.parametrize("request_type", [import_config.ImportProductsRequest, dict,]) +@pytest.mark.parametrize( + "request_type", + [ + import_config.ImportProductsRequest, + dict, + ], +) def test_import_products(request_type, transport: str = "grpc"): client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -2070,7 +2267,8 @@ def test_import_products_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 = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2086,7 +2284,8 @@ async def test_import_products_async( transport: str = "grpc_asyncio", request_type=import_config.ImportProductsRequest ): client = ProductServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -2116,7 +2315,9 @@ async def test_import_products_async_from_dict(): def test_import_products_field_headers(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + 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. @@ -2136,7 +2337,10 @@ def test_import_products_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "parent=parent/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -2165,13 +2369,23 @@ async def test_import_products_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "parent=parent/value", + ) in kw["metadata"] -@pytest.mark.parametrize("request_type", [product_service.SetInventoryRequest, dict,]) +@pytest.mark.parametrize( + "request_type", + [ + product_service.SetInventoryRequest, + dict, + ], +) def test_set_inventory(request_type, transport: str = "grpc"): client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -2197,7 +2411,8 @@ def test_set_inventory_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 = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2213,7 +2428,8 @@ async def test_set_inventory_async( transport: str = "grpc_asyncio", request_type=product_service.SetInventoryRequest ): client = ProductServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -2243,7 +2459,9 @@ async def test_set_inventory_async_from_dict(): def test_set_inventory_field_headers(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + 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. @@ -2263,9 +2481,10 @@ def test_set_inventory_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "inventory.name=inventory.name/value",) in kw[ - "metadata" - ] + assert ( + "x-goog-request-params", + "inventory.name=inventory.name/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -2294,13 +2513,16 @@ async def test_set_inventory_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "inventory.name=inventory.name/value",) in kw[ - "metadata" - ] + assert ( + "x-goog-request-params", + "inventory.name=inventory.name/value", + ) in kw["metadata"] def test_set_inventory_flattened(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.set_inventory), "__call__") as call: @@ -2326,7 +2548,9 @@ def test_set_inventory_flattened(): def test_set_inventory_flattened_error(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) # Attempting to call a method with both a request object and flattened # fields is an error. @@ -2388,11 +2612,16 @@ async def test_set_inventory_flattened_error_async(): @pytest.mark.parametrize( - "request_type", [product_service.AddFulfillmentPlacesRequest, dict,] + "request_type", + [ + product_service.AddFulfillmentPlacesRequest, + dict, + ], ) def test_add_fulfillment_places(request_type, transport: str = "grpc"): client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -2420,7 +2649,8 @@ def test_add_fulfillment_places_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 = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2439,7 +2669,8 @@ async def test_add_fulfillment_places_async( request_type=product_service.AddFulfillmentPlacesRequest, ): client = ProductServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -2471,7 +2702,9 @@ async def test_add_fulfillment_places_async_from_dict(): def test_add_fulfillment_places_field_headers(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + 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. @@ -2493,7 +2726,10 @@ def test_add_fulfillment_places_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "product=product/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "product=product/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -2524,11 +2760,16 @@ async def test_add_fulfillment_places_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "product=product/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "product=product/value", + ) in kw["metadata"] def test_add_fulfillment_places_flattened(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( @@ -2538,7 +2779,9 @@ def test_add_fulfillment_places_flattened(): 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.add_fulfillment_places(product="product_value",) + client.add_fulfillment_places( + product="product_value", + ) # Establish that the underlying call was made with the expected # request object values. @@ -2550,13 +2793,16 @@ def test_add_fulfillment_places_flattened(): def test_add_fulfillment_places_flattened_error(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + 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.add_fulfillment_places( - product_service.AddFulfillmentPlacesRequest(), product="product_value", + product_service.AddFulfillmentPlacesRequest(), + product="product_value", ) @@ -2578,7 +2824,9 @@ async def test_add_fulfillment_places_flattened_async(): ) # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. - response = await client.add_fulfillment_places(product="product_value",) + response = await client.add_fulfillment_places( + product="product_value", + ) # Establish that the underlying call was made with the expected # request object values. @@ -2599,16 +2847,22 @@ async def test_add_fulfillment_places_flattened_error_async(): # fields is an error. with pytest.raises(ValueError): await client.add_fulfillment_places( - product_service.AddFulfillmentPlacesRequest(), product="product_value", + product_service.AddFulfillmentPlacesRequest(), + product="product_value", ) @pytest.mark.parametrize( - "request_type", [product_service.RemoveFulfillmentPlacesRequest, dict,] + "request_type", + [ + product_service.RemoveFulfillmentPlacesRequest, + dict, + ], ) def test_remove_fulfillment_places(request_type, transport: str = "grpc"): client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -2636,7 +2890,8 @@ def test_remove_fulfillment_places_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 = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2655,7 +2910,8 @@ async def test_remove_fulfillment_places_async( request_type=product_service.RemoveFulfillmentPlacesRequest, ): client = ProductServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -2687,7 +2943,9 @@ async def test_remove_fulfillment_places_async_from_dict(): def test_remove_fulfillment_places_field_headers(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + 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. @@ -2709,7 +2967,10 @@ def test_remove_fulfillment_places_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "product=product/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "product=product/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -2740,11 +3001,16 @@ async def test_remove_fulfillment_places_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "product=product/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "product=product/value", + ) in kw["metadata"] def test_remove_fulfillment_places_flattened(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( @@ -2754,7 +3020,9 @@ def test_remove_fulfillment_places_flattened(): 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.remove_fulfillment_places(product="product_value",) + client.remove_fulfillment_places( + product="product_value", + ) # Establish that the underlying call was made with the expected # request object values. @@ -2766,13 +3034,16 @@ def test_remove_fulfillment_places_flattened(): def test_remove_fulfillment_places_flattened_error(): - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = ProductServiceClient( + 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.remove_fulfillment_places( - product_service.RemoveFulfillmentPlacesRequest(), product="product_value", + product_service.RemoveFulfillmentPlacesRequest(), + product="product_value", ) @@ -2794,7 +3065,9 @@ async def test_remove_fulfillment_places_flattened_async(): ) # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. - response = await client.remove_fulfillment_places(product="product_value",) + response = await client.remove_fulfillment_places( + product="product_value", + ) # Establish that the underlying call was made with the expected # request object values. @@ -2815,38 +3088,525 @@ async def test_remove_fulfillment_places_flattened_error_async(): # fields is an error. with pytest.raises(ValueError): await client.remove_fulfillment_places( - product_service.RemoveFulfillmentPlacesRequest(), product="product_value", + product_service.RemoveFulfillmentPlacesRequest(), + product="product_value", ) -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.ProductServiceGrpcTransport( +@pytest.mark.parametrize( + "request_type", + [ + product_service.AddLocalInventoriesRequest, + dict, + ], +) +def test_add_local_inventories(request_type, transport: str = "grpc"): + client = ProductServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) - with pytest.raises(ValueError): - client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, - ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.ProductServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ProductServiceClient( - client_options={"credentials_file": "credentials.json"}, - 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() - # It is an error to provide an api_key and a transport instance. - transport = transports.ProductServiceGrpcTransport( + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_local_inventories), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.add_local_inventories(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.AddLocalInventoriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_add_local_inventories_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 = ProductServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) - options = client_options.ClientOptions() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_local_inventories), "__call__" + ) as call: + client.add_local_inventories() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.AddLocalInventoriesRequest() + + +@pytest.mark.asyncio +async def test_add_local_inventories_async( + transport: str = "grpc_asyncio", + request_type=product_service.AddLocalInventoriesRequest, +): + client = ProductServiceAsyncClient( + 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.add_local_inventories), "__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.add_local_inventories(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.AddLocalInventoriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_add_local_inventories_async_from_dict(): + await test_add_local_inventories_async(request_type=dict) + + +def test_add_local_inventories_field_headers(): + client = ProductServiceClient( + 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 = product_service.AddLocalInventoriesRequest() + + request.product = "product/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_local_inventories), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.add_local_inventories(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", + "product=product/value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_add_local_inventories_field_headers_async(): + client = ProductServiceAsyncClient( + 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 = product_service.AddLocalInventoriesRequest() + + request.product = "product/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_local_inventories), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.add_local_inventories(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", + "product=product/value", + ) in kw["metadata"] + + +def test_add_local_inventories_flattened(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_local_inventories), "__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.add_local_inventories( + product="product_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].product + mock_val = "product_value" + assert arg == mock_val + + +def test_add_local_inventories_flattened_error(): + client = ProductServiceClient( + 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.add_local_inventories( + product_service.AddLocalInventoriesRequest(), + product="product_value", + ) + + +@pytest.mark.asyncio +async def test_add_local_inventories_flattened_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_local_inventories), "__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.add_local_inventories( + product="product_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].product + mock_val = "product_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_add_local_inventories_flattened_error_async(): + client = ProductServiceAsyncClient( + 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.add_local_inventories( + product_service.AddLocalInventoriesRequest(), + product="product_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + product_service.RemoveLocalInventoriesRequest, + dict, + ], +) +def test_remove_local_inventories(request_type, transport: str = "grpc"): + client = ProductServiceClient( + 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.remove_local_inventories), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.remove_local_inventories(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.RemoveLocalInventoriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_remove_local_inventories_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 = ProductServiceClient( + 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.remove_local_inventories), "__call__" + ) as call: + client.remove_local_inventories() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.RemoveLocalInventoriesRequest() + + +@pytest.mark.asyncio +async def test_remove_local_inventories_async( + transport: str = "grpc_asyncio", + request_type=product_service.RemoveLocalInventoriesRequest, +): + client = ProductServiceAsyncClient( + 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.remove_local_inventories), "__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.remove_local_inventories(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.RemoveLocalInventoriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_remove_local_inventories_async_from_dict(): + await test_remove_local_inventories_async(request_type=dict) + + +def test_remove_local_inventories_field_headers(): + client = ProductServiceClient( + 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 = product_service.RemoveLocalInventoriesRequest() + + request.product = "product/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_local_inventories), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.remove_local_inventories(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", + "product=product/value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_remove_local_inventories_field_headers_async(): + client = ProductServiceAsyncClient( + 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 = product_service.RemoveLocalInventoriesRequest() + + request.product = "product/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_local_inventories), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.remove_local_inventories(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", + "product=product/value", + ) in kw["metadata"] + + +def test_remove_local_inventories_flattened(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_local_inventories), "__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.remove_local_inventories( + product="product_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].product + mock_val = "product_value" + assert arg == mock_val + + +def test_remove_local_inventories_flattened_error(): + client = ProductServiceClient( + 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.remove_local_inventories( + product_service.RemoveLocalInventoriesRequest(), + product="product_value", + ) + + +@pytest.mark.asyncio +async def test_remove_local_inventories_flattened_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_local_inventories), "__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.remove_local_inventories( + product="product_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].product + mock_val = "product_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_remove_local_inventories_flattened_error_async(): + client = ProductServiceAsyncClient( + 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.remove_local_inventories( + product_service.RemoveLocalInventoriesRequest(), + product="product_value", + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() options.api_key = "api_key" with pytest.raises(ValueError): - client = ProductServiceClient(client_options=options, transport=transport,) + client = ProductServiceClient( + client_options=options, + transport=transport, + ) # It is an error to provide an api_key and a credential. options = mock.Mock() @@ -2862,7 +3622,8 @@ def test_credentials_transport_error(): ) with pytest.raises(ValueError): client = ProductServiceClient( - client_options={"scopes": ["1", "2"]}, transport=transport, + client_options={"scopes": ["1", "2"]}, + transport=transport, ) @@ -2907,8 +3668,13 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. - client = ProductServiceClient(credentials=ga_credentials.AnonymousCredentials(),) - assert isinstance(client.transport, transports.ProductServiceGrpcTransport,) + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ProductServiceGrpcTransport, + ) def test_product_service_base_transport_error(): @@ -2942,6 +3708,8 @@ def test_product_service_base_transport(): "set_inventory", "add_fulfillment_places", "remove_fulfillment_places", + "add_local_inventories", + "remove_local_inventories", ) for method in methods: with pytest.raises(NotImplementedError): @@ -2966,7 +3734,8 @@ def test_product_service_base_transport_with_credentials_file(): Transport.return_value = None load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.ProductServiceTransport( - credentials_file="credentials.json", quota_project_id="octopus", + credentials_file="credentials.json", + quota_project_id="octopus", ) load_creds.assert_called_once_with( "credentials.json", @@ -3124,7 +3893,8 @@ def test_product_service_grpc_transport_channel(): # Check that channel is used if provided. transport = transports.ProductServiceGrpcTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" @@ -3136,7 +3906,8 @@ def test_product_service_grpc_asyncio_transport_channel(): # Check that channel is used if provided. transport = transports.ProductServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" @@ -3245,12 +4016,16 @@ def test_product_service_transport_channel_mtls_with_adc(transport_class): def test_product_service_grpc_lro_client(): client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + 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,) + 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 @@ -3258,12 +4033,16 @@ def test_product_service_grpc_lro_client(): def test_product_service_grpc_lro_async_client(): client = ProductServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", + 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,) + 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 @@ -3275,7 +4054,10 @@ def test_branch_path(): catalog = "whelk" branch = "octopus" expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format( - project=project, location=location, catalog=catalog, branch=branch, + project=project, + location=location, + catalog=catalog, + branch=branch, ) actual = ProductServiceClient.branch_path(project, location, catalog, branch) assert expected == actual @@ -3351,7 +4133,9 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): folder = "winkle" - expected = "folders/{folder}".format(folder=folder,) + expected = "folders/{folder}".format( + folder=folder, + ) actual = ProductServiceClient.common_folder_path(folder) assert expected == actual @@ -3369,7 +4153,9 @@ def test_parse_common_folder_path(): def test_common_organization_path(): organization = "scallop" - expected = "organizations/{organization}".format(organization=organization,) + expected = "organizations/{organization}".format( + organization=organization, + ) actual = ProductServiceClient.common_organization_path(organization) assert expected == actual @@ -3387,7 +4173,9 @@ def test_parse_common_organization_path(): def test_common_project_path(): project = "squid" - expected = "projects/{project}".format(project=project,) + expected = "projects/{project}".format( + project=project, + ) actual = ProductServiceClient.common_project_path(project) assert expected == actual @@ -3407,7 +4195,8 @@ def test_common_location_path(): project = "whelk" location = "octopus" expected = "projects/{project}/locations/{location}".format( - project=project, location=location, + project=project, + location=location, ) actual = ProductServiceClient.common_location_path(project, location) assert expected == actual @@ -3432,7 +4221,8 @@ def test_client_with_default_client_info(): transports.ProductServiceTransport, "_prep_wrapped_messages" ) as prep: client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -3441,7 +4231,8 @@ def test_client_with_default_client_info(): ) as prep: transport_class = ProductServiceClient.get_transport_class() transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -3449,7 +4240,8 @@ def test_client_with_default_client_info(): @pytest.mark.asyncio async def test_transport_close_async(): client = ProductServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", ) with mock.patch.object( type(getattr(client.transport, "grpc_channel")), "close" diff --git a/tests/unit/gapic/retail_v2/test_search_service.py b/tests/unit/gapic/retail_v2/test_search_service.py index d9b4b9d4..31dea90d 100644 --- a/tests/unit/gapic/retail_v2/test_search_service.py +++ b/tests/unit/gapic/retail_v2/test_search_service.py @@ -86,7 +86,11 @@ def test__get_default_mtls_endpoint(): @pytest.mark.parametrize( - "client_class", [SearchServiceClient, SearchServiceAsyncClient,] + "client_class", + [ + SearchServiceClient, + SearchServiceAsyncClient, + ], ) def test_search_service_client_from_service_account_info(client_class): creds = ga_credentials.AnonymousCredentials() @@ -128,7 +132,11 @@ def test_search_service_client_service_account_always_use_jwt( @pytest.mark.parametrize( - "client_class", [SearchServiceClient, SearchServiceAsyncClient,] + "client_class", + [ + SearchServiceClient, + SearchServiceAsyncClient, + ], ) def test_search_service_client_from_service_account_file(client_class): creds = ga_credentials.AnonymousCredentials() @@ -492,7 +500,9 @@ def test_search_service_client_client_options_scopes( client_class, transport_class, transport_name ): # Check the case scopes are provided. - options = client_options.ClientOptions(scopes=["1", "2"],) + 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) @@ -632,10 +642,17 @@ def test_search_service_client_create_channel_credentials_file( ) -@pytest.mark.parametrize("request_type", [search_service.SearchRequest, dict,]) +@pytest.mark.parametrize( + "request_type", + [ + search_service.SearchRequest, + dict, + ], +) def test_search(request_type, transport: str = "grpc"): client = SearchServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -651,6 +668,7 @@ def test_search(request_type, transport: str = "grpc"): attribution_token="attribution_token_value", next_page_token="next_page_token_value", redirect_uri="redirect_uri_value", + applied_controls=["applied_controls_value"], ) response = client.search(request) @@ -666,13 +684,15 @@ def test_search(request_type, transport: str = "grpc"): assert response.attribution_token == "attribution_token_value" assert response.next_page_token == "next_page_token_value" assert response.redirect_uri == "redirect_uri_value" + assert response.applied_controls == ["applied_controls_value"] def test_search_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 = SearchServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -688,7 +708,8 @@ async def test_search_async( transport: str = "grpc_asyncio", request_type=search_service.SearchRequest ): client = SearchServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -705,6 +726,7 @@ async def test_search_async( attribution_token="attribution_token_value", next_page_token="next_page_token_value", redirect_uri="redirect_uri_value", + applied_controls=["applied_controls_value"], ) ) response = await client.search(request) @@ -721,6 +743,7 @@ async def test_search_async( assert response.attribution_token == "attribution_token_value" assert response.next_page_token == "next_page_token_value" assert response.redirect_uri == "redirect_uri_value" + assert response.applied_controls == ["applied_controls_value"] @pytest.mark.asyncio @@ -729,7 +752,9 @@ async def test_search_async_from_dict(): def test_search_field_headers(): - client = SearchServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = SearchServiceClient( + 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. @@ -749,7 +774,10 @@ def test_search_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "placement=placement/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "placement=placement/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -778,12 +806,16 @@ async def test_search_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "placement=placement/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "placement=placement/value", + ) in kw["metadata"] def test_search_pager(transport_name: str = "grpc"): client = SearchServiceClient( - credentials=ga_credentials.AnonymousCredentials, transport=transport_name, + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, ) # Mock the actual call within the gRPC stub, and fake the request. @@ -798,9 +830,14 @@ def test_search_pager(transport_name: str = "grpc"): ], next_page_token="abc", ), - search_service.SearchResponse(results=[], next_page_token="def",), search_service.SearchResponse( - results=[search_service.SearchResponse.SearchResult(),], + results=[], + next_page_token="def", + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], next_page_token="ghi", ), search_service.SearchResponse( @@ -829,7 +866,8 @@ def test_search_pager(transport_name: str = "grpc"): def test_search_pages(transport_name: str = "grpc"): client = SearchServiceClient( - credentials=ga_credentials.AnonymousCredentials, transport=transport_name, + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, ) # Mock the actual call within the gRPC stub, and fake the request. @@ -844,9 +882,14 @@ def test_search_pages(transport_name: str = "grpc"): ], next_page_token="abc", ), - search_service.SearchResponse(results=[], next_page_token="def",), search_service.SearchResponse( - results=[search_service.SearchResponse.SearchResult(),], + results=[], + next_page_token="def", + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], next_page_token="ghi", ), search_service.SearchResponse( @@ -864,7 +907,9 @@ def test_search_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_search_async_pager(): - client = SearchServiceAsyncClient(credentials=ga_credentials.AnonymousCredentials,) + client = SearchServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( @@ -880,9 +925,14 @@ async def test_search_async_pager(): ], next_page_token="abc", ), - search_service.SearchResponse(results=[], next_page_token="def",), search_service.SearchResponse( - results=[search_service.SearchResponse.SearchResult(),], + results=[], + next_page_token="def", + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], next_page_token="ghi", ), search_service.SearchResponse( @@ -893,7 +943,9 @@ async def test_search_async_pager(): ), RuntimeError, ) - async_pager = await client.search(request={},) + async_pager = await client.search( + request={}, + ) assert async_pager.next_page_token == "abc" responses = [] async for response in async_pager: @@ -907,7 +959,9 @@ async def test_search_async_pager(): @pytest.mark.asyncio async def test_search_async_pages(): - client = SearchServiceAsyncClient(credentials=ga_credentials.AnonymousCredentials,) + client = SearchServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( @@ -923,9 +977,14 @@ async def test_search_async_pages(): ], next_page_token="abc", ), - search_service.SearchResponse(results=[], next_page_token="def",), search_service.SearchResponse( - results=[search_service.SearchResponse.SearchResult(),], + results=[], + next_page_token="def", + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], next_page_token="ghi", ), search_service.SearchResponse( @@ -950,7 +1009,8 @@ def test_credentials_transport_error(): ) with pytest.raises(ValueError): client = SearchServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # It is an error to provide a credentials file and a transport instance. @@ -970,7 +1030,10 @@ def test_credentials_transport_error(): options = client_options.ClientOptions() options.api_key = "api_key" with pytest.raises(ValueError): - client = SearchServiceClient(client_options=options, transport=transport,) + client = SearchServiceClient( + client_options=options, + transport=transport, + ) # It is an error to provide an api_key and a credential. options = mock.Mock() @@ -986,7 +1049,8 @@ def test_credentials_transport_error(): ) with pytest.raises(ValueError): client = SearchServiceClient( - client_options={"scopes": ["1", "2"]}, transport=transport, + client_options={"scopes": ["1", "2"]}, + transport=transport, ) @@ -1031,8 +1095,13 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. - client = SearchServiceClient(credentials=ga_credentials.AnonymousCredentials(),) - assert isinstance(client.transport, transports.SearchServiceGrpcTransport,) + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.SearchServiceGrpcTransport, + ) def test_search_service_base_transport_error(): @@ -1075,7 +1144,8 @@ def test_search_service_base_transport_with_credentials_file(): Transport.return_value = None load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.SearchServiceTransport( - credentials_file="credentials.json", quota_project_id="octopus", + credentials_file="credentials.json", + quota_project_id="octopus", ) load_creds.assert_called_once_with( "credentials.json", @@ -1233,7 +1303,8 @@ def test_search_service_grpc_transport_channel(): # Check that channel is used if provided. transport = transports.SearchServiceGrpcTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" @@ -1245,7 +1316,8 @@ def test_search_service_grpc_asyncio_transport_channel(): # Check that channel is used if provided. transport = transports.SearchServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" @@ -1356,7 +1428,10 @@ def test_branch_path(): catalog = "whelk" branch = "octopus" expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format( - project=project, location=location, catalog=catalog, branch=branch, + project=project, + location=location, + catalog=catalog, + branch=branch, ) actual = SearchServiceClient.branch_path(project, location, catalog, branch) assert expected == actual @@ -1432,7 +1507,9 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): folder = "winkle" - expected = "folders/{folder}".format(folder=folder,) + expected = "folders/{folder}".format( + folder=folder, + ) actual = SearchServiceClient.common_folder_path(folder) assert expected == actual @@ -1450,7 +1527,9 @@ def test_parse_common_folder_path(): def test_common_organization_path(): organization = "scallop" - expected = "organizations/{organization}".format(organization=organization,) + expected = "organizations/{organization}".format( + organization=organization, + ) actual = SearchServiceClient.common_organization_path(organization) assert expected == actual @@ -1468,7 +1547,9 @@ def test_parse_common_organization_path(): def test_common_project_path(): project = "squid" - expected = "projects/{project}".format(project=project,) + expected = "projects/{project}".format( + project=project, + ) actual = SearchServiceClient.common_project_path(project) assert expected == actual @@ -1488,7 +1569,8 @@ def test_common_location_path(): project = "whelk" location = "octopus" expected = "projects/{project}/locations/{location}".format( - project=project, location=location, + project=project, + location=location, ) actual = SearchServiceClient.common_location_path(project, location) assert expected == actual @@ -1513,7 +1595,8 @@ def test_client_with_default_client_info(): transports.SearchServiceTransport, "_prep_wrapped_messages" ) as prep: client = SearchServiceClient( - credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -1522,7 +1605,8 @@ def test_client_with_default_client_info(): ) as prep: transport_class = SearchServiceClient.get_transport_class() transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -1530,7 +1614,8 @@ def test_client_with_default_client_info(): @pytest.mark.asyncio async def test_transport_close_async(): client = SearchServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", ) with mock.patch.object( type(getattr(client.transport, "grpc_channel")), "close" diff --git a/tests/unit/gapic/retail_v2/test_user_event_service.py b/tests/unit/gapic/retail_v2/test_user_event_service.py index fdba9214..ea7322ef 100644 --- a/tests/unit/gapic/retail_v2/test_user_event_service.py +++ b/tests/unit/gapic/retail_v2/test_user_event_service.py @@ -44,6 +44,7 @@ from google.cloud.retail_v2.types import common from google.cloud.retail_v2.types import import_config from google.cloud.retail_v2.types import product +from google.cloud.retail_v2.types import promotion from google.cloud.retail_v2.types import purge_config from google.cloud.retail_v2.types import user_event from google.cloud.retail_v2.types import user_event_service @@ -104,7 +105,11 @@ def test__get_default_mtls_endpoint(): @pytest.mark.parametrize( - "client_class", [UserEventServiceClient, UserEventServiceAsyncClient,] + "client_class", + [ + UserEventServiceClient, + UserEventServiceAsyncClient, + ], ) def test_user_event_service_client_from_service_account_info(client_class): creds = ga_credentials.AnonymousCredentials() @@ -146,7 +151,11 @@ def test_user_event_service_client_service_account_always_use_jwt( @pytest.mark.parametrize( - "client_class", [UserEventServiceClient, UserEventServiceAsyncClient,] + "client_class", + [ + UserEventServiceClient, + UserEventServiceAsyncClient, + ], ) def test_user_event_service_client_from_service_account_file(client_class): creds = ga_credentials.AnonymousCredentials() @@ -520,7 +529,9 @@ def test_user_event_service_client_client_options_scopes( client_class, transport_class, transport_name ): # Check the case scopes are provided. - options = client_options.ClientOptions(scopes=["1", "2"],) + 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) @@ -661,11 +672,16 @@ def test_user_event_service_client_create_channel_credentials_file( @pytest.mark.parametrize( - "request_type", [user_event_service.WriteUserEventRequest, dict,] + "request_type", + [ + user_event_service.WriteUserEventRequest, + dict, + ], ) def test_write_user_event(request_type, transport: str = "grpc"): client = UserEventServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -720,7 +736,8 @@ def test_write_user_event_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 = UserEventServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -737,7 +754,8 @@ async def test_write_user_event_async( request_type=user_event_service.WriteUserEventRequest, ): client = UserEventServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -796,7 +814,9 @@ async def test_write_user_event_async_from_dict(): def test_write_user_event_field_headers(): - client = UserEventServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = UserEventServiceClient( + 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. @@ -816,7 +836,10 @@ def test_write_user_event_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "parent=parent/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -845,15 +868,23 @@ async def test_write_user_event_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "parent=parent/value", + ) in kw["metadata"] @pytest.mark.parametrize( - "request_type", [user_event_service.CollectUserEventRequest, dict,] + "request_type", + [ + user_event_service.CollectUserEventRequest, + dict, + ], ) def test_collect_user_event(request_type, transport: str = "grpc"): client = UserEventServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -866,7 +897,8 @@ def test_collect_user_event(request_type, transport: str = "grpc"): ) as call: # Designate an appropriate return value for the call. call.return_value = httpbody_pb2.HttpBody( - content_type="content_type_value", data=b"data_blob", + content_type="content_type_value", + data=b"data_blob", ) response = client.collect_user_event(request) @@ -885,7 +917,8 @@ def test_collect_user_event_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 = UserEventServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -904,7 +937,8 @@ async def test_collect_user_event_async( request_type=user_event_service.CollectUserEventRequest, ): client = UserEventServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -917,7 +951,10 @@ async def test_collect_user_event_async( ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - httpbody_pb2.HttpBody(content_type="content_type_value", data=b"data_blob",) + httpbody_pb2.HttpBody( + content_type="content_type_value", + data=b"data_blob", + ) ) response = await client.collect_user_event(request) @@ -938,7 +975,9 @@ async def test_collect_user_event_async_from_dict(): def test_collect_user_event_field_headers(): - client = UserEventServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = UserEventServiceClient( + 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. @@ -960,7 +999,10 @@ def test_collect_user_event_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "parent=parent/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -991,13 +1033,23 @@ async def test_collect_user_event_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "parent=parent/value", + ) in kw["metadata"] -@pytest.mark.parametrize("request_type", [purge_config.PurgeUserEventsRequest, dict,]) +@pytest.mark.parametrize( + "request_type", + [ + purge_config.PurgeUserEventsRequest, + dict, + ], +) def test_purge_user_events(request_type, transport: str = "grpc"): client = UserEventServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1025,7 +1077,8 @@ def test_purge_user_events_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 = UserEventServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1043,7 +1096,8 @@ async def test_purge_user_events_async( transport: str = "grpc_asyncio", request_type=purge_config.PurgeUserEventsRequest ): client = UserEventServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1075,7 +1129,9 @@ async def test_purge_user_events_async_from_dict(): def test_purge_user_events_field_headers(): - client = UserEventServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = UserEventServiceClient( + 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. @@ -1097,7 +1153,10 @@ def test_purge_user_events_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "parent=parent/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -1128,13 +1187,23 @@ async def test_purge_user_events_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "parent=parent/value", + ) in kw["metadata"] -@pytest.mark.parametrize("request_type", [import_config.ImportUserEventsRequest, dict,]) +@pytest.mark.parametrize( + "request_type", + [ + import_config.ImportUserEventsRequest, + dict, + ], +) def test_import_user_events(request_type, transport: str = "grpc"): client = UserEventServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1162,7 +1231,8 @@ def test_import_user_events_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 = UserEventServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1180,7 +1250,8 @@ async def test_import_user_events_async( transport: str = "grpc_asyncio", request_type=import_config.ImportUserEventsRequest ): client = UserEventServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1212,7 +1283,9 @@ async def test_import_user_events_async_from_dict(): def test_import_user_events_field_headers(): - client = UserEventServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = UserEventServiceClient( + 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. @@ -1234,7 +1307,10 @@ def test_import_user_events_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "parent=parent/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -1265,15 +1341,23 @@ async def test_import_user_events_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "parent=parent/value", + ) in kw["metadata"] @pytest.mark.parametrize( - "request_type", [user_event_service.RejoinUserEventsRequest, dict,] + "request_type", + [ + user_event_service.RejoinUserEventsRequest, + dict, + ], ) def test_rejoin_user_events(request_type, transport: str = "grpc"): client = UserEventServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1301,7 +1385,8 @@ def test_rejoin_user_events_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 = UserEventServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1320,7 +1405,8 @@ async def test_rejoin_user_events_async( request_type=user_event_service.RejoinUserEventsRequest, ): client = UserEventServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1352,7 +1438,9 @@ async def test_rejoin_user_events_async_from_dict(): def test_rejoin_user_events_field_headers(): - client = UserEventServiceClient(credentials=ga_credentials.AnonymousCredentials(),) + client = UserEventServiceClient( + 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. @@ -1374,7 +1462,10 @@ def test_rejoin_user_events_field_headers(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "parent=parent/value", + ) in kw["metadata"] @pytest.mark.asyncio @@ -1405,7 +1496,10 @@ async def test_rejoin_user_events_field_headers_async(): # Establish that the field header was sent. _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + assert ( + "x-goog-request-params", + "parent=parent/value", + ) in kw["metadata"] def test_credentials_transport_error(): @@ -1415,7 +1509,8 @@ def test_credentials_transport_error(): ) with pytest.raises(ValueError): client = UserEventServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # It is an error to provide a credentials file and a transport instance. @@ -1435,7 +1530,10 @@ def test_credentials_transport_error(): options = client_options.ClientOptions() options.api_key = "api_key" with pytest.raises(ValueError): - client = UserEventServiceClient(client_options=options, transport=transport,) + client = UserEventServiceClient( + client_options=options, + transport=transport, + ) # It is an error to provide an api_key and a credential. options = mock.Mock() @@ -1451,7 +1549,8 @@ def test_credentials_transport_error(): ) with pytest.raises(ValueError): client = UserEventServiceClient( - client_options={"scopes": ["1", "2"]}, transport=transport, + client_options={"scopes": ["1", "2"]}, + transport=transport, ) @@ -1496,8 +1595,13 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. - client = UserEventServiceClient(credentials=ga_credentials.AnonymousCredentials(),) - assert isinstance(client.transport, transports.UserEventServiceGrpcTransport,) + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.UserEventServiceGrpcTransport, + ) def test_user_event_service_base_transport_error(): @@ -1551,7 +1655,8 @@ def test_user_event_service_base_transport_with_credentials_file(): Transport.return_value = None load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.UserEventServiceTransport( - credentials_file="credentials.json", quota_project_id="octopus", + credentials_file="credentials.json", + quota_project_id="octopus", ) load_creds.assert_called_once_with( "credentials.json", @@ -1709,7 +1814,8 @@ def test_user_event_service_grpc_transport_channel(): # Check that channel is used if provided. transport = transports.UserEventServiceGrpcTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" @@ -1721,7 +1827,8 @@ def test_user_event_service_grpc_asyncio_transport_channel(): # Check that channel is used if provided. transport = transports.UserEventServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" @@ -1830,12 +1937,16 @@ def test_user_event_service_transport_channel_mtls_with_adc(transport_class): def test_user_event_service_grpc_lro_client(): client = UserEventServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + 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,) + 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 @@ -1843,12 +1954,16 @@ def test_user_event_service_grpc_lro_client(): def test_user_event_service_grpc_lro_async_client(): client = UserEventServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", + 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,) + 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 @@ -1859,7 +1974,9 @@ def test_catalog_path(): location = "clam" catalog = "whelk" expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format( - project=project, location=location, catalog=catalog, + project=project, + location=location, + catalog=catalog, ) actual = UserEventServiceClient.catalog_path(project, location, catalog) assert expected == actual @@ -1934,7 +2051,9 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): folder = "cuttlefish" - expected = "folders/{folder}".format(folder=folder,) + expected = "folders/{folder}".format( + folder=folder, + ) actual = UserEventServiceClient.common_folder_path(folder) assert expected == actual @@ -1952,7 +2071,9 @@ def test_parse_common_folder_path(): def test_common_organization_path(): organization = "winkle" - expected = "organizations/{organization}".format(organization=organization,) + expected = "organizations/{organization}".format( + organization=organization, + ) actual = UserEventServiceClient.common_organization_path(organization) assert expected == actual @@ -1970,7 +2091,9 @@ def test_parse_common_organization_path(): def test_common_project_path(): project = "scallop" - expected = "projects/{project}".format(project=project,) + expected = "projects/{project}".format( + project=project, + ) actual = UserEventServiceClient.common_project_path(project) assert expected == actual @@ -1990,7 +2113,8 @@ def test_common_location_path(): project = "squid" location = "clam" expected = "projects/{project}/locations/{location}".format( - project=project, location=location, + project=project, + location=location, ) actual = UserEventServiceClient.common_location_path(project, location) assert expected == actual @@ -2015,7 +2139,8 @@ def test_client_with_default_client_info(): transports.UserEventServiceTransport, "_prep_wrapped_messages" ) as prep: client = UserEventServiceClient( - credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -2024,7 +2149,8 @@ def test_client_with_default_client_info(): ) as prep: transport_class = UserEventServiceClient.get_transport_class() transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -2032,7 +2158,8 @@ def test_client_with_default_client_info(): @pytest.mark.asyncio async def test_transport_close_async(): client = UserEventServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", ) with mock.patch.object( type(getattr(client.transport, "grpc_channel")), "close"