From c2b76f84cb3ca586d84312fe06486a441ffd5ad5 Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Mon, 24 Jan 2022 20:11:26 +0000 Subject: [PATCH 1/2] chore: upgrade gapic-generator-java, gax-java and gapic-generator-python PiperOrigin-RevId: 423842556 Source-Link: https://github.com/googleapis/googleapis/commit/a616ca08f4b1416abbac7bc5dd6d61c791756a81 Source-Link: https://github.com/googleapis/googleapis-gen/commit/29b938c58c1e51d019f2ee539d55dc0a3c86a905 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiMjliOTM4YzU4YzFlNTFkMDE5ZjJlZTUzOWQ1NWRjMGEzYzg2YTkwNSJ9 --- owl-bot-staging/v2/.coveragerc | 17 + owl-bot-staging/v2/MANIFEST.in | 2 + owl-bot-staging/v2/README.rst | 49 + owl-bot-staging/v2/docs/conf.py | 376 ++ owl-bot-staging/v2/docs/index.rst | 7 + .../v2/docs/retail_v2/catalog_service.rst | 10 + .../v2/docs/retail_v2/completion_service.rst | 6 + .../v2/docs/retail_v2/prediction_service.rst | 6 + .../v2/docs/retail_v2/product_service.rst | 10 + .../v2/docs/retail_v2/search_service.rst | 10 + .../v2/docs/retail_v2/services.rst | 11 + owl-bot-staging/v2/docs/retail_v2/types.rst | 7 + .../v2/docs/retail_v2/user_event_service.rst | 6 + .../v2/google/cloud/retail/__init__.py | 179 + .../v2/google/cloud/retail/py.typed | 2 + .../v2/google/cloud/retail_v2/__init__.py | 180 + .../cloud/retail_v2/gapic_metadata.json | 313 ++ .../v2/google/cloud/retail_v2/py.typed | 2 + .../cloud/retail_v2/services/__init__.py | 15 + .../services/catalog_service/__init__.py | 22 + .../services/catalog_service/async_client.py | 587 +++ .../services/catalog_service/client.py | 792 ++++ .../services/catalog_service/pagers.py | 140 + .../catalog_service/transports/__init__.py | 33 + .../catalog_service/transports/base.py | 189 + .../catalog_service/transports/grpc.py | 381 ++ .../transports/grpc_asyncio.py | 385 ++ .../services/completion_service/__init__.py | 22 + .../completion_service/async_client.py | 346 ++ .../services/completion_service/client.py | 544 +++ .../completion_service/transports/__init__.py | 33 + .../completion_service/transports/base.py | 167 + .../completion_service/transports/grpc.py | 318 ++ .../transports/grpc_asyncio.py | 322 ++ .../services/prediction_service/__init__.py | 22 + .../prediction_service/async_client.py | 255 ++ .../services/prediction_service/client.py | 452 +++ .../prediction_service/transports/__init__.py | 33 + .../prediction_service/transports/base.py | 145 + .../prediction_service/transports/grpc.py | 254 ++ .../transports/grpc_asyncio.py | 258 ++ .../services/product_service/__init__.py | 22 + .../services/product_service/async_client.py | 1190 ++++++ .../services/product_service/client.py | 1389 +++++++ .../services/product_service/pagers.py | 140 + .../product_service/transports/__init__.py | 33 + .../product_service/transports/base.py | 275 ++ .../product_service/transports/grpc.py | 574 +++ .../transports/grpc_asyncio.py | 578 +++ .../services/search_service/__init__.py | 22 + .../services/search_service/async_client.py | 286 ++ .../services/search_service/client.py | 492 +++ .../services/search_service/pagers.py | 139 + .../search_service/transports/__init__.py | 33 + .../search_service/transports/base.py | 145 + .../search_service/transports/grpc.py | 264 ++ .../search_service/transports/grpc_asyncio.py | 268 ++ .../services/user_event_service/__init__.py | 22 + .../user_event_service/async_client.py | 610 +++ .../services/user_event_service/client.py | 806 ++++ .../user_event_service/transports/__init__.py | 33 + .../user_event_service/transports/base.py | 226 ++ .../user_event_service/transports/grpc.py | 406 ++ .../transports/grpc_asyncio.py | 410 ++ .../google/cloud/retail_v2/types/__init__.py | 178 + .../google/cloud/retail_v2/types/catalog.py | 130 + .../cloud/retail_v2/types/catalog_service.py | 235 ++ .../v2/google/cloud/retail_v2/types/common.py | 651 +++ .../retail_v2/types/completion_service.py | 218 + .../cloud/retail_v2/types/import_config.py | 677 ++++ .../retail_v2/types/prediction_service.py | 260 ++ .../google/cloud/retail_v2/types/product.py | 689 ++++ .../cloud/retail_v2/types/product_service.py | 654 +++ .../cloud/retail_v2/types/purge_config.py | 107 + .../cloud/retail_v2/types/search_service.py | 1001 +++++ .../cloud/retail_v2/types/user_event.py | 492 +++ .../retail_v2/types/user_event_service.py | 154 + owl-bot-staging/v2/mypy.ini | 3 + owl-bot-staging/v2/noxfile.py | 132 + .../v2/scripts/fixup_retail_v2_keywords.py | 197 + owl-bot-staging/v2/setup.py | 54 + owl-bot-staging/v2/tests/__init__.py | 16 + owl-bot-staging/v2/tests/unit/__init__.py | 16 + .../v2/tests/unit/gapic/__init__.py | 16 + .../v2/tests/unit/gapic/retail_v2/__init__.py | 16 + .../gapic/retail_v2/test_catalog_service.py | 2184 ++++++++++ .../retail_v2/test_completion_service.py | 1357 +++++++ .../retail_v2/test_prediction_service.py | 1184 ++++++ .../gapic/retail_v2/test_product_service.py | 3551 +++++++++++++++++ .../gapic/retail_v2/test_search_service.py | 1398 +++++++ .../retail_v2/test_user_event_service.py | 1896 +++++++++ 91 files changed, 32737 insertions(+) create mode 100644 owl-bot-staging/v2/.coveragerc create mode 100644 owl-bot-staging/v2/MANIFEST.in create mode 100644 owl-bot-staging/v2/README.rst create mode 100644 owl-bot-staging/v2/docs/conf.py create mode 100644 owl-bot-staging/v2/docs/index.rst create mode 100644 owl-bot-staging/v2/docs/retail_v2/catalog_service.rst create mode 100644 owl-bot-staging/v2/docs/retail_v2/completion_service.rst create mode 100644 owl-bot-staging/v2/docs/retail_v2/prediction_service.rst create mode 100644 owl-bot-staging/v2/docs/retail_v2/product_service.rst create mode 100644 owl-bot-staging/v2/docs/retail_v2/search_service.rst create mode 100644 owl-bot-staging/v2/docs/retail_v2/services.rst create mode 100644 owl-bot-staging/v2/docs/retail_v2/types.rst create mode 100644 owl-bot-staging/v2/docs/retail_v2/user_event_service.rst create mode 100644 owl-bot-staging/v2/google/cloud/retail/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail/py.typed create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/gapic_metadata.json create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/py.typed create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/async_client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/pagers.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/base.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/async_client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/base.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/async_client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/base.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/async_client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/pagers.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/base.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/async_client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/pagers.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/base.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/async_client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/base.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/catalog.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/catalog_service.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/common.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/completion_service.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/import_config.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/prediction_service.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/product.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/product_service.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/purge_config.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/search_service.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/user_event.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/user_event_service.py create mode 100644 owl-bot-staging/v2/mypy.ini create mode 100644 owl-bot-staging/v2/noxfile.py create mode 100644 owl-bot-staging/v2/scripts/fixup_retail_v2_keywords.py create mode 100644 owl-bot-staging/v2/setup.py create mode 100644 owl-bot-staging/v2/tests/__init__.py create mode 100644 owl-bot-staging/v2/tests/unit/__init__.py create mode 100644 owl-bot-staging/v2/tests/unit/gapic/__init__.py create mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/__init__.py create mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_catalog_service.py create mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_completion_service.py create mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_prediction_service.py create mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_product_service.py create mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_search_service.py create mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_user_event_service.py diff --git a/owl-bot-staging/v2/.coveragerc b/owl-bot-staging/v2/.coveragerc new file mode 100644 index 00000000..a8b114f0 --- /dev/null +++ b/owl-bot-staging/v2/.coveragerc @@ -0,0 +1,17 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + google/cloud/retail/__init__.py +exclude_lines = + # Re-enable the standard pragma + pragma: NO COVER + # Ignore debug-only repr + def __repr__ + # Ignore pkg_resources exceptions. + # This is added at the module level as a safeguard for if someone + # generates the code and tries to run it without pip installing. This + # makes it virtually impossible to test properly. + except pkg_resources.DistributionNotFound diff --git a/owl-bot-staging/v2/MANIFEST.in b/owl-bot-staging/v2/MANIFEST.in new file mode 100644 index 00000000..985b915c --- /dev/null +++ b/owl-bot-staging/v2/MANIFEST.in @@ -0,0 +1,2 @@ +recursive-include google/cloud/retail *.py +recursive-include google/cloud/retail_v2 *.py diff --git a/owl-bot-staging/v2/README.rst b/owl-bot-staging/v2/README.rst new file mode 100644 index 00000000..cb039760 --- /dev/null +++ b/owl-bot-staging/v2/README.rst @@ -0,0 +1,49 @@ +Python Client for Google Cloud Retail API +================================================= + +Quick Start +----------- + +In order to use this library, you first need to go through the following steps: + +1. `Select or create a Cloud Platform project.`_ +2. `Enable billing for your project.`_ +3. Enable the Google Cloud Retail API. +4. `Setup Authentication.`_ + +.. _Select or create a Cloud Platform project.: https://console.cloud.google.com/project +.. _Enable billing for your project.: https://cloud.google.com/billing/docs/how-to/modify-project#enable_billing_for_a_project +.. _Setup Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html + +Installation +~~~~~~~~~~~~ + +Install this library in a `virtualenv`_ using pip. `virtualenv`_ is a tool to +create isolated Python environments. The basic problem it addresses is one of +dependencies and versions, and indirectly permissions. + +With `virtualenv`_, it's possible to install this library without needing system +install permissions, and without clashing with the installed system +dependencies. + +.. _`virtualenv`: https://virtualenv.pypa.io/en/latest/ + + +Mac/Linux +^^^^^^^^^ + +.. code-block:: console + + python3 -m venv + source /bin/activate + /bin/pip install /path/to/library + + +Windows +^^^^^^^ + +.. code-block:: console + + python3 -m venv + \Scripts\activate + \Scripts\pip.exe install \path\to\library diff --git a/owl-bot-staging/v2/docs/conf.py b/owl-bot-staging/v2/docs/conf.py new file mode 100644 index 00000000..649b2123 --- /dev/null +++ b/owl-bot-staging/v2/docs/conf.py @@ -0,0 +1,376 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# google-cloud-retail documentation build configuration file +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os +import shlex + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath("..")) + +__version__ = "0.1.0" + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +needs_sphinx = "1.6.3" + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.intersphinx", + "sphinx.ext.coverage", + "sphinx.ext.napoleon", + "sphinx.ext.todo", + "sphinx.ext.viewcode", +] + +# autodoc/autosummary flags +autoclass_content = "both" +autodoc_default_flags = ["members"] +autosummary_generate = True + + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# Allow markdown includes (so releases.md can include CHANGLEOG.md) +# http://www.sphinx-doc.org/en/master/markdown.html +source_parsers = {".md": "recommonmark.parser.CommonMarkParser"} + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +source_suffix = [".rst", ".md"] + +# The encoding of source files. +# source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = "index" + +# General information about the project. +project = u"google-cloud-retail" +copyright = u"2020, Google, LLC" +author = u"Google APIs" # TODO: autogenerate this bit + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The full version, including alpha/beta/rc tags. +release = __version__ +# The short X.Y version. +version = ".".join(release.split(".")[0:2]) + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +# today = '' +# Else, today_fmt is used as the format for a strftime call. +# today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ["_build"] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +# default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +# add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +# add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +# show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" + +# A list of ignored prefixes for module index sorting. +# modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +# keep_warnings = False + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = "alabaster" + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +html_theme_options = { + "description": "Google Cloud Client Libraries for Python", + "github_user": "googleapis", + "github_repo": "google-cloud-python", + "github_banner": True, + "font_family": "'Roboto', Georgia, sans", + "head_font_family": "'Roboto', Georgia, serif", + "code_font_family": "'Roboto Mono', 'Consolas', monospace", +} + +# Add any paths that contain custom themes here, relative to this directory. +# html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +# html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +# html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +# html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +# html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +# html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +# html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +# html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +# html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +# html_additional_pages = {} + +# If false, no module index is generated. +# html_domain_indices = True + +# If false, no index is generated. +# html_use_index = True + +# If true, the index is split into individual pages for each letter. +# html_split_index = False + +# If true, links to the reST sources are added to the pages. +# html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +# html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +# html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +# html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +# html_file_suffix = None + +# Language to be used for generating the HTML full-text search index. +# Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' +# html_search_language = 'en' + +# A dictionary with options for the search language support, empty by default. +# Now only 'ja' uses this config value +# html_search_options = {'type': 'default'} + +# The name of a javascript file (relative to the configuration directory) that +# implements a search results scorer. If empty, the default will be used. +# html_search_scorer = 'scorer.js' + +# Output file base name for HTML help builder. +htmlhelp_basename = "google-cloud-retail-doc" + +# -- Options for warnings ------------------------------------------------------ + + +suppress_warnings = [ + # Temporarily suppress this to avoid "more than one target found for + # cross-reference" warning, which are intractable for us to avoid while in + # a mono-repo. + # See https://github.com/sphinx-doc/sphinx/blob + # /2a65ffeef5c107c19084fabdd706cdff3f52d93c/sphinx/domains/python.py#L843 + "ref.python" +] + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # 'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + # 'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + # 'preamble': '', + # Latex figure (float) alignment + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ( + master_doc, + "google-cloud-retail.tex", + u"google-cloud-retail Documentation", + author, + "manual", + ) +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +# latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +# latex_use_parts = False + +# If true, show page references after internal links. +# latex_show_pagerefs = False + +# If true, show URL addresses after external links. +# latex_show_urls = False + +# Documents to append as an appendix to all manuals. +# latex_appendices = [] + +# If false, no module index is generated. +# latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ( + master_doc, + "google-cloud-retail", + u"Google Cloud Retail Documentation", + [author], + 1, + ) +] + +# If true, show URL addresses after external links. +# man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ( + master_doc, + "google-cloud-retail", + u"google-cloud-retail Documentation", + author, + "google-cloud-retail", + "GAPIC library for Google Cloud Retail API", + "APIs", + ) +] + +# Documents to append as an appendix to all manuals. +# texinfo_appendices = [] + +# If false, no module index is generated. +# texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +# texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +# texinfo_no_detailmenu = False + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = { + "python": ("http://python.readthedocs.org/en/latest/", None), + "gax": ("https://gax-python.readthedocs.org/en/latest/", None), + "google-auth": ("https://google-auth.readthedocs.io/en/stable", None), + "google-gax": ("https://gax-python.readthedocs.io/en/latest/", None), + "google.api_core": ("https://googleapis.dev/python/google-api-core/latest/", None), + "grpc": ("https://grpc.io/grpc/python/", None), + "requests": ("http://requests.kennethreitz.org/en/stable/", None), + "proto": ("https://proto-plus-python.readthedocs.io/en/stable", None), + "protobuf": ("https://googleapis.dev/python/protobuf/latest/", None), +} + + +# Napoleon settings +napoleon_google_docstring = True +napoleon_numpy_docstring = True +napoleon_include_private_with_doc = False +napoleon_include_special_with_doc = True +napoleon_use_admonition_for_examples = False +napoleon_use_admonition_for_notes = False +napoleon_use_admonition_for_references = False +napoleon_use_ivar = False +napoleon_use_param = True +napoleon_use_rtype = True diff --git a/owl-bot-staging/v2/docs/index.rst b/owl-bot-staging/v2/docs/index.rst new file mode 100644 index 00000000..c70f61bc --- /dev/null +++ b/owl-bot-staging/v2/docs/index.rst @@ -0,0 +1,7 @@ +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + retail_v2/services + retail_v2/types diff --git a/owl-bot-staging/v2/docs/retail_v2/catalog_service.rst b/owl-bot-staging/v2/docs/retail_v2/catalog_service.rst new file mode 100644 index 00000000..5b7227d9 --- /dev/null +++ b/owl-bot-staging/v2/docs/retail_v2/catalog_service.rst @@ -0,0 +1,10 @@ +CatalogService +-------------------------------- + +.. automodule:: google.cloud.retail_v2.services.catalog_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2.services.catalog_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v2/docs/retail_v2/completion_service.rst b/owl-bot-staging/v2/docs/retail_v2/completion_service.rst new file mode 100644 index 00000000..551f89ed --- /dev/null +++ b/owl-bot-staging/v2/docs/retail_v2/completion_service.rst @@ -0,0 +1,6 @@ +CompletionService +----------------------------------- + +.. automodule:: google.cloud.retail_v2.services.completion_service + :members: + :inherited-members: diff --git a/owl-bot-staging/v2/docs/retail_v2/prediction_service.rst b/owl-bot-staging/v2/docs/retail_v2/prediction_service.rst new file mode 100644 index 00000000..12ffb6ee --- /dev/null +++ b/owl-bot-staging/v2/docs/retail_v2/prediction_service.rst @@ -0,0 +1,6 @@ +PredictionService +----------------------------------- + +.. automodule:: google.cloud.retail_v2.services.prediction_service + :members: + :inherited-members: diff --git a/owl-bot-staging/v2/docs/retail_v2/product_service.rst b/owl-bot-staging/v2/docs/retail_v2/product_service.rst new file mode 100644 index 00000000..0b8fa911 --- /dev/null +++ b/owl-bot-staging/v2/docs/retail_v2/product_service.rst @@ -0,0 +1,10 @@ +ProductService +-------------------------------- + +.. automodule:: google.cloud.retail_v2.services.product_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2.services.product_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v2/docs/retail_v2/search_service.rst b/owl-bot-staging/v2/docs/retail_v2/search_service.rst new file mode 100644 index 00000000..af72819d --- /dev/null +++ b/owl-bot-staging/v2/docs/retail_v2/search_service.rst @@ -0,0 +1,10 @@ +SearchService +------------------------------- + +.. automodule:: google.cloud.retail_v2.services.search_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2.services.search_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v2/docs/retail_v2/services.rst b/owl-bot-staging/v2/docs/retail_v2/services.rst new file mode 100644 index 00000000..f86138d7 --- /dev/null +++ b/owl-bot-staging/v2/docs/retail_v2/services.rst @@ -0,0 +1,11 @@ +Services for Google Cloud Retail v2 API +======================================= +.. toctree:: + :maxdepth: 2 + + catalog_service + completion_service + prediction_service + product_service + search_service + user_event_service diff --git a/owl-bot-staging/v2/docs/retail_v2/types.rst b/owl-bot-staging/v2/docs/retail_v2/types.rst new file mode 100644 index 00000000..54951beb --- /dev/null +++ b/owl-bot-staging/v2/docs/retail_v2/types.rst @@ -0,0 +1,7 @@ +Types for Google Cloud Retail v2 API +==================================== + +.. automodule:: google.cloud.retail_v2.types + :members: + :undoc-members: + :show-inheritance: diff --git a/owl-bot-staging/v2/docs/retail_v2/user_event_service.rst b/owl-bot-staging/v2/docs/retail_v2/user_event_service.rst new file mode 100644 index 00000000..00e214a9 --- /dev/null +++ b/owl-bot-staging/v2/docs/retail_v2/user_event_service.rst @@ -0,0 +1,6 @@ +UserEventService +---------------------------------- + +.. automodule:: google.cloud.retail_v2.services.user_event_service + :members: + :inherited-members: diff --git a/owl-bot-staging/v2/google/cloud/retail/__init__.py b/owl-bot-staging/v2/google/cloud/retail/__init__.py new file mode 100644 index 00000000..f2ff862d --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail/__init__.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from google.cloud.retail_v2.services.catalog_service.client import CatalogServiceClient +from google.cloud.retail_v2.services.catalog_service.async_client import CatalogServiceAsyncClient +from google.cloud.retail_v2.services.completion_service.client import CompletionServiceClient +from google.cloud.retail_v2.services.completion_service.async_client import CompletionServiceAsyncClient +from google.cloud.retail_v2.services.prediction_service.client import PredictionServiceClient +from google.cloud.retail_v2.services.prediction_service.async_client import PredictionServiceAsyncClient +from google.cloud.retail_v2.services.product_service.client import ProductServiceClient +from google.cloud.retail_v2.services.product_service.async_client import ProductServiceAsyncClient +from google.cloud.retail_v2.services.search_service.client import SearchServiceClient +from google.cloud.retail_v2.services.search_service.async_client import SearchServiceAsyncClient +from google.cloud.retail_v2.services.user_event_service.client import UserEventServiceClient +from google.cloud.retail_v2.services.user_event_service.async_client import UserEventServiceAsyncClient + +from google.cloud.retail_v2.types.catalog import Catalog +from google.cloud.retail_v2.types.catalog import ProductLevelConfig +from google.cloud.retail_v2.types.catalog_service import GetDefaultBranchRequest +from google.cloud.retail_v2.types.catalog_service import GetDefaultBranchResponse +from google.cloud.retail_v2.types.catalog_service import ListCatalogsRequest +from google.cloud.retail_v2.types.catalog_service import ListCatalogsResponse +from google.cloud.retail_v2.types.catalog_service import SetDefaultBranchRequest +from google.cloud.retail_v2.types.catalog_service import UpdateCatalogRequest +from google.cloud.retail_v2.types.common import Audience +from google.cloud.retail_v2.types.common import ColorInfo +from google.cloud.retail_v2.types.common import CustomAttribute +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 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 +from google.cloud.retail_v2.types.completion_service import CompleteQueryResponse +from google.cloud.retail_v2.types.import_config import BigQuerySource +from google.cloud.retail_v2.types.import_config import CompletionDataInputConfig +from google.cloud.retail_v2.types.import_config import GcsSource +from google.cloud.retail_v2.types.import_config import ImportCompletionDataRequest +from google.cloud.retail_v2.types.import_config import ImportCompletionDataResponse +from google.cloud.retail_v2.types.import_config import ImportErrorsConfig +from google.cloud.retail_v2.types.import_config import ImportMetadata +from google.cloud.retail_v2.types.import_config import ImportProductsRequest +from google.cloud.retail_v2.types.import_config import ImportProductsResponse +from google.cloud.retail_v2.types.import_config import ImportUserEventsRequest +from google.cloud.retail_v2.types.import_config import ImportUserEventsResponse +from google.cloud.retail_v2.types.import_config import ProductInlineSource +from google.cloud.retail_v2.types.import_config import ProductInputConfig +from google.cloud.retail_v2.types.import_config import UserEventImportSummary +from google.cloud.retail_v2.types.import_config import UserEventInlineSource +from google.cloud.retail_v2.types.import_config import UserEventInputConfig +from google.cloud.retail_v2.types.prediction_service import PredictRequest +from google.cloud.retail_v2.types.prediction_service import PredictResponse +from google.cloud.retail_v2.types.product import Product +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 CreateProductRequest +from google.cloud.retail_v2.types.product_service import DeleteProductRequest +from google.cloud.retail_v2.types.product_service import GetProductRequest +from google.cloud.retail_v2.types.product_service import ListProductsRequest +from google.cloud.retail_v2.types.product_service import ListProductsResponse +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 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.purge_config import PurgeMetadata +from google.cloud.retail_v2.types.purge_config import PurgeUserEventsRequest +from google.cloud.retail_v2.types.purge_config import PurgeUserEventsResponse +from google.cloud.retail_v2.types.search_service import SearchRequest +from google.cloud.retail_v2.types.search_service import SearchResponse +from google.cloud.retail_v2.types.user_event import CompletionDetail +from google.cloud.retail_v2.types.user_event import ProductDetail +from google.cloud.retail_v2.types.user_event import PurchaseTransaction +from google.cloud.retail_v2.types.user_event import UserEvent +from google.cloud.retail_v2.types.user_event_service import CollectUserEventRequest +from google.cloud.retail_v2.types.user_event_service import RejoinUserEventsMetadata +from google.cloud.retail_v2.types.user_event_service import RejoinUserEventsRequest +from google.cloud.retail_v2.types.user_event_service import RejoinUserEventsResponse +from google.cloud.retail_v2.types.user_event_service import WriteUserEventRequest + +__all__ = ('CatalogServiceClient', + 'CatalogServiceAsyncClient', + 'CompletionServiceClient', + 'CompletionServiceAsyncClient', + 'PredictionServiceClient', + 'PredictionServiceAsyncClient', + 'ProductServiceClient', + 'ProductServiceAsyncClient', + 'SearchServiceClient', + 'SearchServiceAsyncClient', + 'UserEventServiceClient', + 'UserEventServiceAsyncClient', + 'Catalog', + 'ProductLevelConfig', + 'GetDefaultBranchRequest', + 'GetDefaultBranchResponse', + 'ListCatalogsRequest', + 'ListCatalogsResponse', + 'SetDefaultBranchRequest', + 'UpdateCatalogRequest', + 'Audience', + 'ColorInfo', + 'CustomAttribute', + 'FulfillmentInfo', + 'Image', + 'Interval', + 'PriceInfo', + 'Promotion', + 'Rating', + 'UserInfo', + 'CompleteQueryRequest', + 'CompleteQueryResponse', + 'BigQuerySource', + 'CompletionDataInputConfig', + 'GcsSource', + 'ImportCompletionDataRequest', + 'ImportCompletionDataResponse', + 'ImportErrorsConfig', + 'ImportMetadata', + 'ImportProductsRequest', + 'ImportProductsResponse', + 'ImportUserEventsRequest', + 'ImportUserEventsResponse', + 'ProductInlineSource', + 'ProductInputConfig', + 'UserEventImportSummary', + 'UserEventInlineSource', + 'UserEventInputConfig', + 'PredictRequest', + 'PredictResponse', + 'Product', + 'AddFulfillmentPlacesMetadata', + 'AddFulfillmentPlacesRequest', + 'AddFulfillmentPlacesResponse', + 'CreateProductRequest', + 'DeleteProductRequest', + 'GetProductRequest', + 'ListProductsRequest', + 'ListProductsResponse', + 'RemoveFulfillmentPlacesMetadata', + 'RemoveFulfillmentPlacesRequest', + 'RemoveFulfillmentPlacesResponse', + 'SetInventoryMetadata', + 'SetInventoryRequest', + 'SetInventoryResponse', + 'UpdateProductRequest', + 'PurgeMetadata', + 'PurgeUserEventsRequest', + 'PurgeUserEventsResponse', + 'SearchRequest', + 'SearchResponse', + 'CompletionDetail', + 'ProductDetail', + 'PurchaseTransaction', + 'UserEvent', + 'CollectUserEventRequest', + 'RejoinUserEventsMetadata', + 'RejoinUserEventsRequest', + 'RejoinUserEventsResponse', + 'WriteUserEventRequest', +) diff --git a/owl-bot-staging/v2/google/cloud/retail/py.typed b/owl-bot-staging/v2/google/cloud/retail/py.typed new file mode 100644 index 00000000..fda82836 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-retail package uses inline types. diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/__init__.py new file mode 100644 index 00000000..9bd379b4 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/__init__.py @@ -0,0 +1,180 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from .services.catalog_service import CatalogServiceClient +from .services.catalog_service import CatalogServiceAsyncClient +from .services.completion_service import CompletionServiceClient +from .services.completion_service import CompletionServiceAsyncClient +from .services.prediction_service import PredictionServiceClient +from .services.prediction_service import PredictionServiceAsyncClient +from .services.product_service import ProductServiceClient +from .services.product_service import ProductServiceAsyncClient +from .services.search_service import SearchServiceClient +from .services.search_service import SearchServiceAsyncClient +from .services.user_event_service import UserEventServiceClient +from .services.user_event_service import UserEventServiceAsyncClient + +from .types.catalog import Catalog +from .types.catalog import ProductLevelConfig +from .types.catalog_service import GetDefaultBranchRequest +from .types.catalog_service import GetDefaultBranchResponse +from .types.catalog_service import ListCatalogsRequest +from .types.catalog_service import ListCatalogsResponse +from .types.catalog_service import SetDefaultBranchRequest +from .types.catalog_service import UpdateCatalogRequest +from .types.common import Audience +from .types.common import ColorInfo +from .types.common import CustomAttribute +from .types.common import FulfillmentInfo +from .types.common import Image +from .types.common import Interval +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 +from .types.completion_service import CompleteQueryResponse +from .types.import_config import BigQuerySource +from .types.import_config import CompletionDataInputConfig +from .types.import_config import GcsSource +from .types.import_config import ImportCompletionDataRequest +from .types.import_config import ImportCompletionDataResponse +from .types.import_config import ImportErrorsConfig +from .types.import_config import ImportMetadata +from .types.import_config import ImportProductsRequest +from .types.import_config import ImportProductsResponse +from .types.import_config import ImportUserEventsRequest +from .types.import_config import ImportUserEventsResponse +from .types.import_config import ProductInlineSource +from .types.import_config import ProductInputConfig +from .types.import_config import UserEventImportSummary +from .types.import_config import UserEventInlineSource +from .types.import_config import UserEventInputConfig +from .types.prediction_service import PredictRequest +from .types.prediction_service import PredictResponse +from .types.product import Product +from .types.product_service import AddFulfillmentPlacesMetadata +from .types.product_service import AddFulfillmentPlacesRequest +from .types.product_service import AddFulfillmentPlacesResponse +from .types.product_service import CreateProductRequest +from .types.product_service import DeleteProductRequest +from .types.product_service import GetProductRequest +from .types.product_service import ListProductsRequest +from .types.product_service import ListProductsResponse +from .types.product_service import RemoveFulfillmentPlacesMetadata +from .types.product_service import RemoveFulfillmentPlacesRequest +from .types.product_service import RemoveFulfillmentPlacesResponse +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.purge_config import PurgeMetadata +from .types.purge_config import PurgeUserEventsRequest +from .types.purge_config import PurgeUserEventsResponse +from .types.search_service import SearchRequest +from .types.search_service import SearchResponse +from .types.user_event import CompletionDetail +from .types.user_event import ProductDetail +from .types.user_event import PurchaseTransaction +from .types.user_event import UserEvent +from .types.user_event_service import CollectUserEventRequest +from .types.user_event_service import RejoinUserEventsMetadata +from .types.user_event_service import RejoinUserEventsRequest +from .types.user_event_service import RejoinUserEventsResponse +from .types.user_event_service import WriteUserEventRequest + +__all__ = ( + 'CatalogServiceAsyncClient', + 'CompletionServiceAsyncClient', + 'PredictionServiceAsyncClient', + 'ProductServiceAsyncClient', + 'SearchServiceAsyncClient', + 'UserEventServiceAsyncClient', +'AddFulfillmentPlacesMetadata', +'AddFulfillmentPlacesRequest', +'AddFulfillmentPlacesResponse', +'Audience', +'BigQuerySource', +'Catalog', +'CatalogServiceClient', +'CollectUserEventRequest', +'ColorInfo', +'CompleteQueryRequest', +'CompleteQueryResponse', +'CompletionDataInputConfig', +'CompletionDetail', +'CompletionServiceClient', +'CreateProductRequest', +'CustomAttribute', +'DeleteProductRequest', +'FulfillmentInfo', +'GcsSource', +'GetDefaultBranchRequest', +'GetDefaultBranchResponse', +'GetProductRequest', +'Image', +'ImportCompletionDataRequest', +'ImportCompletionDataResponse', +'ImportErrorsConfig', +'ImportMetadata', +'ImportProductsRequest', +'ImportProductsResponse', +'ImportUserEventsRequest', +'ImportUserEventsResponse', +'Interval', +'ListCatalogsRequest', +'ListCatalogsResponse', +'ListProductsRequest', +'ListProductsResponse', +'PredictRequest', +'PredictResponse', +'PredictionServiceClient', +'PriceInfo', +'Product', +'ProductDetail', +'ProductInlineSource', +'ProductInputConfig', +'ProductLevelConfig', +'ProductServiceClient', +'Promotion', +'PurchaseTransaction', +'PurgeMetadata', +'PurgeUserEventsRequest', +'PurgeUserEventsResponse', +'Rating', +'RejoinUserEventsMetadata', +'RejoinUserEventsRequest', +'RejoinUserEventsResponse', +'RemoveFulfillmentPlacesMetadata', +'RemoveFulfillmentPlacesRequest', +'RemoveFulfillmentPlacesResponse', +'SearchRequest', +'SearchResponse', +'SearchServiceClient', +'SetDefaultBranchRequest', +'SetInventoryMetadata', +'SetInventoryRequest', +'SetInventoryResponse', +'UpdateCatalogRequest', +'UpdateProductRequest', +'UserEvent', +'UserEventImportSummary', +'UserEventInlineSource', +'UserEventInputConfig', +'UserEventServiceClient', +'UserInfo', +'WriteUserEventRequest', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/gapic_metadata.json b/owl-bot-staging/v2/google/cloud/retail_v2/gapic_metadata.json new file mode 100644 index 00000000..088fcc42 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/gapic_metadata.json @@ -0,0 +1,313 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.cloud.retail_v2", + "protoPackage": "google.cloud.retail.v2", + "schema": "1.0", + "services": { + "CatalogService": { + "clients": { + "grpc": { + "libraryClient": "CatalogServiceClient", + "rpcs": { + "GetDefaultBranch": { + "methods": [ + "get_default_branch" + ] + }, + "ListCatalogs": { + "methods": [ + "list_catalogs" + ] + }, + "SetDefaultBranch": { + "methods": [ + "set_default_branch" + ] + }, + "UpdateCatalog": { + "methods": [ + "update_catalog" + ] + } + } + }, + "grpc-async": { + "libraryClient": "CatalogServiceAsyncClient", + "rpcs": { + "GetDefaultBranch": { + "methods": [ + "get_default_branch" + ] + }, + "ListCatalogs": { + "methods": [ + "list_catalogs" + ] + }, + "SetDefaultBranch": { + "methods": [ + "set_default_branch" + ] + }, + "UpdateCatalog": { + "methods": [ + "update_catalog" + ] + } + } + } + } + }, + "CompletionService": { + "clients": { + "grpc": { + "libraryClient": "CompletionServiceClient", + "rpcs": { + "CompleteQuery": { + "methods": [ + "complete_query" + ] + }, + "ImportCompletionData": { + "methods": [ + "import_completion_data" + ] + } + } + }, + "grpc-async": { + "libraryClient": "CompletionServiceAsyncClient", + "rpcs": { + "CompleteQuery": { + "methods": [ + "complete_query" + ] + }, + "ImportCompletionData": { + "methods": [ + "import_completion_data" + ] + } + } + } + } + }, + "PredictionService": { + "clients": { + "grpc": { + "libraryClient": "PredictionServiceClient", + "rpcs": { + "Predict": { + "methods": [ + "predict" + ] + } + } + }, + "grpc-async": { + "libraryClient": "PredictionServiceAsyncClient", + "rpcs": { + "Predict": { + "methods": [ + "predict" + ] + } + } + } + } + }, + "ProductService": { + "clients": { + "grpc": { + "libraryClient": "ProductServiceClient", + "rpcs": { + "AddFulfillmentPlaces": { + "methods": [ + "add_fulfillment_places" + ] + }, + "CreateProduct": { + "methods": [ + "create_product" + ] + }, + "DeleteProduct": { + "methods": [ + "delete_product" + ] + }, + "GetProduct": { + "methods": [ + "get_product" + ] + }, + "ImportProducts": { + "methods": [ + "import_products" + ] + }, + "ListProducts": { + "methods": [ + "list_products" + ] + }, + "RemoveFulfillmentPlaces": { + "methods": [ + "remove_fulfillment_places" + ] + }, + "SetInventory": { + "methods": [ + "set_inventory" + ] + }, + "UpdateProduct": { + "methods": [ + "update_product" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ProductServiceAsyncClient", + "rpcs": { + "AddFulfillmentPlaces": { + "methods": [ + "add_fulfillment_places" + ] + }, + "CreateProduct": { + "methods": [ + "create_product" + ] + }, + "DeleteProduct": { + "methods": [ + "delete_product" + ] + }, + "GetProduct": { + "methods": [ + "get_product" + ] + }, + "ImportProducts": { + "methods": [ + "import_products" + ] + }, + "ListProducts": { + "methods": [ + "list_products" + ] + }, + "RemoveFulfillmentPlaces": { + "methods": [ + "remove_fulfillment_places" + ] + }, + "SetInventory": { + "methods": [ + "set_inventory" + ] + }, + "UpdateProduct": { + "methods": [ + "update_product" + ] + } + } + } + } + }, + "SearchService": { + "clients": { + "grpc": { + "libraryClient": "SearchServiceClient", + "rpcs": { + "Search": { + "methods": [ + "search" + ] + } + } + }, + "grpc-async": { + "libraryClient": "SearchServiceAsyncClient", + "rpcs": { + "Search": { + "methods": [ + "search" + ] + } + } + } + } + }, + "UserEventService": { + "clients": { + "grpc": { + "libraryClient": "UserEventServiceClient", + "rpcs": { + "CollectUserEvent": { + "methods": [ + "collect_user_event" + ] + }, + "ImportUserEvents": { + "methods": [ + "import_user_events" + ] + }, + "PurgeUserEvents": { + "methods": [ + "purge_user_events" + ] + }, + "RejoinUserEvents": { + "methods": [ + "rejoin_user_events" + ] + }, + "WriteUserEvent": { + "methods": [ + "write_user_event" + ] + } + } + }, + "grpc-async": { + "libraryClient": "UserEventServiceAsyncClient", + "rpcs": { + "CollectUserEvent": { + "methods": [ + "collect_user_event" + ] + }, + "ImportUserEvents": { + "methods": [ + "import_user_events" + ] + }, + "PurgeUserEvents": { + "methods": [ + "purge_user_events" + ] + }, + "RejoinUserEvents": { + "methods": [ + "rejoin_user_events" + ] + }, + "WriteUserEvent": { + "methods": [ + "write_user_event" + ] + } + } + } + } + } + } +} diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/py.typed b/owl-bot-staging/v2/google/cloud/retail_v2/py.typed new file mode 100644 index 00000000..fda82836 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-retail package uses inline types. diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/__init__.py new file mode 100644 index 00000000..4de65971 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/__init__.py new file mode 100644 index 00000000..316640d9 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .client import CatalogServiceClient +from .async_client import CatalogServiceAsyncClient + +__all__ = ( + 'CatalogServiceClient', + 'CatalogServiceAsyncClient', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/async_client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/async_client.py new file mode 100644 index 00000000..0510e57a --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/async_client.py @@ -0,0 +1,587 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +import functools +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.cloud.retail_v2.services.catalog_service import pagers +from google.cloud.retail_v2.types import catalog +from google.cloud.retail_v2.types import catalog as gcr_catalog +from google.cloud.retail_v2.types import catalog_service +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import CatalogServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import CatalogServiceGrpcAsyncIOTransport +from .client import CatalogServiceClient + + +class CatalogServiceAsyncClient: + """Service for managing catalog configuration.""" + + _client: CatalogServiceClient + + DEFAULT_ENDPOINT = CatalogServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CatalogServiceClient.DEFAULT_MTLS_ENDPOINT + + branch_path = staticmethod(CatalogServiceClient.branch_path) + parse_branch_path = staticmethod(CatalogServiceClient.parse_branch_path) + catalog_path = staticmethod(CatalogServiceClient.catalog_path) + parse_catalog_path = staticmethod(CatalogServiceClient.parse_catalog_path) + common_billing_account_path = staticmethod(CatalogServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(CatalogServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(CatalogServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(CatalogServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(CatalogServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(CatalogServiceClient.parse_common_organization_path) + common_project_path = staticmethod(CatalogServiceClient.common_project_path) + parse_common_project_path = staticmethod(CatalogServiceClient.parse_common_project_path) + common_location_path = staticmethod(CatalogServiceClient.common_location_path) + parse_common_location_path = staticmethod(CatalogServiceClient.parse_common_location_path) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CatalogServiceAsyncClient: The constructed client. + """ + return CatalogServiceClient.from_service_account_info.__func__(CatalogServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CatalogServiceAsyncClient: The constructed client. + """ + return CatalogServiceClient.from_service_account_file.__func__(CatalogServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CatalogServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CatalogServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CatalogServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(CatalogServiceClient).get_transport_class, type(CatalogServiceClient)) + + def __init__(self, *, + credentials: ga_credentials.Credentials = None, + transport: Union[str, CatalogServiceTransport] = "grpc_asyncio", + client_options: ClientOptions = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the catalog service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.CatalogServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CatalogServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def list_catalogs(self, + request: Union[catalog_service.ListCatalogsRequest, dict] = None, + *, + parent: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListCatalogsAsyncPager: + r"""Lists all the [Catalog][google.cloud.retail.v2.Catalog]s + associated with the project. + + Args: + request (Union[google.cloud.retail_v2.types.ListCatalogsRequest, dict]): + The request object. Request for + [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] + method. + parent (:class:`str`): + Required. The account resource name with an associated + location. + + If the caller does not have permission to list + [Catalog][google.cloud.retail.v2.Catalog]s under this + location, regardless of whether or not this location + exists, a PERMISSION_DENIED error is returned. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.services.catalog_service.pagers.ListCatalogsAsyncPager: + Response for + [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = catalog_service.ListCatalogsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_catalogs, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListCatalogsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_catalog(self, + request: Union[catalog_service.UpdateCatalogRequest, dict] = None, + *, + catalog: gcr_catalog.Catalog = None, + update_mask: field_mask_pb2.FieldMask = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_catalog.Catalog: + r"""Updates the [Catalog][google.cloud.retail.v2.Catalog]s. + + Args: + request (Union[google.cloud.retail_v2.types.UpdateCatalogRequest, dict]): + The request object. Request for + [CatalogService.UpdateCatalog][google.cloud.retail.v2.CatalogService.UpdateCatalog] + method. + catalog (:class:`google.cloud.retail_v2.types.Catalog`): + Required. The [Catalog][google.cloud.retail.v2.Catalog] + to update. + + If the caller does not have permission to update the + [Catalog][google.cloud.retail.v2.Catalog], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Catalog][google.cloud.retail.v2.Catalog] to + update does not exist, a NOT_FOUND error is returned. + + This corresponds to the ``catalog`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Indicates which fields in the provided + [Catalog][google.cloud.retail.v2.Catalog] to update. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.Catalog: + The catalog configuration. + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([catalog, update_mask]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = catalog_service.UpdateCatalogRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_catalog, + 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(( + ("catalog.name", request.catalog.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def set_default_branch(self, + request: Union[catalog_service.SetDefaultBranchRequest, dict] = None, + *, + catalog: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Set a specified branch id as default branch. API methods such as + [SearchService.Search][google.cloud.retail.v2.SearchService.Search], + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct], + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + will treat requests using "default_branch" to the actual branch + id set as default. + + For example, if ``projects/*/locations/*/catalogs/*/branches/1`` + is set as default, setting + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/default_branch`` + is equivalent to setting + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/1``. + + Using multiple branches can be useful when developers would like + to have a staging branch to test and verify for future usage. + When it becomes ready, developers switch on the staging branch + using this API while keeping using + ``projects/*/locations/*/catalogs/*/branches/default_branch`` as + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to route the traffic to this staging branch. + + CAUTION: If you have live predict/search traffic, switching the + default branch could potentially cause outages if the ID space + of the new branch is very different from the old one. + + More specifically: + + - PredictionService will only return product IDs from branch + {newBranch}. + - SearchService will only return product IDs from branch + {newBranch} (if branch is not explicitly set). + - 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. + + Args: + request (Union[google.cloud.retail_v2.types.SetDefaultBranchRequest, dict]): + The request object. Request message to set a specified + branch as new default_branch. + catalog (:class:`str`): + Full resource name of the catalog, such as + ``projects/*/locations/global/catalogs/default_catalog``. + + This corresponds to the ``catalog`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([catalog]) + 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 = catalog_service.SetDefaultBranchRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.set_default_branch, + 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(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def get_default_branch(self, + request: Union[catalog_service.GetDefaultBranchRequest, dict] = None, + *, + catalog: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog_service.GetDefaultBranchResponse: + r"""Get which branch is currently default branch set by + [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. + + Args: + request (Union[google.cloud.retail_v2.types.GetDefaultBranchRequest, dict]): + The request object. Request message to show which branch + is currently the default branch. + catalog (:class:`str`): + The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog``. + + This corresponds to the ``catalog`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.GetDefaultBranchResponse: + Response message of + [CatalogService.GetDefaultBranch][google.cloud.retail.v2.CatalogService.GetDefaultBranch]. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([catalog]) + 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 = catalog_service.GetDefaultBranchRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_default_branch, + 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(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ( + "CatalogServiceAsyncClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/client.py new file mode 100644 index 00000000..baf571c1 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/client.py @@ -0,0 +1,792 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +import os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.cloud.retail_v2.services.catalog_service import pagers +from google.cloud.retail_v2.types import catalog +from google.cloud.retail_v2.types import catalog as gcr_catalog +from google.cloud.retail_v2.types import catalog_service +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import CatalogServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CatalogServiceGrpcTransport +from .transports.grpc_asyncio import CatalogServiceGrpcAsyncIOTransport + + +class CatalogServiceClientMeta(type): + """Metaclass for the CatalogService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + _transport_registry = OrderedDict() # type: Dict[str, Type[CatalogServiceTransport]] + _transport_registry["grpc"] = CatalogServiceGrpcTransport + _transport_registry["grpc_asyncio"] = CatalogServiceGrpcAsyncIOTransport + + def get_transport_class(cls, + label: str = None, + ) -> Type[CatalogServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CatalogServiceClient(metaclass=CatalogServiceClientMeta): + """Service for managing catalog configuration.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "retail.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CatalogServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CatalogServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CatalogServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CatalogServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + 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, ) + + @staticmethod + def parse_branch_path(path: str) -> Dict[str,str]: + """Parses a branch path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str, ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str,str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str, ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder, ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str,str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str, ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization, ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str,str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str, ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project, ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str,str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str, ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format(project=project, location=location, ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str,str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError("Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError("Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`") + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CatalogServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the catalog service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CatalogServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options) + + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError("client_options.api_key and credentials are mutually exclusive") + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CatalogServiceTransport): + # transport is a CatalogServiceTransport instance. + if credentials or client_options.credentials_file or api_key_value: + raise ValueError("When providing a transport instance, " + "provide its credentials directly.") + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + import google.auth._default # type: ignore + + if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"): + credentials = google.auth._default.get_api_key_credentials(api_key_value) + + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def list_catalogs(self, + request: Union[catalog_service.ListCatalogsRequest, dict] = None, + *, + parent: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListCatalogsPager: + r"""Lists all the [Catalog][google.cloud.retail.v2.Catalog]s + associated with the project. + + Args: + request (Union[google.cloud.retail_v2.types.ListCatalogsRequest, dict]): + The request object. Request for + [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] + method. + parent (str): + Required. The account resource name with an associated + location. + + If the caller does not have permission to list + [Catalog][google.cloud.retail.v2.Catalog]s under this + location, regardless of whether or not this location + exists, a PERMISSION_DENIED error is returned. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.services.catalog_service.pagers.ListCatalogsPager: + Response for + [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a catalog_service.ListCatalogsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.ListCatalogsRequest): + request = catalog_service.ListCatalogsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_catalogs] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListCatalogsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_catalog(self, + request: Union[catalog_service.UpdateCatalogRequest, dict] = None, + *, + catalog: gcr_catalog.Catalog = None, + update_mask: field_mask_pb2.FieldMask = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_catalog.Catalog: + r"""Updates the [Catalog][google.cloud.retail.v2.Catalog]s. + + Args: + request (Union[google.cloud.retail_v2.types.UpdateCatalogRequest, dict]): + The request object. Request for + [CatalogService.UpdateCatalog][google.cloud.retail.v2.CatalogService.UpdateCatalog] + method. + catalog (google.cloud.retail_v2.types.Catalog): + Required. The [Catalog][google.cloud.retail.v2.Catalog] + to update. + + If the caller does not have permission to update the + [Catalog][google.cloud.retail.v2.Catalog], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Catalog][google.cloud.retail.v2.Catalog] to + update does not exist, a NOT_FOUND error is returned. + + This corresponds to the ``catalog`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [Catalog][google.cloud.retail.v2.Catalog] to update. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.Catalog: + The catalog configuration. + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([catalog, update_mask]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a catalog_service.UpdateCatalogRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.UpdateCatalogRequest): + request = catalog_service.UpdateCatalogRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_catalog] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("catalog.name", request.catalog.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def set_default_branch(self, + request: Union[catalog_service.SetDefaultBranchRequest, dict] = None, + *, + catalog: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Set a specified branch id as default branch. API methods such as + [SearchService.Search][google.cloud.retail.v2.SearchService.Search], + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct], + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + will treat requests using "default_branch" to the actual branch + id set as default. + + For example, if ``projects/*/locations/*/catalogs/*/branches/1`` + is set as default, setting + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/default_branch`` + is equivalent to setting + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/1``. + + Using multiple branches can be useful when developers would like + to have a staging branch to test and verify for future usage. + When it becomes ready, developers switch on the staging branch + using this API while keeping using + ``projects/*/locations/*/catalogs/*/branches/default_branch`` as + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to route the traffic to this staging branch. + + CAUTION: If you have live predict/search traffic, switching the + default branch could potentially cause outages if the ID space + of the new branch is very different from the old one. + + More specifically: + + - PredictionService will only return product IDs from branch + {newBranch}. + - SearchService will only return product IDs from branch + {newBranch} (if branch is not explicitly set). + - 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. + + Args: + request (Union[google.cloud.retail_v2.types.SetDefaultBranchRequest, dict]): + The request object. Request message to set a specified + branch as new default_branch. + catalog (str): + Full resource name of the catalog, such as + ``projects/*/locations/global/catalogs/default_catalog``. + + This corresponds to the ``catalog`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([catalog]) + 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 catalog_service.SetDefaultBranchRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.SetDefaultBranchRequest): + request = catalog_service.SetDefaultBranchRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.set_default_branch] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def get_default_branch(self, + request: Union[catalog_service.GetDefaultBranchRequest, dict] = None, + *, + catalog: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog_service.GetDefaultBranchResponse: + r"""Get which branch is currently default branch set by + [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. + + Args: + request (Union[google.cloud.retail_v2.types.GetDefaultBranchRequest, dict]): + The request object. Request message to show which branch + is currently the default branch. + catalog (str): + The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog``. + + This corresponds to the ``catalog`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.GetDefaultBranchResponse: + Response message of + [CatalogService.GetDefaultBranch][google.cloud.retail.v2.CatalogService.GetDefaultBranch]. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([catalog]) + 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 catalog_service.GetDefaultBranchRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.GetDefaultBranchRequest): + request = catalog_service.GetDefaultBranchRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_default_branch] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ( + "CatalogServiceClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/pagers.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/pagers.py new file mode 100644 index 00000000..2ca8b45a --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/pagers.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import Any, AsyncIterator, Awaitable, Callable, Sequence, Tuple, Optional, Iterator + +from google.cloud.retail_v2.types import catalog +from google.cloud.retail_v2.types import catalog_service + + +class ListCatalogsPager: + """A pager for iterating through ``list_catalogs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2.types.ListCatalogsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``catalogs`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListCatalogs`` requests and continue to iterate + through the ``catalogs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2.types.ListCatalogsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., catalog_service.ListCatalogsResponse], + request: catalog_service.ListCatalogsRequest, + response: catalog_service.ListCatalogsResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.retail_v2.types.ListCatalogsRequest): + The initial request object. + response (google.cloud.retail_v2.types.ListCatalogsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = catalog_service.ListCatalogsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[catalog_service.ListCatalogsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[catalog.Catalog]: + for page in self.pages: + yield from page.catalogs + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListCatalogsAsyncPager: + """A pager for iterating through ``list_catalogs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2.types.ListCatalogsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``catalogs`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListCatalogs`` requests and continue to iterate + through the ``catalogs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2.types.ListCatalogsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., Awaitable[catalog_service.ListCatalogsResponse]], + request: catalog_service.ListCatalogsRequest, + response: catalog_service.ListCatalogsResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.retail_v2.types.ListCatalogsRequest): + The initial request object. + response (google.cloud.retail_v2.types.ListCatalogsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = catalog_service.ListCatalogsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[catalog_service.ListCatalogsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + def __aiter__(self) -> AsyncIterator[catalog.Catalog]: + async def async_generator(): + async for page in self.pages: + for response in page.catalogs: + yield response + + return async_generator() + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/__init__.py new file mode 100644 index 00000000..7d55f7e9 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/__init__.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from typing import Dict, Type + +from .base import CatalogServiceTransport +from .grpc import CatalogServiceGrpcTransport +from .grpc_asyncio import CatalogServiceGrpcAsyncIOTransport + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[CatalogServiceTransport]] +_transport_registry['grpc'] = CatalogServiceGrpcTransport +_transport_registry['grpc_asyncio'] = CatalogServiceGrpcAsyncIOTransport + +__all__ = ( + 'CatalogServiceTransport', + 'CatalogServiceGrpcTransport', + 'CatalogServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/base.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/base.py new file mode 100644 index 00000000..3853f48b --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/base.py @@ -0,0 +1,189 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.retail_v2.types import catalog as gcr_catalog +from google.cloud.retail_v2.types import catalog_service +from google.protobuf import empty_pb2 # type: ignore + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + 'google-cloud-retail', + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CatalogServiceTransport(abc.ABC): + """Abstract transport class for CatalogService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.googleapis.com' + def __init__( + self, *, + host: str = DEFAULT_HOST, + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ':' not in host: + host += ':443' + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs("'credentials_file' and 'credentials' are mutually exclusive") + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id + ) + elif credentials is None: + credentials, _ = google.auth.default(**scopes_kwargs, quota_project_id=quota_project_id) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if always_use_jwt_access and isinstance(credentials, service_account.Credentials) and hasattr(service_account.Credentials, "with_always_use_jwt_access"): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + 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.update_catalog: gapic_v1.method.wrap_method( + 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.get_default_branch: gapic_v1.method.wrap_method( + 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! + """ + raise NotImplementedError() + + @property + def list_catalogs(self) -> Callable[ + [catalog_service.ListCatalogsRequest], + Union[ + catalog_service.ListCatalogsResponse, + Awaitable[catalog_service.ListCatalogsResponse] + ]]: + raise NotImplementedError() + + @property + def update_catalog(self) -> Callable[ + [catalog_service.UpdateCatalogRequest], + Union[ + gcr_catalog.Catalog, + Awaitable[gcr_catalog.Catalog] + ]]: + raise NotImplementedError() + + @property + def set_default_branch(self) -> Callable[ + [catalog_service.SetDefaultBranchRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def get_default_branch(self) -> Callable[ + [catalog_service.GetDefaultBranchRequest], + Union[ + catalog_service.GetDefaultBranchResponse, + Awaitable[catalog_service.GetDefaultBranchResponse] + ]]: + raise NotImplementedError() + + +__all__ = ( + 'CatalogServiceTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc.py new file mode 100644 index 00000000..c0245324 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc.py @@ -0,0 +1,381 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.cloud.retail_v2.types import catalog as gcr_catalog +from google.cloud.retail_v2.types import catalog_service +from google.protobuf import empty_pb2 # type: ignore +from .base import CatalogServiceTransport, DEFAULT_CLIENT_INFO + + +class CatalogServiceGrpcTransport(CatalogServiceTransport): + """gRPC backend transport for CatalogService. + + Service for managing catalog configuration. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + _stubs: Dict[str, Callable] + + def __init__(self, *, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + credentials=self._credentials, + credentials_file=credentials_file, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel(cls, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def list_catalogs(self) -> Callable[ + [catalog_service.ListCatalogsRequest], + catalog_service.ListCatalogsResponse]: + r"""Return a callable for the list catalogs method over gRPC. + + Lists all the [Catalog][google.cloud.retail.v2.Catalog]s + associated with the project. + + Returns: + Callable[[~.ListCatalogsRequest], + ~.ListCatalogsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_catalogs' not in self._stubs: + self._stubs['list_catalogs'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/ListCatalogs', + request_serializer=catalog_service.ListCatalogsRequest.serialize, + response_deserializer=catalog_service.ListCatalogsResponse.deserialize, + ) + return self._stubs['list_catalogs'] + + @property + def update_catalog(self) -> Callable[ + [catalog_service.UpdateCatalogRequest], + gcr_catalog.Catalog]: + r"""Return a callable for the update catalog method over gRPC. + + Updates the [Catalog][google.cloud.retail.v2.Catalog]s. + + Returns: + Callable[[~.UpdateCatalogRequest], + ~.Catalog]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'update_catalog' not in self._stubs: + self._stubs['update_catalog'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/UpdateCatalog', + request_serializer=catalog_service.UpdateCatalogRequest.serialize, + response_deserializer=gcr_catalog.Catalog.deserialize, + ) + return self._stubs['update_catalog'] + + @property + def set_default_branch(self) -> Callable[ + [catalog_service.SetDefaultBranchRequest], + empty_pb2.Empty]: + r"""Return a callable for the set default branch method over gRPC. + + Set a specified branch id as default branch. API methods such as + [SearchService.Search][google.cloud.retail.v2.SearchService.Search], + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct], + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + will treat requests using "default_branch" to the actual branch + id set as default. + + For example, if ``projects/*/locations/*/catalogs/*/branches/1`` + is set as default, setting + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/default_branch`` + is equivalent to setting + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/1``. + + Using multiple branches can be useful when developers would like + to have a staging branch to test and verify for future usage. + When it becomes ready, developers switch on the staging branch + using this API while keeping using + ``projects/*/locations/*/catalogs/*/branches/default_branch`` as + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to route the traffic to this staging branch. + + CAUTION: If you have live predict/search traffic, switching the + default branch could potentially cause outages if the ID space + of the new branch is very different from the old one. + + More specifically: + + - PredictionService will only return product IDs from branch + {newBranch}. + - SearchService will only return product IDs from branch + {newBranch} (if branch is not explicitly set). + - 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]: + 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 'set_default_branch' not in self._stubs: + self._stubs['set_default_branch'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/SetDefaultBranch', + request_serializer=catalog_service.SetDefaultBranchRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['set_default_branch'] + + @property + def get_default_branch(self) -> Callable[ + [catalog_service.GetDefaultBranchRequest], + catalog_service.GetDefaultBranchResponse]: + r"""Return a callable for the get default branch method over gRPC. + + Get which branch is currently default branch set by + [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]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_default_branch' not in self._stubs: + self._stubs['get_default_branch'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/GetDefaultBranch', + request_serializer=catalog_service.GetDefaultBranchRequest.serialize, + response_deserializer=catalog_service.GetDefaultBranchResponse.deserialize, + ) + return self._stubs['get_default_branch'] + + def close(self): + self.grpc_channel.close() + +__all__ = ( + 'CatalogServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc_asyncio.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..96a62e1a --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc_asyncio.py @@ -0,0 +1,385 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.retail_v2.types import catalog as gcr_catalog +from google.cloud.retail_v2.types import catalog_service +from google.protobuf import empty_pb2 # type: ignore +from .base import CatalogServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import CatalogServiceGrpcTransport + + +class CatalogServiceGrpcAsyncIOTransport(CatalogServiceTransport): + """gRPC AsyncIO backend transport for CatalogService. + + Service for managing catalog configuration. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel(cls, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + def __init__(self, *, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: aio.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id=None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + credentials=self._credentials, + credentials_file=credentials_file, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def list_catalogs(self) -> Callable[ + [catalog_service.ListCatalogsRequest], + Awaitable[catalog_service.ListCatalogsResponse]]: + r"""Return a callable for the list catalogs method over gRPC. + + Lists all the [Catalog][google.cloud.retail.v2.Catalog]s + associated with the project. + + Returns: + Callable[[~.ListCatalogsRequest], + Awaitable[~.ListCatalogsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_catalogs' not in self._stubs: + self._stubs['list_catalogs'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/ListCatalogs', + request_serializer=catalog_service.ListCatalogsRequest.serialize, + response_deserializer=catalog_service.ListCatalogsResponse.deserialize, + ) + return self._stubs['list_catalogs'] + + @property + def update_catalog(self) -> Callable[ + [catalog_service.UpdateCatalogRequest], + Awaitable[gcr_catalog.Catalog]]: + r"""Return a callable for the update catalog method over gRPC. + + Updates the [Catalog][google.cloud.retail.v2.Catalog]s. + + Returns: + Callable[[~.UpdateCatalogRequest], + Awaitable[~.Catalog]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'update_catalog' not in self._stubs: + self._stubs['update_catalog'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/UpdateCatalog', + request_serializer=catalog_service.UpdateCatalogRequest.serialize, + response_deserializer=gcr_catalog.Catalog.deserialize, + ) + return self._stubs['update_catalog'] + + @property + def set_default_branch(self) -> Callable[ + [catalog_service.SetDefaultBranchRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the set default branch method over gRPC. + + Set a specified branch id as default branch. API methods such as + [SearchService.Search][google.cloud.retail.v2.SearchService.Search], + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct], + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + will treat requests using "default_branch" to the actual branch + id set as default. + + For example, if ``projects/*/locations/*/catalogs/*/branches/1`` + is set as default, setting + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/default_branch`` + is equivalent to setting + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/1``. + + Using multiple branches can be useful when developers would like + to have a staging branch to test and verify for future usage. + When it becomes ready, developers switch on the staging branch + using this API while keeping using + ``projects/*/locations/*/catalogs/*/branches/default_branch`` as + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to route the traffic to this staging branch. + + CAUTION: If you have live predict/search traffic, switching the + default branch could potentially cause outages if the ID space + of the new branch is very different from the old one. + + More specifically: + + - PredictionService will only return product IDs from branch + {newBranch}. + - SearchService will only return product IDs from branch + {newBranch} (if branch is not explicitly set). + - 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]]: + 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 'set_default_branch' not in self._stubs: + self._stubs['set_default_branch'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/SetDefaultBranch', + request_serializer=catalog_service.SetDefaultBranchRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['set_default_branch'] + + @property + def get_default_branch(self) -> Callable[ + [catalog_service.GetDefaultBranchRequest], + Awaitable[catalog_service.GetDefaultBranchResponse]]: + r"""Return a callable for the get default branch method over gRPC. + + Get which branch is currently default branch set by + [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]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_default_branch' not in self._stubs: + self._stubs['get_default_branch'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/GetDefaultBranch', + request_serializer=catalog_service.GetDefaultBranchRequest.serialize, + response_deserializer=catalog_service.GetDefaultBranchResponse.deserialize, + ) + return self._stubs['get_default_branch'] + + def close(self): + return self.grpc_channel.close() + + +__all__ = ( + 'CatalogServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/__init__.py new file mode 100644 index 00000000..dbedd175 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .client import CompletionServiceClient +from .async_client import CompletionServiceAsyncClient + +__all__ = ( + 'CompletionServiceClient', + 'CompletionServiceAsyncClient', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/async_client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/async_client.py new file mode 100644 index 00000000..51d1be06 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/async_client.py @@ -0,0 +1,346 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +import functools +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.retail_v2.types import completion_service +from google.cloud.retail_v2.types import import_config +from .transports.base import CompletionServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import CompletionServiceGrpcAsyncIOTransport +from .client import CompletionServiceClient + + +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. + """ + + _client: CompletionServiceClient + + DEFAULT_ENDPOINT = CompletionServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CompletionServiceClient.DEFAULT_MTLS_ENDPOINT + + catalog_path = staticmethod(CompletionServiceClient.catalog_path) + parse_catalog_path = staticmethod(CompletionServiceClient.parse_catalog_path) + common_billing_account_path = staticmethod(CompletionServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(CompletionServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(CompletionServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(CompletionServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(CompletionServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(CompletionServiceClient.parse_common_organization_path) + common_project_path = staticmethod(CompletionServiceClient.common_project_path) + parse_common_project_path = staticmethod(CompletionServiceClient.parse_common_project_path) + common_location_path = staticmethod(CompletionServiceClient.common_location_path) + parse_common_location_path = staticmethod(CompletionServiceClient.parse_common_location_path) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CompletionServiceAsyncClient: The constructed client. + """ + return CompletionServiceClient.from_service_account_info.__func__(CompletionServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CompletionServiceAsyncClient: The constructed client. + """ + return CompletionServiceClient.from_service_account_file.__func__(CompletionServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CompletionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CompletionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CompletionServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(CompletionServiceClient).get_transport_class, type(CompletionServiceClient)) + + def __init__(self, *, + credentials: ga_credentials.Credentials = None, + transport: Union[str, CompletionServiceTransport] = "grpc_asyncio", + client_options: ClientOptions = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the completion service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.CompletionServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CompletionServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def complete_query(self, + request: Union[completion_service.CompleteQueryRequest, dict] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + 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. + + Args: + request (Union[google.cloud.retail_v2.types.CompleteQueryRequest, dict]): + The request object. Auto-complete parameters. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.CompleteQueryResponse: + Response of the auto-complete query. + """ + # Create or coerce a protobuf request object. + request = completion_service.CompleteQueryRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.complete_query, + 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(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def import_completion_data(self, + request: Union[import_config.ImportCompletionDataRequest, dict] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + 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. + + Args: + request (Union[google.cloud.retail_v2.types.ImportCompletionDataRequest, dict]): + The request object. Request message for + ImportCompletionData methods. + 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.ImportCompletionDataResponse` Response of the + [ImportCompletionDataRequest][google.cloud.retail.v2.ImportCompletionDataRequest]. + If the long running operation is done, this message + is returned by the + google.longrunning.Operations.response field if the + operation is successful. + + """ + # Create or coerce a protobuf request object. + request = import_config.ImportCompletionDataRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.import_completion_data, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + import_config.ImportCompletionDataResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ( + "CompletionServiceAsyncClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/client.py new file mode 100644 index 00000000..65cb8884 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/client.py @@ -0,0 +1,544 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +import os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.retail_v2.types import completion_service +from google.cloud.retail_v2.types import import_config +from .transports.base import CompletionServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CompletionServiceGrpcTransport +from .transports.grpc_asyncio import CompletionServiceGrpcAsyncIOTransport + + +class CompletionServiceClientMeta(type): + """Metaclass for the CompletionService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + _transport_registry = OrderedDict() # type: Dict[str, Type[CompletionServiceTransport]] + _transport_registry["grpc"] = CompletionServiceGrpcTransport + _transport_registry["grpc_asyncio"] = CompletionServiceGrpcAsyncIOTransport + + def get_transport_class(cls, + label: str = None, + ) -> Type[CompletionServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class 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. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "retail.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CompletionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CompletionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CompletionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CompletionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str, ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str,str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str, ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder, ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str,str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str, ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization, ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str,str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str, ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project, ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str,str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str, ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format(project=project, location=location, ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str,str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError("Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError("Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`") + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CompletionServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the completion service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CompletionServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options) + + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError("client_options.api_key and credentials are mutually exclusive") + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CompletionServiceTransport): + # transport is a CompletionServiceTransport instance. + if credentials or client_options.credentials_file or api_key_value: + raise ValueError("When providing a transport instance, " + "provide its credentials directly.") + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + import google.auth._default # type: ignore + + if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"): + credentials = google.auth._default.get_api_key_credentials(api_key_value) + + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def complete_query(self, + request: Union[completion_service.CompleteQueryRequest, dict] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + 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. + + Args: + request (Union[google.cloud.retail_v2.types.CompleteQueryRequest, dict]): + The request object. Auto-complete parameters. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.CompleteQueryResponse: + Response of the auto-complete query. + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a completion_service.CompleteQueryRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, completion_service.CompleteQueryRequest): + request = completion_service.CompleteQueryRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.complete_query] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def import_completion_data(self, + request: Union[import_config.ImportCompletionDataRequest, dict] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + 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. + + Args: + request (Union[google.cloud.retail_v2.types.ImportCompletionDataRequest, dict]): + The request object. Request message for + ImportCompletionData methods. + 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.ImportCompletionDataResponse` Response of the + [ImportCompletionDataRequest][google.cloud.retail.v2.ImportCompletionDataRequest]. + If the long running operation is done, this message + is returned by the + google.longrunning.Operations.response field if the + operation is successful. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a import_config.ImportCompletionDataRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, import_config.ImportCompletionDataRequest): + request = import_config.ImportCompletionDataRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.import_completion_data] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + import_config.ImportCompletionDataResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ( + "CompletionServiceClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/__init__.py new file mode 100644 index 00000000..afb1afd2 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/__init__.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from typing import Dict, Type + +from .base import CompletionServiceTransport +from .grpc import CompletionServiceGrpcTransport +from .grpc_asyncio import CompletionServiceGrpcAsyncIOTransport + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[CompletionServiceTransport]] +_transport_registry['grpc'] = CompletionServiceGrpcTransport +_transport_registry['grpc_asyncio'] = CompletionServiceGrpcAsyncIOTransport + +__all__ = ( + 'CompletionServiceTransport', + 'CompletionServiceGrpcTransport', + 'CompletionServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/base.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/base.py new file mode 100644 index 00000000..5edbc6a1 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/base.py @@ -0,0 +1,167 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.retail_v2.types import completion_service +from google.cloud.retail_v2.types import import_config +from google.longrunning import operations_pb2 # type: ignore + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + 'google-cloud-retail', + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CompletionServiceTransport(abc.ABC): + """Abstract transport class for CompletionService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.googleapis.com' + def __init__( + self, *, + host: str = DEFAULT_HOST, + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ':' not in host: + host += ':443' + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs("'credentials_file' and 'credentials' are mutually exclusive") + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id + ) + elif credentials is None: + credentials, _ = google.auth.default(**scopes_kwargs, quota_project_id=quota_project_id) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if always_use_jwt_access and isinstance(credentials, service_account.Credentials) and hasattr(service_account.Credentials, "with_always_use_jwt_access"): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + 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.import_completion_data: gapic_v1.method.wrap_method( + self.import_completion_data, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def complete_query(self) -> Callable[ + [completion_service.CompleteQueryRequest], + Union[ + completion_service.CompleteQueryResponse, + Awaitable[completion_service.CompleteQueryResponse] + ]]: + raise NotImplementedError() + + @property + def import_completion_data(self) -> Callable[ + [import_config.ImportCompletionDataRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + +__all__ = ( + 'CompletionServiceTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc.py new file mode 100644 index 00000000..321cbca8 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc.py @@ -0,0 +1,318 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.cloud.retail_v2.types import completion_service +from google.cloud.retail_v2.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from .base import CompletionServiceTransport, DEFAULT_CLIENT_INFO + + +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. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + _stubs: Dict[str, Callable] + + def __init__(self, *, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + credentials=self._credentials, + credentials_file=credentials_file, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel(cls, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Sanity check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def complete_query(self) -> Callable[ + [completion_service.CompleteQueryRequest], + completion_service.CompleteQueryResponse]: + 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. + + Returns: + Callable[[~.CompleteQueryRequest], + ~.CompleteQueryResponse]: + 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 'complete_query' not in self._stubs: + self._stubs['complete_query'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CompletionService/CompleteQuery', + request_serializer=completion_service.CompleteQueryRequest.serialize, + response_deserializer=completion_service.CompleteQueryResponse.deserialize, + ) + return self._stubs['complete_query'] + + @property + def import_completion_data(self) -> Callable[ + [import_config.ImportCompletionDataRequest], + operations_pb2.Operation]: + 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. + + Returns: + Callable[[~.ImportCompletionDataRequest], + ~.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 'import_completion_data' not in self._stubs: + self._stubs['import_completion_data'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CompletionService/ImportCompletionData', + request_serializer=import_config.ImportCompletionDataRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_completion_data'] + + def close(self): + self.grpc_channel.close() + +__all__ = ( + 'CompletionServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc_asyncio.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..0731a483 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc_asyncio.py @@ -0,0 +1,322 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.retail_v2.types import completion_service +from google.cloud.retail_v2.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from .base import CompletionServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import CompletionServiceGrpcTransport + + +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. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel(cls, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + def __init__(self, *, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: aio.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id=None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + credentials=self._credentials, + credentials_file=credentials_file, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Sanity check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def complete_query(self) -> Callable[ + [completion_service.CompleteQueryRequest], + Awaitable[completion_service.CompleteQueryResponse]]: + 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. + + Returns: + Callable[[~.CompleteQueryRequest], + Awaitable[~.CompleteQueryResponse]]: + 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 'complete_query' not in self._stubs: + self._stubs['complete_query'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CompletionService/CompleteQuery', + request_serializer=completion_service.CompleteQueryRequest.serialize, + response_deserializer=completion_service.CompleteQueryResponse.deserialize, + ) + return self._stubs['complete_query'] + + @property + def import_completion_data(self) -> Callable[ + [import_config.ImportCompletionDataRequest], + Awaitable[operations_pb2.Operation]]: + 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. + + Returns: + Callable[[~.ImportCompletionDataRequest], + 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 'import_completion_data' not in self._stubs: + self._stubs['import_completion_data'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CompletionService/ImportCompletionData', + request_serializer=import_config.ImportCompletionDataRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_completion_data'] + + def close(self): + return self.grpc_channel.close() + + +__all__ = ( + 'CompletionServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/__init__.py new file mode 100644 index 00000000..13c5d11c --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .client import PredictionServiceClient +from .async_client import PredictionServiceAsyncClient + +__all__ = ( + 'PredictionServiceClient', + 'PredictionServiceAsyncClient', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/async_client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/async_client.py new file mode 100644 index 00000000..9593b0ea --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/async_client.py @@ -0,0 +1,255 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +import functools +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.cloud.retail_v2.types import prediction_service +from .transports.base import PredictionServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import PredictionServiceGrpcAsyncIOTransport +from .client import PredictionServiceClient + + +class PredictionServiceAsyncClient: + """Service for making recommendation prediction.""" + + _client: PredictionServiceClient + + DEFAULT_ENDPOINT = PredictionServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = PredictionServiceClient.DEFAULT_MTLS_ENDPOINT + + product_path = staticmethod(PredictionServiceClient.product_path) + parse_product_path = staticmethod(PredictionServiceClient.parse_product_path) + common_billing_account_path = staticmethod(PredictionServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(PredictionServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(PredictionServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(PredictionServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(PredictionServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(PredictionServiceClient.parse_common_organization_path) + common_project_path = staticmethod(PredictionServiceClient.common_project_path) + parse_common_project_path = staticmethod(PredictionServiceClient.parse_common_project_path) + common_location_path = staticmethod(PredictionServiceClient.common_location_path) + parse_common_location_path = staticmethod(PredictionServiceClient.parse_common_location_path) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + PredictionServiceAsyncClient: The constructed client. + """ + return PredictionServiceClient.from_service_account_info.__func__(PredictionServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + PredictionServiceAsyncClient: The constructed client. + """ + return PredictionServiceClient.from_service_account_file.__func__(PredictionServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return PredictionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> PredictionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + PredictionServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(PredictionServiceClient).get_transport_class, type(PredictionServiceClient)) + + def __init__(self, *, + credentials: ga_credentials.Credentials = None, + transport: Union[str, PredictionServiceTransport] = "grpc_asyncio", + client_options: ClientOptions = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the prediction service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.PredictionServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = PredictionServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def predict(self, + request: Union[prediction_service.PredictRequest, dict] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> prediction_service.PredictResponse: + r"""Makes a recommendation prediction. + + Args: + request (Union[google.cloud.retail_v2.types.PredictRequest, dict]): + The request object. Request message for Predict method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.PredictResponse: + Response message for predict method. + """ + # Create or coerce a protobuf request object. + request = prediction_service.PredictRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.predict, + 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(( + ("placement", request.placement), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ( + "PredictionServiceAsyncClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/client.py new file mode 100644 index 00000000..b0217ea8 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/client.py @@ -0,0 +1,452 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +import os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.cloud.retail_v2.types import prediction_service +from .transports.base import PredictionServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import PredictionServiceGrpcTransport +from .transports.grpc_asyncio import PredictionServiceGrpcAsyncIOTransport + + +class PredictionServiceClientMeta(type): + """Metaclass for the PredictionService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + _transport_registry = OrderedDict() # type: Dict[str, Type[PredictionServiceTransport]] + _transport_registry["grpc"] = PredictionServiceGrpcTransport + _transport_registry["grpc_asyncio"] = PredictionServiceGrpcAsyncIOTransport + + def get_transport_class(cls, + label: str = None, + ) -> Type[PredictionServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class PredictionServiceClient(metaclass=PredictionServiceClientMeta): + """Service for making recommendation prediction.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "retail.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + PredictionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + PredictionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> PredictionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + PredictionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def product_path(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(project=project, location=location, catalog=catalog, branch=branch, product=product, ) + + @staticmethod + def parse_product_path(path: str) -> Dict[str,str]: + """Parses a product path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)/products/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str, ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str,str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str, ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder, ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str,str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str, ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization, ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str,str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str, ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project, ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str,str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str, ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format(project=project, location=location, ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str,str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError("Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError("Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`") + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, PredictionServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the prediction service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, PredictionServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options) + + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError("client_options.api_key and credentials are mutually exclusive") + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, PredictionServiceTransport): + # transport is a PredictionServiceTransport instance. + if credentials or client_options.credentials_file or api_key_value: + raise ValueError("When providing a transport instance, " + "provide its credentials directly.") + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + import google.auth._default # type: ignore + + if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"): + credentials = google.auth._default.get_api_key_credentials(api_key_value) + + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def predict(self, + request: Union[prediction_service.PredictRequest, dict] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> prediction_service.PredictResponse: + r"""Makes a recommendation prediction. + + Args: + request (Union[google.cloud.retail_v2.types.PredictRequest, dict]): + The request object. Request message for Predict method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.PredictResponse: + Response message for predict method. + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a prediction_service.PredictRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, prediction_service.PredictRequest): + request = prediction_service.PredictRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.predict] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("placement", request.placement), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ( + "PredictionServiceClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/__init__.py new file mode 100644 index 00000000..d747de2c --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/__init__.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from typing import Dict, Type + +from .base import PredictionServiceTransport +from .grpc import PredictionServiceGrpcTransport +from .grpc_asyncio import PredictionServiceGrpcAsyncIOTransport + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[PredictionServiceTransport]] +_transport_registry['grpc'] = PredictionServiceGrpcTransport +_transport_registry['grpc_asyncio'] = PredictionServiceGrpcAsyncIOTransport + +__all__ = ( + 'PredictionServiceTransport', + 'PredictionServiceGrpcTransport', + 'PredictionServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/base.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/base.py new file mode 100644 index 00000000..b0debf1c --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/base.py @@ -0,0 +1,145 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.retail_v2.types import prediction_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + 'google-cloud-retail', + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class PredictionServiceTransport(abc.ABC): + """Abstract transport class for PredictionService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.googleapis.com' + def __init__( + self, *, + host: str = DEFAULT_HOST, + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ':' not in host: + host += ':443' + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs("'credentials_file' and 'credentials' are mutually exclusive") + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id + ) + elif credentials is None: + credentials, _ = google.auth.default(**scopes_kwargs, quota_project_id=quota_project_id) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if always_use_jwt_access and isinstance(credentials, service_account.Credentials) and hasattr(service_account.Credentials, "with_always_use_jwt_access"): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + 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, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def predict(self) -> Callable[ + [prediction_service.PredictRequest], + Union[ + prediction_service.PredictResponse, + Awaitable[prediction_service.PredictResponse] + ]]: + raise NotImplementedError() + + +__all__ = ( + 'PredictionServiceTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc.py new file mode 100644 index 00000000..90ae3faa --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc.py @@ -0,0 +1,254 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.cloud.retail_v2.types import prediction_service +from .base import PredictionServiceTransport, DEFAULT_CLIENT_INFO + + +class PredictionServiceGrpcTransport(PredictionServiceTransport): + """gRPC backend transport for PredictionService. + + Service for making recommendation prediction. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + _stubs: Dict[str, Callable] + + def __init__(self, *, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + credentials=self._credentials, + credentials_file=credentials_file, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel(cls, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def predict(self) -> Callable[ + [prediction_service.PredictRequest], + prediction_service.PredictResponse]: + r"""Return a callable for the predict method over gRPC. + + Makes a recommendation prediction. + + Returns: + Callable[[~.PredictRequest], + ~.PredictResponse]: + 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 'predict' not in self._stubs: + self._stubs['predict'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.PredictionService/Predict', + request_serializer=prediction_service.PredictRequest.serialize, + response_deserializer=prediction_service.PredictResponse.deserialize, + ) + return self._stubs['predict'] + + def close(self): + self.grpc_channel.close() + +__all__ = ( + 'PredictionServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc_asyncio.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..5aafb5f8 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc_asyncio.py @@ -0,0 +1,258 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.retail_v2.types import prediction_service +from .base import PredictionServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import PredictionServiceGrpcTransport + + +class PredictionServiceGrpcAsyncIOTransport(PredictionServiceTransport): + """gRPC AsyncIO backend transport for PredictionService. + + Service for making recommendation prediction. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel(cls, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + def __init__(self, *, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: aio.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id=None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + credentials=self._credentials, + credentials_file=credentials_file, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def predict(self) -> Callable[ + [prediction_service.PredictRequest], + Awaitable[prediction_service.PredictResponse]]: + r"""Return a callable for the predict method over gRPC. + + Makes a recommendation prediction. + + Returns: + Callable[[~.PredictRequest], + Awaitable[~.PredictResponse]]: + 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 'predict' not in self._stubs: + self._stubs['predict'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.PredictionService/Predict', + request_serializer=prediction_service.PredictRequest.serialize, + response_deserializer=prediction_service.PredictResponse.deserialize, + ) + return self._stubs['predict'] + + def close(self): + return self.grpc_channel.close() + + +__all__ = ( + 'PredictionServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/__init__.py new file mode 100644 index 00000000..0cea8c87 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .client import ProductServiceClient +from .async_client import ProductServiceAsyncClient + +__all__ = ( + 'ProductServiceClient', + 'ProductServiceAsyncClient', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/async_client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/async_client.py new file mode 100644 index 00000000..e1cc0b41 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/async_client.py @@ -0,0 +1,1190 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +import functools +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.retail_v2.services.product_service import pagers +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 product as gcr_product +from google.cloud.retail_v2.types import product_service +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 +from .transports.base import ProductServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ProductServiceGrpcAsyncIOTransport +from .client import ProductServiceClient + + +class ProductServiceAsyncClient: + """Service for ingesting [Product][google.cloud.retail.v2.Product] + information of the customer's website. + """ + + _client: ProductServiceClient + + DEFAULT_ENDPOINT = ProductServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ProductServiceClient.DEFAULT_MTLS_ENDPOINT + + branch_path = staticmethod(ProductServiceClient.branch_path) + parse_branch_path = staticmethod(ProductServiceClient.parse_branch_path) + product_path = staticmethod(ProductServiceClient.product_path) + parse_product_path = staticmethod(ProductServiceClient.parse_product_path) + common_billing_account_path = staticmethod(ProductServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ProductServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ProductServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(ProductServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(ProductServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(ProductServiceClient.parse_common_organization_path) + common_project_path = staticmethod(ProductServiceClient.common_project_path) + parse_common_project_path = staticmethod(ProductServiceClient.parse_common_project_path) + common_location_path = staticmethod(ProductServiceClient.common_location_path) + parse_common_location_path = staticmethod(ProductServiceClient.parse_common_location_path) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductServiceAsyncClient: The constructed client. + """ + return ProductServiceClient.from_service_account_info.__func__(ProductServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductServiceAsyncClient: The constructed client. + """ + return ProductServiceClient.from_service_account_file.__func__(ProductServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ProductServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ProductServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ProductServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(ProductServiceClient).get_transport_class, type(ProductServiceClient)) + + def __init__(self, *, + credentials: ga_credentials.Credentials = None, + transport: Union[str, ProductServiceTransport] = "grpc_asyncio", + client_options: ClientOptions = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the product service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.ProductServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ProductServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def create_product(self, + request: Union[product_service.CreateProductRequest, dict] = None, + *, + parent: str = None, + product: gcr_product.Product = None, + product_id: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_product.Product: + r"""Creates a [Product][google.cloud.retail.v2.Product]. + + Args: + request (Union[google.cloud.retail_v2.types.CreateProductRequest, dict]): + The request object. Request message for + [CreateProduct][] method. + parent (:class:`str`): + Required. The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (:class:`google.cloud.retail_v2.types.Product`): + Required. The [Product][google.cloud.retail.v2.Product] + to create. + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_id (:class:`str`): + Required. The ID to use for the + [Product][google.cloud.retail.v2.Product], which will + become the final component of the + [Product.name][google.cloud.retail.v2.Product.name]. + + If the caller does not have permission to create the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + This field must be unique among all + [Product][google.cloud.retail.v2.Product]s with the same + [parent][google.cloud.retail.v2.CreateProductRequest.parent]. + Otherwise, an ALREADY_EXISTS error is returned. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + This corresponds to the ``product_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, product, product_id]) + 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.CreateProductRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if product is not None: + request.product = product + if product_id is not None: + request.product_id = product_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_product, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_product(self, + request: Union[product_service.GetProductRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product.Product: + r"""Gets a [Product][google.cloud.retail.v2.Product]. + + Args: + request (Union[google.cloud.retail_v2.types.GetProductRequest, dict]): + The request object. Request message for [GetProduct][] + method. + name (: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. + + If the requested + [Product][google.cloud.retail.v2.Product] does not + exist, a NOT_FOUND error is returned. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_service.GetProductRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_product, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_products(self, + request: Union[product_service.ListProductsRequest, dict] = None, + *, + parent: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListProductsAsyncPager: + r"""Gets a list of [Product][google.cloud.retail.v2.Product]s. + + Args: + request (Union[google.cloud.retail_v2.types.ListProductsRequest, dict]): + The request object. Request message for + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + method. + parent (:class:`str`): + Required. The parent branch resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/0``. + Use ``default_branch`` as the branch ID, to list + products under the default branch. + + If the caller does not have permission to list + [Product][google.cloud.retail.v2.Product]s under this + branch, regardless of whether or not this branch exists, + a PERMISSION_DENIED error is returned. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.services.product_service.pagers.ListProductsAsyncPager: + Response message for + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_service.ListProductsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_products, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListProductsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_product(self, + request: Union[product_service.UpdateProductRequest, dict] = None, + *, + product: gcr_product.Product = None, + update_mask: field_mask_pb2.FieldMask = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_product.Product: + r"""Updates a [Product][google.cloud.retail.v2.Product]. + + Args: + request (Union[google.cloud.retail_v2.types.UpdateProductRequest, dict]): + The request object. Request message for + [UpdateProduct][] method. + product (:class:`google.cloud.retail_v2.types.Product`): + Required. The product to update/create. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Product][google.cloud.retail.v2.Product] to + update does not exist and + [allow_missing][google.cloud.retail.v2.UpdateProductRequest.allow_missing] + is not set, a NOT_FOUND error is returned. + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Indicates which fields in the provided + [Product][google.cloud.retail.v2.Product] to update. The + immutable and output only fields are NOT supported. If + not set, all supported fields (the fields that are + neither immutable nor output only) are updated. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([product, update_mask]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_service.UpdateProductRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if product is not None: + request.product = product + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_product, + 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.name", request.product.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_product(self, + request: Union[product_service.DeleteProductRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes a [Product][google.cloud.retail.v2.Product]. + + Args: + request (Union[google.cloud.retail_v2.types.DeleteProductRequest, dict]): + The request object. Request message for + [DeleteProduct][] method. + name (: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 delete the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Product][google.cloud.retail.v2.Product] to + delete does not exist, a NOT_FOUND error is returned. + + The [Product][google.cloud.retail.v2.Product] to delete + can neither be a + [Product.Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION] + [Product][google.cloud.retail.v2.Product] member nor a + [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product] with more than + one + [variants][google.cloud.retail.v2.Product.Type.VARIANT]. + Otherwise, an INVALID_ARGUMENT error is returned. + + All inventory information for the named + [Product][google.cloud.retail.v2.Product] will be + deleted. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_service.DeleteProductRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_product, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def import_products(self, + request: Union[import_config.ImportProductsRequest, dict] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Bulk import of multiple + [Product][google.cloud.retail.v2.Product]s. + + Request processing may be synchronous. No partial updating is + supported. Non-existing items are created. + + Note that it is possible for a subset of the + [Product][google.cloud.retail.v2.Product]s to be successfully + updated. + + Args: + request (Union[google.cloud.retail_v2.types.ImportProductsRequest, dict]): + The request object. Request message for Import methods. + 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.ImportProductsResponse` Response of the + [ImportProductsRequest][google.cloud.retail.v2.ImportProductsRequest]. + If the long running operation is done, then this + message is returned by the + google.longrunning.Operations.response field if the + operation was successful. + + """ + # Create or coerce a protobuf request object. + request = import_config.ImportProductsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.import_products, + default_retry=retries.Retry( +initial=0.1,maximum=300.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=300.0, + ), + default_timeout=300.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + import_config.ImportProductsResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + async def set_inventory(self, + request: Union[product_service.SetInventoryRequest, dict] = None, + *, + inventory: product.Product = None, + set_mask: field_mask_pb2.FieldMask = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Updates inventory information for a + [Product][google.cloud.retail.v2.Product] 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 fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, updates are not + immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + When inventory is updated with + [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct], + the specified inventory field value(s) will overwrite any + existing value(s) while ignoring the last update time for this + field. Furthermore, the last update time for the specified + inventory fields will be overwritten to the time of the + [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + or + [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + request. + + If no inventory fields are set in + [CreateProductRequest.product][google.cloud.retail.v2.CreateProductRequest.product], + then any pre-existing inventory information for this product + will be used. + + If no inventory fields are set in + [UpdateProductRequest.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], + [AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces], + and + [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. + + Args: + request (Union[google.cloud.retail_v2.types.SetInventoryRequest, dict]): + The request object. Request message for [SetInventory][] + method. + inventory (:class:`google.cloud.retail_v2.types.Product`): + Required. The inventory information to update. The + allowable fields to update are: + + - [Product.price_info][google.cloud.retail.v2.Product.price_info] + - [Product.availability][google.cloud.retail.v2.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] + The updated inventory fields must be specified in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask]. + + If [SetInventoryRequest.inventory.name][] is empty or + invalid, an INVALID_ARGUMENT error is returned. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2.Product] named in + [Product.name][google.cloud.retail.v2.Product.name], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the [Product][google.cloud.retail.v2.Product] to + update does not have existing inventory information, the + provided inventory information will be inserted. + + If the [Product][google.cloud.retail.v2.Product] to + update has existing inventory information, the provided + inventory information will be merged while respecting + the last update time for each inventory field, using the + provided or default value for + [SetInventoryRequest.set_time][google.cloud.retail.v2.SetInventoryRequest.set_time]. + + The last update time is recorded for the following + inventory fields: + + - [Product.price_info][google.cloud.retail.v2.Product.price_info] + - [Product.availability][google.cloud.retail.v2.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] + + If a full overwrite of inventory information while + ignoring timestamps is needed, [UpdateProduct][] should + be invoked instead. + + This corresponds to the ``inventory`` field + on the ``request`` instance; if ``request`` is provided, this + 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. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned and the entire update + will be ignored. + + This corresponds to the ``set_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.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.SetInventoryResponse` Response of the SetInventoryRequest. Currently empty because + there is no meaningful response populated from the + [SetInventory][] method. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([inventory, set_mask]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_service.SetInventoryRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if inventory is not None: + request.inventory = inventory + if set_mask is not None: + request.set_mask = set_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.set_inventory, + 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(( + ("inventory.name", request.inventory.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + product_service.SetInventoryResponse, + metadata_type=product_service.SetInventoryMetadata, + ) + + # Done; return the response. + return response + + async def add_fulfillment_places(self, + request: Union[product_service.AddFulfillmentPlacesRequest, dict] = None, + *, + product: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Incrementally adds place IDs to + [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the added place IDs + 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]. + + 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. + + Args: + request (Union[google.cloud.retail_v2.types.AddFulfillmentPlacesRequest, dict]): + The request object. Request message for + [AddFulfillmentPlaces][] 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.AddFulfillmentPlacesResponse` Response of the AddFulfillmentPlacesRequest. Currently empty because + there is no meaningful response populated from the + [AddFulfillmentPlaces][] method. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + 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.AddFulfillmentPlacesRequest(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_fulfillment_places, + 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.AddFulfillmentPlacesResponse, + metadata_type=product_service.AddFulfillmentPlacesMetadata, + ) + + # Done; return the response. + return response + + async def remove_fulfillment_places(self, + request: Union[product_service.RemoveFulfillmentPlacesRequest, dict] = None, + *, + product: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Incrementally removes place IDs from a + [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the removed place IDs + 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]. + + 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. + + Args: + request (Union[google.cloud.retail_v2.types.RemoveFulfillmentPlacesRequest, dict]): + The request object. Request message for + [RemoveFulfillmentPlaces][] 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.RemoveFulfillmentPlacesResponse` Response of the RemoveFulfillmentPlacesRequest. Currently empty because there + is no meaningful response populated from the + [RemoveFulfillmentPlaces][] method. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + 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.RemoveFulfillmentPlacesRequest(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_fulfillment_places, + 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.RemoveFulfillmentPlacesResponse, + metadata_type=product_service.RemoveFulfillmentPlacesMetadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ( + "ProductServiceAsyncClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/client.py new file mode 100644 index 00000000..a6908eed --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/client.py @@ -0,0 +1,1389 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +import os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.retail_v2.services.product_service import pagers +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 product as gcr_product +from google.cloud.retail_v2.types import product_service +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 +from .transports.base import ProductServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ProductServiceGrpcTransport +from .transports.grpc_asyncio import ProductServiceGrpcAsyncIOTransport + + +class ProductServiceClientMeta(type): + """Metaclass for the ProductService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + _transport_registry = OrderedDict() # type: Dict[str, Type[ProductServiceTransport]] + _transport_registry["grpc"] = ProductServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ProductServiceGrpcAsyncIOTransport + + def get_transport_class(cls, + label: str = None, + ) -> Type[ProductServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ProductServiceClient(metaclass=ProductServiceClientMeta): + """Service for ingesting [Product][google.cloud.retail.v2.Product] + information of the customer's website. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "retail.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ProductServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ProductServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + 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, ) + + @staticmethod + def parse_branch_path(path: str) -> Dict[str,str]: + """Parses a branch path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def product_path(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(project=project, location=location, catalog=catalog, branch=branch, product=product, ) + + @staticmethod + def parse_product_path(path: str) -> Dict[str,str]: + """Parses a product path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)/products/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str, ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str,str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str, ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder, ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str,str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str, ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization, ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str,str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str, ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project, ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str,str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str, ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format(project=project, location=location, ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str,str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError("Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError("Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`") + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ProductServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the product service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ProductServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options) + + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError("client_options.api_key and credentials are mutually exclusive") + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ProductServiceTransport): + # transport is a ProductServiceTransport instance. + if credentials or client_options.credentials_file or api_key_value: + raise ValueError("When providing a transport instance, " + "provide its credentials directly.") + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + import google.auth._default # type: ignore + + if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"): + credentials = google.auth._default.get_api_key_credentials(api_key_value) + + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def create_product(self, + request: Union[product_service.CreateProductRequest, dict] = None, + *, + parent: str = None, + product: gcr_product.Product = None, + product_id: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_product.Product: + r"""Creates a [Product][google.cloud.retail.v2.Product]. + + Args: + request (Union[google.cloud.retail_v2.types.CreateProductRequest, dict]): + The request object. Request message for + [CreateProduct][] method. + parent (str): + Required. The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (google.cloud.retail_v2.types.Product): + Required. The [Product][google.cloud.retail.v2.Product] + to create. + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_id (str): + Required. The ID to use for the + [Product][google.cloud.retail.v2.Product], which will + become the final component of the + [Product.name][google.cloud.retail.v2.Product.name]. + + If the caller does not have permission to create the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + This field must be unique among all + [Product][google.cloud.retail.v2.Product]s with the same + [parent][google.cloud.retail.v2.CreateProductRequest.parent]. + Otherwise, an ALREADY_EXISTS error is returned. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + This corresponds to the ``product_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, product, product_id]) + 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.CreateProductRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.CreateProductRequest): + request = product_service.CreateProductRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if product is not None: + request.product = product + if product_id is not None: + request.product_id = product_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_product] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_product(self, + request: Union[product_service.GetProductRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product.Product: + r"""Gets a [Product][google.cloud.retail.v2.Product]. + + Args: + request (Union[google.cloud.retail_v2.types.GetProductRequest, dict]): + The request object. Request message for [GetProduct][] + method. + name (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. + + If the requested + [Product][google.cloud.retail.v2.Product] does not + exist, a NOT_FOUND error is returned. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_service.GetProductRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.GetProductRequest): + request = product_service.GetProductRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_product] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_products(self, + request: Union[product_service.ListProductsRequest, dict] = None, + *, + parent: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListProductsPager: + r"""Gets a list of [Product][google.cloud.retail.v2.Product]s. + + Args: + request (Union[google.cloud.retail_v2.types.ListProductsRequest, dict]): + The request object. Request message for + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + method. + parent (str): + Required. The parent branch resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/0``. + Use ``default_branch`` as the branch ID, to list + products under the default branch. + + If the caller does not have permission to list + [Product][google.cloud.retail.v2.Product]s under this + branch, regardless of whether or not this branch exists, + a PERMISSION_DENIED error is returned. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.services.product_service.pagers.ListProductsPager: + Response message for + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_service.ListProductsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.ListProductsRequest): + request = product_service.ListProductsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_products] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListProductsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_product(self, + request: Union[product_service.UpdateProductRequest, dict] = None, + *, + product: gcr_product.Product = None, + update_mask: field_mask_pb2.FieldMask = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_product.Product: + r"""Updates a [Product][google.cloud.retail.v2.Product]. + + Args: + request (Union[google.cloud.retail_v2.types.UpdateProductRequest, dict]): + The request object. Request message for + [UpdateProduct][] method. + product (google.cloud.retail_v2.types.Product): + Required. The product to update/create. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Product][google.cloud.retail.v2.Product] to + update does not exist and + [allow_missing][google.cloud.retail.v2.UpdateProductRequest.allow_missing] + is not set, a NOT_FOUND error is returned. + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [Product][google.cloud.retail.v2.Product] to update. The + immutable and output only fields are NOT supported. If + not set, all supported fields (the fields that are + neither immutable nor output only) are updated. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([product, update_mask]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_service.UpdateProductRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.UpdateProductRequest): + request = product_service.UpdateProductRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if product is not None: + request.product = product + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_product] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product.name", request.product.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_product(self, + request: Union[product_service.DeleteProductRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes a [Product][google.cloud.retail.v2.Product]. + + Args: + request (Union[google.cloud.retail_v2.types.DeleteProductRequest, dict]): + The request object. Request message for + [DeleteProduct][] method. + name (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 delete the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Product][google.cloud.retail.v2.Product] to + delete does not exist, a NOT_FOUND error is returned. + + The [Product][google.cloud.retail.v2.Product] to delete + can neither be a + [Product.Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION] + [Product][google.cloud.retail.v2.Product] member nor a + [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product] with more than + one + [variants][google.cloud.retail.v2.Product.Type.VARIANT]. + Otherwise, an INVALID_ARGUMENT error is returned. + + All inventory information for the named + [Product][google.cloud.retail.v2.Product] will be + deleted. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_service.DeleteProductRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.DeleteProductRequest): + request = product_service.DeleteProductRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_product] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def import_products(self, + request: Union[import_config.ImportProductsRequest, dict] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Bulk import of multiple + [Product][google.cloud.retail.v2.Product]s. + + Request processing may be synchronous. No partial updating is + supported. Non-existing items are created. + + Note that it is possible for a subset of the + [Product][google.cloud.retail.v2.Product]s to be successfully + updated. + + Args: + request (Union[google.cloud.retail_v2.types.ImportProductsRequest, dict]): + The request object. Request message for Import methods. + 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.ImportProductsResponse` Response of the + [ImportProductsRequest][google.cloud.retail.v2.ImportProductsRequest]. + If the long running operation is done, then this + message is returned by the + google.longrunning.Operations.response field if the + operation was successful. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a import_config.ImportProductsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, import_config.ImportProductsRequest): + request = import_config.ImportProductsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.import_products] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + import_config.ImportProductsResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + def set_inventory(self, + request: Union[product_service.SetInventoryRequest, dict] = None, + *, + inventory: product.Product = None, + set_mask: field_mask_pb2.FieldMask = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Updates inventory information for a + [Product][google.cloud.retail.v2.Product] 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 fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, updates are not + immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + When inventory is updated with + [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct], + the specified inventory field value(s) will overwrite any + existing value(s) while ignoring the last update time for this + field. Furthermore, the last update time for the specified + inventory fields will be overwritten to the time of the + [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + or + [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + request. + + If no inventory fields are set in + [CreateProductRequest.product][google.cloud.retail.v2.CreateProductRequest.product], + then any pre-existing inventory information for this product + will be used. + + If no inventory fields are set in + [UpdateProductRequest.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], + [AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces], + and + [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. + + Args: + request (Union[google.cloud.retail_v2.types.SetInventoryRequest, dict]): + The request object. Request message for [SetInventory][] + method. + inventory (google.cloud.retail_v2.types.Product): + Required. The inventory information to update. The + allowable fields to update are: + + - [Product.price_info][google.cloud.retail.v2.Product.price_info] + - [Product.availability][google.cloud.retail.v2.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] + The updated inventory fields must be specified in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask]. + + If [SetInventoryRequest.inventory.name][] is empty or + invalid, an INVALID_ARGUMENT error is returned. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2.Product] named in + [Product.name][google.cloud.retail.v2.Product.name], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the [Product][google.cloud.retail.v2.Product] to + update does not have existing inventory information, the + provided inventory information will be inserted. + + If the [Product][google.cloud.retail.v2.Product] to + update has existing inventory information, the provided + inventory information will be merged while respecting + the last update time for each inventory field, using the + provided or default value for + [SetInventoryRequest.set_time][google.cloud.retail.v2.SetInventoryRequest.set_time]. + + The last update time is recorded for the following + inventory fields: + + - [Product.price_info][google.cloud.retail.v2.Product.price_info] + - [Product.availability][google.cloud.retail.v2.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] + + If a full overwrite of inventory information while + ignoring timestamps is needed, [UpdateProduct][] should + be invoked instead. + + This corresponds to the ``inventory`` field + on the ``request`` instance; if ``request`` is provided, this + 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. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned and the entire update + will be ignored. + + This corresponds to the ``set_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.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.SetInventoryResponse` Response of the SetInventoryRequest. Currently empty because + there is no meaningful response populated from the + [SetInventory][] method. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([inventory, set_mask]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_service.SetInventoryRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.SetInventoryRequest): + request = product_service.SetInventoryRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if inventory is not None: + request.inventory = inventory + if set_mask is not None: + request.set_mask = set_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.set_inventory] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("inventory.name", request.inventory.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + product_service.SetInventoryResponse, + metadata_type=product_service.SetInventoryMetadata, + ) + + # Done; return the response. + return response + + def add_fulfillment_places(self, + request: Union[product_service.AddFulfillmentPlacesRequest, dict] = None, + *, + product: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Incrementally adds place IDs to + [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the added place IDs + 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]. + + 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. + + Args: + request (Union[google.cloud.retail_v2.types.AddFulfillmentPlacesRequest, dict]): + The request object. Request message for + [AddFulfillmentPlaces][] 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.AddFulfillmentPlacesResponse` Response of the AddFulfillmentPlacesRequest. Currently empty because + there is no meaningful response populated from the + [AddFulfillmentPlaces][] method. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + 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.AddFulfillmentPlacesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.AddFulfillmentPlacesRequest): + request = product_service.AddFulfillmentPlacesRequest(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_fulfillment_places] + + # 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.AddFulfillmentPlacesResponse, + metadata_type=product_service.AddFulfillmentPlacesMetadata, + ) + + # Done; return the response. + return response + + def remove_fulfillment_places(self, + request: Union[product_service.RemoveFulfillmentPlacesRequest, dict] = None, + *, + product: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Incrementally removes place IDs from a + [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the removed place IDs + 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]. + + 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. + + Args: + request (Union[google.cloud.retail_v2.types.RemoveFulfillmentPlacesRequest, dict]): + The request object. Request message for + [RemoveFulfillmentPlaces][] 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.RemoveFulfillmentPlacesResponse` Response of the RemoveFulfillmentPlacesRequest. Currently empty because there + is no meaningful response populated from the + [RemoveFulfillmentPlaces][] method. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + 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.RemoveFulfillmentPlacesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.RemoveFulfillmentPlacesRequest): + request = product_service.RemoveFulfillmentPlacesRequest(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_fulfillment_places] + + # 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.RemoveFulfillmentPlacesResponse, + metadata_type=product_service.RemoveFulfillmentPlacesMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ( + "ProductServiceClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/pagers.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/pagers.py new file mode 100644 index 00000000..d1addca2 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/pagers.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import Any, AsyncIterator, Awaitable, Callable, Sequence, Tuple, Optional, Iterator + +from google.cloud.retail_v2.types import product +from google.cloud.retail_v2.types import product_service + + +class ListProductsPager: + """A pager for iterating through ``list_products`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2.types.ListProductsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``products`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListProducts`` requests and continue to iterate + through the ``products`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2.types.ListProductsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., product_service.ListProductsResponse], + request: product_service.ListProductsRequest, + response: product_service.ListProductsResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.retail_v2.types.ListProductsRequest): + The initial request object. + response (google.cloud.retail_v2.types.ListProductsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_service.ListProductsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[product_service.ListProductsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[product.Product]: + for page in self.pages: + yield from page.products + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListProductsAsyncPager: + """A pager for iterating through ``list_products`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2.types.ListProductsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``products`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListProducts`` requests and continue to iterate + through the ``products`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2.types.ListProductsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., Awaitable[product_service.ListProductsResponse]], + request: product_service.ListProductsRequest, + response: product_service.ListProductsResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.retail_v2.types.ListProductsRequest): + The initial request object. + response (google.cloud.retail_v2.types.ListProductsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_service.ListProductsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[product_service.ListProductsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + def __aiter__(self) -> AsyncIterator[product.Product]: + async def async_generator(): + async for page in self.pages: + for response in page.products: + yield response + + return async_generator() + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/__init__.py new file mode 100644 index 00000000..2f27ad58 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/__init__.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from typing import Dict, Type + +from .base import ProductServiceTransport +from .grpc import ProductServiceGrpcTransport +from .grpc_asyncio import ProductServiceGrpcAsyncIOTransport + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ProductServiceTransport]] +_transport_registry['grpc'] = ProductServiceGrpcTransport +_transport_registry['grpc_asyncio'] = ProductServiceGrpcAsyncIOTransport + +__all__ = ( + 'ProductServiceTransport', + 'ProductServiceGrpcTransport', + 'ProductServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/base.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/base.py new file mode 100644 index 00000000..7e475a6c --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/base.py @@ -0,0 +1,275 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.retail_v2.types import import_config +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.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + 'google-cloud-retail', + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class ProductServiceTransport(abc.ABC): + """Abstract transport class for ProductService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.googleapis.com' + def __init__( + self, *, + host: str = DEFAULT_HOST, + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ':' not in host: + host += ':443' + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs("'credentials_file' and 'credentials' are mutually exclusive") + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id + ) + elif credentials is None: + credentials, _ = google.auth.default(**scopes_kwargs, quota_project_id=quota_project_id) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if always_use_jwt_access and isinstance(credentials, service_account.Credentials) and hasattr(service_account.Credentials, "with_always_use_jwt_access"): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + 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.get_product: gapic_v1.method.wrap_method( + 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.update_product: gapic_v1.method.wrap_method( + 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.import_products: gapic_v1.method.wrap_method( + self.import_products, + default_retry=retries.Retry( +initial=0.1,maximum=300.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=300.0, + ), + default_timeout=300.0, + client_info=client_info, + ), + self.set_inventory: gapic_v1.method.wrap_method( + self.set_inventory, + default_timeout=None, + client_info=client_info, + ), + self.add_fulfillment_places: gapic_v1.method.wrap_method( + self.add_fulfillment_places, + default_timeout=None, + client_info=client_info, + ), + self.remove_fulfillment_places: gapic_v1.method.wrap_method( + self.remove_fulfillment_places, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def create_product(self) -> Callable[ + [product_service.CreateProductRequest], + Union[ + gcr_product.Product, + Awaitable[gcr_product.Product] + ]]: + raise NotImplementedError() + + @property + def get_product(self) -> Callable[ + [product_service.GetProductRequest], + Union[ + product.Product, + Awaitable[product.Product] + ]]: + raise NotImplementedError() + + @property + def list_products(self) -> Callable[ + [product_service.ListProductsRequest], + Union[ + product_service.ListProductsResponse, + Awaitable[product_service.ListProductsResponse] + ]]: + raise NotImplementedError() + + @property + def update_product(self) -> Callable[ + [product_service.UpdateProductRequest], + Union[ + gcr_product.Product, + Awaitable[gcr_product.Product] + ]]: + raise NotImplementedError() + + @property + def delete_product(self) -> Callable[ + [product_service.DeleteProductRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def import_products(self) -> Callable[ + [import_config.ImportProductsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def set_inventory(self) -> Callable[ + [product_service.SetInventoryRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def add_fulfillment_places(self) -> Callable[ + [product_service.AddFulfillmentPlacesRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def remove_fulfillment_places(self) -> Callable[ + [product_service.RemoveFulfillmentPlacesRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + +__all__ = ( + 'ProductServiceTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc.py new file mode 100644 index 00000000..14db14bd --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc.py @@ -0,0 +1,574 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.cloud.retail_v2.types import import_config +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.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ProductServiceTransport, DEFAULT_CLIENT_INFO + + +class ProductServiceGrpcTransport(ProductServiceTransport): + """gRPC backend transport for ProductService. + + Service for ingesting [Product][google.cloud.retail.v2.Product] + information of the customer's website. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + _stubs: Dict[str, Callable] + + def __init__(self, *, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + credentials=self._credentials, + credentials_file=credentials_file, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel(cls, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Sanity check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def create_product(self) -> Callable[ + [product_service.CreateProductRequest], + gcr_product.Product]: + r"""Return a callable for the create product method over gRPC. + + Creates a [Product][google.cloud.retail.v2.Product]. + + Returns: + Callable[[~.CreateProductRequest], + ~.Product]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'create_product' not in self._stubs: + self._stubs['create_product'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/CreateProduct', + request_serializer=product_service.CreateProductRequest.serialize, + response_deserializer=gcr_product.Product.deserialize, + ) + return self._stubs['create_product'] + + @property + def get_product(self) -> Callable[ + [product_service.GetProductRequest], + product.Product]: + r"""Return a callable for the get product method over gRPC. + + Gets a [Product][google.cloud.retail.v2.Product]. + + Returns: + Callable[[~.GetProductRequest], + ~.Product]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_product' not in self._stubs: + self._stubs['get_product'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/GetProduct', + request_serializer=product_service.GetProductRequest.serialize, + response_deserializer=product.Product.deserialize, + ) + return self._stubs['get_product'] + + @property + def list_products(self) -> Callable[ + [product_service.ListProductsRequest], + product_service.ListProductsResponse]: + r"""Return a callable for the list products method over gRPC. + + Gets a list of [Product][google.cloud.retail.v2.Product]s. + + Returns: + Callable[[~.ListProductsRequest], + ~.ListProductsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_products' not in self._stubs: + self._stubs['list_products'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/ListProducts', + request_serializer=product_service.ListProductsRequest.serialize, + response_deserializer=product_service.ListProductsResponse.deserialize, + ) + return self._stubs['list_products'] + + @property + def update_product(self) -> Callable[ + [product_service.UpdateProductRequest], + gcr_product.Product]: + r"""Return a callable for the update product method over gRPC. + + Updates a [Product][google.cloud.retail.v2.Product]. + + Returns: + Callable[[~.UpdateProductRequest], + ~.Product]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'update_product' not in self._stubs: + self._stubs['update_product'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/UpdateProduct', + request_serializer=product_service.UpdateProductRequest.serialize, + response_deserializer=gcr_product.Product.deserialize, + ) + return self._stubs['update_product'] + + @property + def delete_product(self) -> Callable[ + [product_service.DeleteProductRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete product method over gRPC. + + Deletes a [Product][google.cloud.retail.v2.Product]. + + Returns: + Callable[[~.DeleteProductRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'delete_product' not in self._stubs: + self._stubs['delete_product'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/DeleteProduct', + request_serializer=product_service.DeleteProductRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_product'] + + @property + def import_products(self) -> Callable[ + [import_config.ImportProductsRequest], + operations_pb2.Operation]: + r"""Return a callable for the import products method over gRPC. + + Bulk import of multiple + [Product][google.cloud.retail.v2.Product]s. + + Request processing may be synchronous. No partial updating is + supported. Non-existing items are created. + + Note that it is possible for a subset of the + [Product][google.cloud.retail.v2.Product]s to be successfully + updated. + + Returns: + Callable[[~.ImportProductsRequest], + ~.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 'import_products' not in self._stubs: + self._stubs['import_products'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/ImportProducts', + request_serializer=import_config.ImportProductsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_products'] + + @property + def set_inventory(self) -> Callable[ + [product_service.SetInventoryRequest], + operations_pb2.Operation]: + r"""Return a callable for the set inventory method over gRPC. + + Updates inventory information for a + [Product][google.cloud.retail.v2.Product] 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 fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, updates are not + immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + When inventory is updated with + [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct], + the specified inventory field value(s) will overwrite any + existing value(s) while ignoring the last update time for this + field. Furthermore, the last update time for the specified + inventory fields will be overwritten to the time of the + [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + or + [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + request. + + If no inventory fields are set in + [CreateProductRequest.product][google.cloud.retail.v2.CreateProductRequest.product], + then any pre-existing inventory information for this product + will be used. + + If no inventory fields are set in + [UpdateProductRequest.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], + [AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces], + and + [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. + + Returns: + Callable[[~.SetInventoryRequest], + ~.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 'set_inventory' not in self._stubs: + self._stubs['set_inventory'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/SetInventory', + request_serializer=product_service.SetInventoryRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['set_inventory'] + + @property + def add_fulfillment_places(self) -> Callable[ + [product_service.AddFulfillmentPlacesRequest], + operations_pb2.Operation]: + r"""Return a callable for the add fulfillment places method over gRPC. + + Incrementally adds place IDs to + [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the added place IDs + 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]. + + 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[[~.AddFulfillmentPlacesRequest], + ~.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_fulfillment_places' not in self._stubs: + self._stubs['add_fulfillment_places'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/AddFulfillmentPlaces', + request_serializer=product_service.AddFulfillmentPlacesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['add_fulfillment_places'] + + @property + def remove_fulfillment_places(self) -> Callable[ + [product_service.RemoveFulfillmentPlacesRequest], + operations_pb2.Operation]: + r"""Return a callable for the remove fulfillment places method over gRPC. + + Incrementally removes place IDs from a + [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the removed place IDs + 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]. + + 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[[~.RemoveFulfillmentPlacesRequest], + ~.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_fulfillment_places' not in self._stubs: + self._stubs['remove_fulfillment_places'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/RemoveFulfillmentPlaces', + request_serializer=product_service.RemoveFulfillmentPlacesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['remove_fulfillment_places'] + + def close(self): + self.grpc_channel.close() + +__all__ = ( + 'ProductServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc_asyncio.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..811e1ff4 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc_asyncio.py @@ -0,0 +1,578 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.retail_v2.types import import_config +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.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ProductServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import ProductServiceGrpcTransport + + +class ProductServiceGrpcAsyncIOTransport(ProductServiceTransport): + """gRPC AsyncIO backend transport for ProductService. + + Service for ingesting [Product][google.cloud.retail.v2.Product] + information of the customer's website. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel(cls, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + def __init__(self, *, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: aio.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id=None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + credentials=self._credentials, + credentials_file=credentials_file, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Sanity check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def create_product(self) -> Callable[ + [product_service.CreateProductRequest], + Awaitable[gcr_product.Product]]: + r"""Return a callable for the create product method over gRPC. + + Creates a [Product][google.cloud.retail.v2.Product]. + + Returns: + Callable[[~.CreateProductRequest], + Awaitable[~.Product]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'create_product' not in self._stubs: + self._stubs['create_product'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/CreateProduct', + request_serializer=product_service.CreateProductRequest.serialize, + response_deserializer=gcr_product.Product.deserialize, + ) + return self._stubs['create_product'] + + @property + def get_product(self) -> Callable[ + [product_service.GetProductRequest], + Awaitable[product.Product]]: + r"""Return a callable for the get product method over gRPC. + + Gets a [Product][google.cloud.retail.v2.Product]. + + Returns: + Callable[[~.GetProductRequest], + Awaitable[~.Product]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_product' not in self._stubs: + self._stubs['get_product'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/GetProduct', + request_serializer=product_service.GetProductRequest.serialize, + response_deserializer=product.Product.deserialize, + ) + return self._stubs['get_product'] + + @property + def list_products(self) -> Callable[ + [product_service.ListProductsRequest], + Awaitable[product_service.ListProductsResponse]]: + r"""Return a callable for the list products method over gRPC. + + Gets a list of [Product][google.cloud.retail.v2.Product]s. + + Returns: + Callable[[~.ListProductsRequest], + Awaitable[~.ListProductsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_products' not in self._stubs: + self._stubs['list_products'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/ListProducts', + request_serializer=product_service.ListProductsRequest.serialize, + response_deserializer=product_service.ListProductsResponse.deserialize, + ) + return self._stubs['list_products'] + + @property + def update_product(self) -> Callable[ + [product_service.UpdateProductRequest], + Awaitable[gcr_product.Product]]: + r"""Return a callable for the update product method over gRPC. + + Updates a [Product][google.cloud.retail.v2.Product]. + + Returns: + Callable[[~.UpdateProductRequest], + Awaitable[~.Product]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'update_product' not in self._stubs: + self._stubs['update_product'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/UpdateProduct', + request_serializer=product_service.UpdateProductRequest.serialize, + response_deserializer=gcr_product.Product.deserialize, + ) + return self._stubs['update_product'] + + @property + def delete_product(self) -> Callable[ + [product_service.DeleteProductRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete product method over gRPC. + + Deletes a [Product][google.cloud.retail.v2.Product]. + + Returns: + Callable[[~.DeleteProductRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'delete_product' not in self._stubs: + self._stubs['delete_product'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/DeleteProduct', + request_serializer=product_service.DeleteProductRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_product'] + + @property + def import_products(self) -> Callable[ + [import_config.ImportProductsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the import products method over gRPC. + + Bulk import of multiple + [Product][google.cloud.retail.v2.Product]s. + + Request processing may be synchronous. No partial updating is + supported. Non-existing items are created. + + Note that it is possible for a subset of the + [Product][google.cloud.retail.v2.Product]s to be successfully + updated. + + Returns: + Callable[[~.ImportProductsRequest], + 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 'import_products' not in self._stubs: + self._stubs['import_products'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/ImportProducts', + request_serializer=import_config.ImportProductsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_products'] + + @property + def set_inventory(self) -> Callable[ + [product_service.SetInventoryRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the set inventory method over gRPC. + + Updates inventory information for a + [Product][google.cloud.retail.v2.Product] 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 fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, updates are not + immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + When inventory is updated with + [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct], + the specified inventory field value(s) will overwrite any + existing value(s) while ignoring the last update time for this + field. Furthermore, the last update time for the specified + inventory fields will be overwritten to the time of the + [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + or + [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + request. + + If no inventory fields are set in + [CreateProductRequest.product][google.cloud.retail.v2.CreateProductRequest.product], + then any pre-existing inventory information for this product + will be used. + + If no inventory fields are set in + [UpdateProductRequest.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], + [AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces], + and + [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. + + Returns: + Callable[[~.SetInventoryRequest], + 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 'set_inventory' not in self._stubs: + self._stubs['set_inventory'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/SetInventory', + request_serializer=product_service.SetInventoryRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['set_inventory'] + + @property + def add_fulfillment_places(self) -> Callable[ + [product_service.AddFulfillmentPlacesRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the add fulfillment places method over gRPC. + + Incrementally adds place IDs to + [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the added place IDs + 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]. + + 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[[~.AddFulfillmentPlacesRequest], + 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_fulfillment_places' not in self._stubs: + self._stubs['add_fulfillment_places'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/AddFulfillmentPlaces', + request_serializer=product_service.AddFulfillmentPlacesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['add_fulfillment_places'] + + @property + def remove_fulfillment_places(self) -> Callable[ + [product_service.RemoveFulfillmentPlacesRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the remove fulfillment places method over gRPC. + + Incrementally removes place IDs from a + [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the removed place IDs + 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]. + + 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[[~.RemoveFulfillmentPlacesRequest], + 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_fulfillment_places' not in self._stubs: + self._stubs['remove_fulfillment_places'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/RemoveFulfillmentPlaces', + request_serializer=product_service.RemoveFulfillmentPlacesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['remove_fulfillment_places'] + + def close(self): + return self.grpc_channel.close() + + +__all__ = ( + 'ProductServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/__init__.py new file mode 100644 index 00000000..2fa43cc2 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .client import SearchServiceClient +from .async_client import SearchServiceAsyncClient + +__all__ = ( + 'SearchServiceClient', + 'SearchServiceAsyncClient', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/async_client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/async_client.py new file mode 100644 index 00000000..3169b7da --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/async_client.py @@ -0,0 +1,286 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +import functools +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.cloud.retail_v2.services.search_service import pagers +from google.cloud.retail_v2.types import search_service +from .transports.base import SearchServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import SearchServiceGrpcAsyncIOTransport +from .client import SearchServiceClient + + +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. + """ + + _client: SearchServiceClient + + DEFAULT_ENDPOINT = SearchServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = SearchServiceClient.DEFAULT_MTLS_ENDPOINT + + branch_path = staticmethod(SearchServiceClient.branch_path) + parse_branch_path = staticmethod(SearchServiceClient.parse_branch_path) + product_path = staticmethod(SearchServiceClient.product_path) + parse_product_path = staticmethod(SearchServiceClient.parse_product_path) + common_billing_account_path = staticmethod(SearchServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(SearchServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(SearchServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(SearchServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(SearchServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(SearchServiceClient.parse_common_organization_path) + common_project_path = staticmethod(SearchServiceClient.common_project_path) + parse_common_project_path = staticmethod(SearchServiceClient.parse_common_project_path) + common_location_path = staticmethod(SearchServiceClient.common_location_path) + parse_common_location_path = staticmethod(SearchServiceClient.parse_common_location_path) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SearchServiceAsyncClient: The constructed client. + """ + return SearchServiceClient.from_service_account_info.__func__(SearchServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SearchServiceAsyncClient: The constructed client. + """ + return SearchServiceClient.from_service_account_file.__func__(SearchServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return SearchServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> SearchServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SearchServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(SearchServiceClient).get_transport_class, type(SearchServiceClient)) + + def __init__(self, *, + credentials: ga_credentials.Credentials = None, + transport: Union[str, SearchServiceTransport] = "grpc_asyncio", + client_options: ClientOptions = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the search service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.SearchServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = SearchServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def search(self, + request: Union[search_service.SearchRequest, dict] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + 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. + + Args: + request (Union[google.cloud.retail_v2.types.SearchRequest, dict]): + The request object. Request message for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.services.search_service.pagers.SearchAsyncPager: + Response message for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + request = search_service.SearchRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.search, + 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(( + ("placement", request.placement), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.SearchAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ( + "SearchServiceAsyncClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/client.py new file mode 100644 index 00000000..838fba23 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/client.py @@ -0,0 +1,492 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +import os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.cloud.retail_v2.services.search_service import pagers +from google.cloud.retail_v2.types import search_service +from .transports.base import SearchServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import SearchServiceGrpcTransport +from .transports.grpc_asyncio import SearchServiceGrpcAsyncIOTransport + + +class SearchServiceClientMeta(type): + """Metaclass for the SearchService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + _transport_registry = OrderedDict() # type: Dict[str, Type[SearchServiceTransport]] + _transport_registry["grpc"] = SearchServiceGrpcTransport + _transport_registry["grpc_asyncio"] = SearchServiceGrpcAsyncIOTransport + + def get_transport_class(cls, + label: str = None, + ) -> Type[SearchServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class 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. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "retail.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SearchServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SearchServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> SearchServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SearchServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + 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, ) + + @staticmethod + def parse_branch_path(path: str) -> Dict[str,str]: + """Parses a branch path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def product_path(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(project=project, location=location, catalog=catalog, branch=branch, product=product, ) + + @staticmethod + def parse_product_path(path: str) -> Dict[str,str]: + """Parses a product path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)/products/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str, ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str,str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str, ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder, ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str,str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str, ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization, ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str,str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str, ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project, ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str,str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str, ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format(project=project, location=location, ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str,str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError("Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError("Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`") + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, SearchServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the search service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, SearchServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options) + + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError("client_options.api_key and credentials are mutually exclusive") + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, SearchServiceTransport): + # transport is a SearchServiceTransport instance. + if credentials or client_options.credentials_file or api_key_value: + raise ValueError("When providing a transport instance, " + "provide its credentials directly.") + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + import google.auth._default # type: ignore + + if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"): + credentials = google.auth._default.get_api_key_credentials(api_key_value) + + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def search(self, + request: Union[search_service.SearchRequest, dict] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + 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. + + Args: + request (Union[google.cloud.retail_v2.types.SearchRequest, dict]): + The request object. Request message for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.services.search_service.pagers.SearchPager: + Response message for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a search_service.SearchRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, search_service.SearchRequest): + request = search_service.SearchRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.search] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("placement", request.placement), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.SearchPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ( + "SearchServiceClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/pagers.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/pagers.py new file mode 100644 index 00000000..bd901167 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/pagers.py @@ -0,0 +1,139 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import Any, AsyncIterator, Awaitable, Callable, Sequence, Tuple, Optional, Iterator + +from google.cloud.retail_v2.types import search_service + + +class SearchPager: + """A pager for iterating through ``search`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2.types.SearchResponse` object, and + provides an ``__iter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``Search`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2.types.SearchResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., search_service.SearchResponse], + request: search_service.SearchRequest, + response: search_service.SearchResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.retail_v2.types.SearchRequest): + The initial request object. + response (google.cloud.retail_v2.types.SearchResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = search_service.SearchRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[search_service.SearchResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[search_service.SearchResponse.SearchResult]: + for page in self.pages: + yield from page.results + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class SearchAsyncPager: + """A pager for iterating through ``search`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2.types.SearchResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``Search`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2.types.SearchResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., Awaitable[search_service.SearchResponse]], + request: search_service.SearchRequest, + response: search_service.SearchResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.retail_v2.types.SearchRequest): + The initial request object. + response (google.cloud.retail_v2.types.SearchResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = search_service.SearchRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[search_service.SearchResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + def __aiter__(self) -> AsyncIterator[search_service.SearchResponse.SearchResult]: + async def async_generator(): + async for page in self.pages: + for response in page.results: + yield response + + return async_generator() + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/__init__.py new file mode 100644 index 00000000..d7acf5fa --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/__init__.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from typing import Dict, Type + +from .base import SearchServiceTransport +from .grpc import SearchServiceGrpcTransport +from .grpc_asyncio import SearchServiceGrpcAsyncIOTransport + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[SearchServiceTransport]] +_transport_registry['grpc'] = SearchServiceGrpcTransport +_transport_registry['grpc_asyncio'] = SearchServiceGrpcAsyncIOTransport + +__all__ = ( + 'SearchServiceTransport', + 'SearchServiceGrpcTransport', + 'SearchServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/base.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/base.py new file mode 100644 index 00000000..03235dd3 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/base.py @@ -0,0 +1,145 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.retail_v2.types import search_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + 'google-cloud-retail', + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class SearchServiceTransport(abc.ABC): + """Abstract transport class for SearchService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.googleapis.com' + def __init__( + self, *, + host: str = DEFAULT_HOST, + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ':' not in host: + host += ':443' + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs("'credentials_file' and 'credentials' are mutually exclusive") + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id + ) + elif credentials is None: + credentials, _ = google.auth.default(**scopes_kwargs, quota_project_id=quota_project_id) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if always_use_jwt_access and isinstance(credentials, service_account.Credentials) and hasattr(service_account.Credentials, "with_always_use_jwt_access"): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + 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, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def search(self) -> Callable[ + [search_service.SearchRequest], + Union[ + search_service.SearchResponse, + Awaitable[search_service.SearchResponse] + ]]: + raise NotImplementedError() + + +__all__ = ( + 'SearchServiceTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc.py new file mode 100644 index 00000000..5b082d93 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc.py @@ -0,0 +1,264 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.cloud.retail_v2.types import search_service +from .base import SearchServiceTransport, DEFAULT_CLIENT_INFO + + +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. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + _stubs: Dict[str, Callable] + + def __init__(self, *, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + credentials=self._credentials, + credentials_file=credentials_file, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel(cls, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def search(self) -> Callable[ + [search_service.SearchRequest], + search_service.SearchResponse]: + 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. + + Returns: + Callable[[~.SearchRequest], + ~.SearchResponse]: + 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 'search' not in self._stubs: + self._stubs['search'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.SearchService/Search', + request_serializer=search_service.SearchRequest.serialize, + response_deserializer=search_service.SearchResponse.deserialize, + ) + return self._stubs['search'] + + def close(self): + self.grpc_channel.close() + +__all__ = ( + 'SearchServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc_asyncio.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..ee3c956c --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc_asyncio.py @@ -0,0 +1,268 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.retail_v2.types import search_service +from .base import SearchServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import SearchServiceGrpcTransport + + +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. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel(cls, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + def __init__(self, *, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: aio.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id=None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + credentials=self._credentials, + credentials_file=credentials_file, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def search(self) -> Callable[ + [search_service.SearchRequest], + Awaitable[search_service.SearchResponse]]: + 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. + + Returns: + Callable[[~.SearchRequest], + Awaitable[~.SearchResponse]]: + 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 'search' not in self._stubs: + self._stubs['search'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.SearchService/Search', + request_serializer=search_service.SearchRequest.serialize, + response_deserializer=search_service.SearchResponse.deserialize, + ) + return self._stubs['search'] + + def close(self): + return self.grpc_channel.close() + + +__all__ = ( + 'SearchServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/__init__.py new file mode 100644 index 00000000..808f8208 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .client import UserEventServiceClient +from .async_client import UserEventServiceAsyncClient + +__all__ = ( + 'UserEventServiceClient', + 'UserEventServiceAsyncClient', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/async_client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/async_client.py new file mode 100644 index 00000000..bff9a954 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/async_client.py @@ -0,0 +1,610 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +import functools +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api import httpbody_pb2 # type: ignore +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import import_config +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 +from google.protobuf import any_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import UserEventServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import UserEventServiceGrpcAsyncIOTransport +from .client import UserEventServiceClient + + +class UserEventServiceAsyncClient: + """Service for ingesting end user actions on the customer + website. + """ + + _client: UserEventServiceClient + + DEFAULT_ENDPOINT = UserEventServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = UserEventServiceClient.DEFAULT_MTLS_ENDPOINT + + catalog_path = staticmethod(UserEventServiceClient.catalog_path) + parse_catalog_path = staticmethod(UserEventServiceClient.parse_catalog_path) + product_path = staticmethod(UserEventServiceClient.product_path) + parse_product_path = staticmethod(UserEventServiceClient.parse_product_path) + common_billing_account_path = staticmethod(UserEventServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(UserEventServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(UserEventServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(UserEventServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(UserEventServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(UserEventServiceClient.parse_common_organization_path) + common_project_path = staticmethod(UserEventServiceClient.common_project_path) + parse_common_project_path = staticmethod(UserEventServiceClient.parse_common_project_path) + common_location_path = staticmethod(UserEventServiceClient.common_location_path) + parse_common_location_path = staticmethod(UserEventServiceClient.parse_common_location_path) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + UserEventServiceAsyncClient: The constructed client. + """ + return UserEventServiceClient.from_service_account_info.__func__(UserEventServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + UserEventServiceAsyncClient: The constructed client. + """ + return UserEventServiceClient.from_service_account_file.__func__(UserEventServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return UserEventServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> UserEventServiceTransport: + """Returns the transport used by the client instance. + + Returns: + UserEventServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(UserEventServiceClient).get_transport_class, type(UserEventServiceClient)) + + def __init__(self, *, + credentials: ga_credentials.Credentials = None, + transport: Union[str, UserEventServiceTransport] = "grpc_asyncio", + client_options: ClientOptions = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the user event service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.UserEventServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = UserEventServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def write_user_event(self, + request: Union[user_event_service.WriteUserEventRequest, dict] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> user_event.UserEvent: + r"""Writes a single user event. + + Args: + request (Union[google.cloud.retail_v2.types.WriteUserEventRequest, dict]): + The request object. Request message for WriteUserEvent + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.UserEvent: + UserEvent captures all metadata + information Retail API needs to know + about how end users interact with + customers' website. + + """ + # Create or coerce a protobuf request object. + request = user_event_service.WriteUserEventRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.write_user_event, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def collect_user_event(self, + request: Union[user_event_service.CollectUserEventRequest, dict] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> httpbody_pb2.HttpBody: + r"""Writes a single user event from the browser. This + uses a GET request to due to browser restriction of + POST-ing to a 3rd party domain. + This method is used only by the Retail API JavaScript + pixel and Google Tag Manager. Users should not call this + method directly. + + Args: + request (Union[google.cloud.retail_v2.types.CollectUserEventRequest, dict]): + The request object. Request message for CollectUserEvent + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api.httpbody_pb2.HttpBody: + Message that represents an arbitrary HTTP body. It should only be used for + payload formats that can't be represented as JSON, + such as raw binary or an HTML page. + + This message can be used both in streaming and + non-streaming API methods in the request as well as + the response. + + It can be used as a top-level request field, which is + convenient if one wants to extract parameters from + either the URL or HTTP template into the request + fields and also want access to the raw HTTP body. + + Example: + + message GetResourceRequest { + // A unique request id. string request_id = 1; + + // The raw HTTP body is bound to this field. + google.api.HttpBody http_body = 2; + + } + + service ResourceService { + rpc GetResource(GetResourceRequest) + returns (google.api.HttpBody); + + rpc UpdateResource(google.api.HttpBody) + returns (google.protobuf.Empty); + + } + + Example with streaming methods: + + service CaldavService { + rpc GetCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + + rpc UpdateCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + + } + + Use of this type only changes how the request and + response bodies are handled, all other features will + continue to work unchanged. + + """ + # Create or coerce a protobuf request object. + request = user_event_service.CollectUserEventRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.collect_user_event, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def purge_user_events(self, + request: Union[purge_config.PurgeUserEventsRequest, dict] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Deletes permanently all user events specified by the + filter provided. Depending on the number of events + specified by the filter, this operation could take hours + or days to complete. To test a filter, use the list + command first. + + Args: + request (Union[google.cloud.retail_v2.types.PurgeUserEventsRequest, dict]): + The request object. Request message for PurgeUserEvents + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.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.PurgeUserEventsResponse` Response of the PurgeUserEventsRequest. If the long running operation is + successfully done, then this message is returned by + the google.longrunning.Operations.response field. + + """ + # Create or coerce a protobuf request object. + request = purge_config.PurgeUserEventsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.purge_user_events, + default_retry=retries.Retry( +initial=0.1,maximum=30.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=30.0, + ), + default_timeout=30.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + purge_config.PurgeUserEventsResponse, + metadata_type=purge_config.PurgeMetadata, + ) + + # Done; return the response. + return response + + async def import_user_events(self, + request: Union[import_config.ImportUserEventsRequest, dict] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Bulk import of User events. Request processing might + be synchronous. Events that already exist are skipped. + Use this method for backfilling historical user events. + Operation.response is of type ImportResponse. Note that + it is possible for a subset of the items to be + successfully inserted. Operation.metadata is of type + ImportMetadata. + + Args: + request (Union[google.cloud.retail_v2.types.ImportUserEventsRequest, dict]): + The request object. Request message for the + ImportUserEvents request. + 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.ImportUserEventsResponse` Response of the ImportUserEventsRequest. If the long running + operation was successful, then this message is + returned by the + google.longrunning.Operations.response field if the + operation was successful. + + """ + # Create or coerce a protobuf request object. + request = import_config.ImportUserEventsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.import_user_events, + default_retry=retries.Retry( +initial=0.1,maximum=300.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + import_config.ImportUserEventsResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + async def rejoin_user_events(self, + request: Union[user_event_service.RejoinUserEventsRequest, dict] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Triggers 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 + with latest version of product catalog. It can also be + used to correct events joined with wrong product + catalog. + + Args: + request (Union[google.cloud.retail_v2.types.RejoinUserEventsRequest, dict]): + The request object. Request message for RejoinUserEvents + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.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.RejoinUserEventsResponse` + Response message for RejoinUserEvents method. + + """ + # Create or coerce a protobuf request object. + request = user_event_service.RejoinUserEventsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.rejoin_user_events, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + user_event_service.RejoinUserEventsResponse, + metadata_type=user_event_service.RejoinUserEventsMetadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ( + "UserEventServiceAsyncClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/client.py new file mode 100644 index 00000000..efa6d0b3 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/client.py @@ -0,0 +1,806 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +import os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api import httpbody_pb2 # type: ignore +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import import_config +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 +from google.protobuf import any_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import UserEventServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import UserEventServiceGrpcTransport +from .transports.grpc_asyncio import UserEventServiceGrpcAsyncIOTransport + + +class UserEventServiceClientMeta(type): + """Metaclass for the UserEventService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + _transport_registry = OrderedDict() # type: Dict[str, Type[UserEventServiceTransport]] + _transport_registry["grpc"] = UserEventServiceGrpcTransport + _transport_registry["grpc_asyncio"] = UserEventServiceGrpcAsyncIOTransport + + def get_transport_class(cls, + label: str = None, + ) -> Type[UserEventServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class UserEventServiceClient(metaclass=UserEventServiceClientMeta): + """Service for ingesting end user actions on the customer + website. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "retail.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + UserEventServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + UserEventServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> UserEventServiceTransport: + """Returns the transport used by the client instance. + + Returns: + UserEventServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def product_path(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(project=project, location=location, catalog=catalog, branch=branch, product=product, ) + + @staticmethod + def parse_product_path(path: str) -> Dict[str,str]: + """Parses a product path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)/products/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str, ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str,str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str, ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder, ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str,str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str, ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization, ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str,str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str, ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project, ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str,str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str, ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format(project=project, location=location, ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str,str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError("Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError("Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`") + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, UserEventServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the user event service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, UserEventServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options) + + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError("client_options.api_key and credentials are mutually exclusive") + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, UserEventServiceTransport): + # transport is a UserEventServiceTransport instance. + if credentials or client_options.credentials_file or api_key_value: + raise ValueError("When providing a transport instance, " + "provide its credentials directly.") + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + import google.auth._default # type: ignore + + if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"): + credentials = google.auth._default.get_api_key_credentials(api_key_value) + + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def write_user_event(self, + request: Union[user_event_service.WriteUserEventRequest, dict] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> user_event.UserEvent: + r"""Writes a single user event. + + Args: + request (Union[google.cloud.retail_v2.types.WriteUserEventRequest, dict]): + The request object. Request message for WriteUserEvent + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.retail_v2.types.UserEvent: + UserEvent captures all metadata + information Retail API needs to know + about how end users interact with + customers' website. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a user_event_service.WriteUserEventRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, user_event_service.WriteUserEventRequest): + request = user_event_service.WriteUserEventRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.write_user_event] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def collect_user_event(self, + request: Union[user_event_service.CollectUserEventRequest, dict] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> httpbody_pb2.HttpBody: + r"""Writes a single user event from the browser. This + uses a GET request to due to browser restriction of + POST-ing to a 3rd party domain. + This method is used only by the Retail API JavaScript + pixel and Google Tag Manager. Users should not call this + method directly. + + Args: + request (Union[google.cloud.retail_v2.types.CollectUserEventRequest, dict]): + The request object. Request message for CollectUserEvent + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api.httpbody_pb2.HttpBody: + Message that represents an arbitrary HTTP body. It should only be used for + payload formats that can't be represented as JSON, + such as raw binary or an HTML page. + + This message can be used both in streaming and + non-streaming API methods in the request as well as + the response. + + It can be used as a top-level request field, which is + convenient if one wants to extract parameters from + either the URL or HTTP template into the request + fields and also want access to the raw HTTP body. + + Example: + + message GetResourceRequest { + // A unique request id. string request_id = 1; + + // The raw HTTP body is bound to this field. + google.api.HttpBody http_body = 2; + + } + + service ResourceService { + rpc GetResource(GetResourceRequest) + returns (google.api.HttpBody); + + rpc UpdateResource(google.api.HttpBody) + returns (google.protobuf.Empty); + + } + + Example with streaming methods: + + service CaldavService { + rpc GetCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + + rpc UpdateCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + + } + + Use of this type only changes how the request and + response bodies are handled, all other features will + continue to work unchanged. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a user_event_service.CollectUserEventRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, user_event_service.CollectUserEventRequest): + request = user_event_service.CollectUserEventRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.collect_user_event] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def purge_user_events(self, + request: Union[purge_config.PurgeUserEventsRequest, dict] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Deletes permanently all user events specified by the + filter provided. Depending on the number of events + specified by the filter, this operation could take hours + or days to complete. To test a filter, use the list + command first. + + Args: + request (Union[google.cloud.retail_v2.types.PurgeUserEventsRequest, dict]): + The request object. Request message for PurgeUserEvents + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.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.PurgeUserEventsResponse` Response of the PurgeUserEventsRequest. If the long running operation is + successfully done, then this message is returned by + the google.longrunning.Operations.response field. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a purge_config.PurgeUserEventsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, purge_config.PurgeUserEventsRequest): + request = purge_config.PurgeUserEventsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.purge_user_events] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + purge_config.PurgeUserEventsResponse, + metadata_type=purge_config.PurgeMetadata, + ) + + # Done; return the response. + return response + + def import_user_events(self, + request: Union[import_config.ImportUserEventsRequest, dict] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Bulk import of User events. Request processing might + be synchronous. Events that already exist are skipped. + Use this method for backfilling historical user events. + Operation.response is of type ImportResponse. Note that + it is possible for a subset of the items to be + successfully inserted. Operation.metadata is of type + ImportMetadata. + + Args: + request (Union[google.cloud.retail_v2.types.ImportUserEventsRequest, dict]): + The request object. Request message for the + ImportUserEvents request. + 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.ImportUserEventsResponse` Response of the ImportUserEventsRequest. If the long running + operation was successful, then this message is + returned by the + google.longrunning.Operations.response field if the + operation was successful. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a import_config.ImportUserEventsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, import_config.ImportUserEventsRequest): + request = import_config.ImportUserEventsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.import_user_events] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + import_config.ImportUserEventsResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + def rejoin_user_events(self, + request: Union[user_event_service.RejoinUserEventsRequest, dict] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Triggers 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 + with latest version of product catalog. It can also be + used to correct events joined with wrong product + catalog. + + Args: + request (Union[google.cloud.retail_v2.types.RejoinUserEventsRequest, dict]): + The request object. Request message for RejoinUserEvents + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.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.RejoinUserEventsResponse` + Response message for RejoinUserEvents method. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a user_event_service.RejoinUserEventsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, user_event_service.RejoinUserEventsRequest): + request = user_event_service.RejoinUserEventsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.rejoin_user_events] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + user_event_service.RejoinUserEventsResponse, + metadata_type=user_event_service.RejoinUserEventsMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-retail", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ( + "UserEventServiceClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/__init__.py new file mode 100644 index 00000000..7cff2187 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/__init__.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from typing import Dict, Type + +from .base import UserEventServiceTransport +from .grpc import UserEventServiceGrpcTransport +from .grpc_asyncio import UserEventServiceGrpcAsyncIOTransport + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[UserEventServiceTransport]] +_transport_registry['grpc'] = UserEventServiceGrpcTransport +_transport_registry['grpc_asyncio'] = UserEventServiceGrpcAsyncIOTransport + +__all__ = ( + 'UserEventServiceTransport', + 'UserEventServiceGrpcTransport', + 'UserEventServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/base.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/base.py new file mode 100644 index 00000000..0a28e430 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/base.py @@ -0,0 +1,226 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.api import httpbody_pb2 # type: ignore +from google.cloud.retail_v2.types import import_config +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 +from google.longrunning import operations_pb2 # type: ignore + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + 'google-cloud-retail', + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class UserEventServiceTransport(abc.ABC): + """Abstract transport class for UserEventService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.googleapis.com' + def __init__( + self, *, + host: str = DEFAULT_HOST, + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ':' not in host: + host += ':443' + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs("'credentials_file' and 'credentials' are mutually exclusive") + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id + ) + elif credentials is None: + credentials, _ = google.auth.default(**scopes_kwargs, quota_project_id=quota_project_id) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if always_use_jwt_access and isinstance(credentials, service_account.Credentials) and hasattr(service_account.Credentials, "with_always_use_jwt_access"): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + 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.collect_user_event: gapic_v1.method.wrap_method( + self.collect_user_event, + default_timeout=None, + client_info=client_info, + ), + self.purge_user_events: gapic_v1.method.wrap_method( + self.purge_user_events, + default_retry=retries.Retry( +initial=0.1,maximum=30.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=30.0, + ), + default_timeout=30.0, + client_info=client_info, + ), + self.import_user_events: gapic_v1.method.wrap_method( + self.import_user_events, + default_retry=retries.Retry( +initial=0.1,maximum=300.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.rejoin_user_events: gapic_v1.method.wrap_method( + 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! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def write_user_event(self) -> Callable[ + [user_event_service.WriteUserEventRequest], + Union[ + user_event.UserEvent, + Awaitable[user_event.UserEvent] + ]]: + raise NotImplementedError() + + @property + def collect_user_event(self) -> Callable[ + [user_event_service.CollectUserEventRequest], + Union[ + httpbody_pb2.HttpBody, + Awaitable[httpbody_pb2.HttpBody] + ]]: + raise NotImplementedError() + + @property + def purge_user_events(self) -> Callable[ + [purge_config.PurgeUserEventsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def import_user_events(self) -> Callable[ + [import_config.ImportUserEventsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def rejoin_user_events(self) -> Callable[ + [user_event_service.RejoinUserEventsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + +__all__ = ( + 'UserEventServiceTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc.py new file mode 100644 index 00000000..efda9abb --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc.py @@ -0,0 +1,406 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.api import httpbody_pb2 # type: ignore +from google.cloud.retail_v2.types import import_config +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 +from google.longrunning import operations_pb2 # type: ignore +from .base import UserEventServiceTransport, DEFAULT_CLIENT_INFO + + +class UserEventServiceGrpcTransport(UserEventServiceTransport): + """gRPC backend transport for UserEventService. + + Service for ingesting end user actions on the customer + website. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + _stubs: Dict[str, Callable] + + def __init__(self, *, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + credentials=self._credentials, + credentials_file=credentials_file, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel(cls, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Sanity check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def write_user_event(self) -> Callable[ + [user_event_service.WriteUserEventRequest], + user_event.UserEvent]: + r"""Return a callable for the write user event method over gRPC. + + Writes a single user event. + + Returns: + Callable[[~.WriteUserEventRequest], + ~.UserEvent]: + 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 'write_user_event' not in self._stubs: + self._stubs['write_user_event'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.UserEventService/WriteUserEvent', + request_serializer=user_event_service.WriteUserEventRequest.serialize, + response_deserializer=user_event.UserEvent.deserialize, + ) + return self._stubs['write_user_event'] + + @property + def collect_user_event(self) -> Callable[ + [user_event_service.CollectUserEventRequest], + httpbody_pb2.HttpBody]: + r"""Return a callable for the collect user event method over gRPC. + + Writes a single user event from the browser. This + uses a GET request to due to browser restriction of + POST-ing to a 3rd party domain. + This method is used only by the Retail API JavaScript + pixel and Google Tag Manager. Users should not call this + method directly. + + Returns: + Callable[[~.CollectUserEventRequest], + ~.HttpBody]: + 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 'collect_user_event' not in self._stubs: + self._stubs['collect_user_event'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.UserEventService/CollectUserEvent', + request_serializer=user_event_service.CollectUserEventRequest.serialize, + response_deserializer=httpbody_pb2.HttpBody.FromString, + ) + return self._stubs['collect_user_event'] + + @property + def purge_user_events(self) -> Callable[ + [purge_config.PurgeUserEventsRequest], + operations_pb2.Operation]: + r"""Return a callable for the purge user events method over gRPC. + + Deletes permanently all user events specified by the + filter provided. Depending on the number of events + specified by the filter, this operation could take hours + or days to complete. To test a filter, use the list + command first. + + Returns: + Callable[[~.PurgeUserEventsRequest], + ~.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 'purge_user_events' not in self._stubs: + self._stubs['purge_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.UserEventService/PurgeUserEvents', + request_serializer=purge_config.PurgeUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['purge_user_events'] + + @property + def import_user_events(self) -> Callable[ + [import_config.ImportUserEventsRequest], + operations_pb2.Operation]: + r"""Return a callable for the import user events method over gRPC. + + Bulk import of User events. Request processing might + be synchronous. Events that already exist are skipped. + Use this method for backfilling historical user events. + Operation.response is of type ImportResponse. Note that + it is possible for a subset of the items to be + successfully inserted. Operation.metadata is of type + ImportMetadata. + + Returns: + Callable[[~.ImportUserEventsRequest], + ~.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 'import_user_events' not in self._stubs: + self._stubs['import_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.UserEventService/ImportUserEvents', + request_serializer=import_config.ImportUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_user_events'] + + @property + def rejoin_user_events(self) -> Callable[ + [user_event_service.RejoinUserEventsRequest], + operations_pb2.Operation]: + r"""Return a callable for the rejoin user events method over gRPC. + + Triggers 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 + with latest version of product catalog. It can also be + used to correct events joined with wrong product + catalog. + + Returns: + Callable[[~.RejoinUserEventsRequest], + ~.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 'rejoin_user_events' not in self._stubs: + self._stubs['rejoin_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.UserEventService/RejoinUserEvents', + request_serializer=user_event_service.RejoinUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['rejoin_user_events'] + + def close(self): + self.grpc_channel.close() + +__all__ = ( + 'UserEventServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc_asyncio.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..a0e4c061 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc_asyncio.py @@ -0,0 +1,410 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.api import httpbody_pb2 # type: ignore +from google.cloud.retail_v2.types import import_config +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 +from google.longrunning import operations_pb2 # type: ignore +from .base import UserEventServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import UserEventServiceGrpcTransport + + +class UserEventServiceGrpcAsyncIOTransport(UserEventServiceTransport): + """gRPC AsyncIO backend transport for UserEventService. + + Service for ingesting end user actions on the customer + website. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel(cls, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + def __init__(self, *, + host: str = 'retail.googleapis.com', + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: aio.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id=None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + credentials=self._credentials, + credentials_file=credentials_file, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Sanity check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def write_user_event(self) -> Callable[ + [user_event_service.WriteUserEventRequest], + Awaitable[user_event.UserEvent]]: + r"""Return a callable for the write user event method over gRPC. + + Writes a single user event. + + Returns: + Callable[[~.WriteUserEventRequest], + Awaitable[~.UserEvent]]: + 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 'write_user_event' not in self._stubs: + self._stubs['write_user_event'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.UserEventService/WriteUserEvent', + request_serializer=user_event_service.WriteUserEventRequest.serialize, + response_deserializer=user_event.UserEvent.deserialize, + ) + return self._stubs['write_user_event'] + + @property + def collect_user_event(self) -> Callable[ + [user_event_service.CollectUserEventRequest], + Awaitable[httpbody_pb2.HttpBody]]: + r"""Return a callable for the collect user event method over gRPC. + + Writes a single user event from the browser. This + uses a GET request to due to browser restriction of + POST-ing to a 3rd party domain. + This method is used only by the Retail API JavaScript + pixel and Google Tag Manager. Users should not call this + method directly. + + Returns: + Callable[[~.CollectUserEventRequest], + Awaitable[~.HttpBody]]: + 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 'collect_user_event' not in self._stubs: + self._stubs['collect_user_event'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.UserEventService/CollectUserEvent', + request_serializer=user_event_service.CollectUserEventRequest.serialize, + response_deserializer=httpbody_pb2.HttpBody.FromString, + ) + return self._stubs['collect_user_event'] + + @property + def purge_user_events(self) -> Callable[ + [purge_config.PurgeUserEventsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the purge user events method over gRPC. + + Deletes permanently all user events specified by the + filter provided. Depending on the number of events + specified by the filter, this operation could take hours + or days to complete. To test a filter, use the list + command first. + + Returns: + Callable[[~.PurgeUserEventsRequest], + 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 'purge_user_events' not in self._stubs: + self._stubs['purge_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.UserEventService/PurgeUserEvents', + request_serializer=purge_config.PurgeUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['purge_user_events'] + + @property + def import_user_events(self) -> Callable[ + [import_config.ImportUserEventsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the import user events method over gRPC. + + Bulk import of User events. Request processing might + be synchronous. Events that already exist are skipped. + Use this method for backfilling historical user events. + Operation.response is of type ImportResponse. Note that + it is possible for a subset of the items to be + successfully inserted. Operation.metadata is of type + ImportMetadata. + + Returns: + Callable[[~.ImportUserEventsRequest], + 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 'import_user_events' not in self._stubs: + self._stubs['import_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.UserEventService/ImportUserEvents', + request_serializer=import_config.ImportUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_user_events'] + + @property + def rejoin_user_events(self) -> Callable[ + [user_event_service.RejoinUserEventsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the rejoin user events method over gRPC. + + Triggers 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 + with latest version of product catalog. It can also be + used to correct events joined with wrong product + catalog. + + Returns: + Callable[[~.RejoinUserEventsRequest], + 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 'rejoin_user_events' not in self._stubs: + self._stubs['rejoin_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.UserEventService/RejoinUserEvents', + request_serializer=user_event_service.RejoinUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['rejoin_user_events'] + + def close(self): + return self.grpc_channel.close() + + +__all__ = ( + 'UserEventServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/__init__.py new file mode 100644 index 00000000..686e8b61 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/__init__.py @@ -0,0 +1,178 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .catalog import ( + Catalog, + ProductLevelConfig, +) +from .catalog_service import ( + GetDefaultBranchRequest, + GetDefaultBranchResponse, + ListCatalogsRequest, + ListCatalogsResponse, + SetDefaultBranchRequest, + UpdateCatalogRequest, +) +from .common import ( + Audience, + ColorInfo, + CustomAttribute, + FulfillmentInfo, + Image, + Interval, + PriceInfo, + Promotion, + Rating, + UserInfo, +) +from .completion_service import ( + CompleteQueryRequest, + CompleteQueryResponse, +) +from .import_config import ( + BigQuerySource, + CompletionDataInputConfig, + GcsSource, + ImportCompletionDataRequest, + ImportCompletionDataResponse, + ImportErrorsConfig, + ImportMetadata, + ImportProductsRequest, + ImportProductsResponse, + ImportUserEventsRequest, + ImportUserEventsResponse, + ProductInlineSource, + ProductInputConfig, + UserEventImportSummary, + UserEventInlineSource, + UserEventInputConfig, +) +from .prediction_service import ( + PredictRequest, + PredictResponse, +) +from .product import ( + Product, +) +from .product_service import ( + AddFulfillmentPlacesMetadata, + AddFulfillmentPlacesRequest, + AddFulfillmentPlacesResponse, + CreateProductRequest, + DeleteProductRequest, + GetProductRequest, + ListProductsRequest, + ListProductsResponse, + RemoveFulfillmentPlacesMetadata, + RemoveFulfillmentPlacesRequest, + RemoveFulfillmentPlacesResponse, + SetInventoryMetadata, + SetInventoryRequest, + SetInventoryResponse, + UpdateProductRequest, +) +from .purge_config import ( + PurgeMetadata, + PurgeUserEventsRequest, + PurgeUserEventsResponse, +) +from .search_service import ( + SearchRequest, + SearchResponse, +) +from .user_event import ( + CompletionDetail, + ProductDetail, + PurchaseTransaction, + UserEvent, +) +from .user_event_service import ( + CollectUserEventRequest, + RejoinUserEventsMetadata, + RejoinUserEventsRequest, + RejoinUserEventsResponse, + WriteUserEventRequest, +) + +__all__ = ( + 'Catalog', + 'ProductLevelConfig', + 'GetDefaultBranchRequest', + 'GetDefaultBranchResponse', + 'ListCatalogsRequest', + 'ListCatalogsResponse', + 'SetDefaultBranchRequest', + 'UpdateCatalogRequest', + 'Audience', + 'ColorInfo', + 'CustomAttribute', + 'FulfillmentInfo', + 'Image', + 'Interval', + 'PriceInfo', + 'Promotion', + 'Rating', + 'UserInfo', + 'CompleteQueryRequest', + 'CompleteQueryResponse', + 'BigQuerySource', + 'CompletionDataInputConfig', + 'GcsSource', + 'ImportCompletionDataRequest', + 'ImportCompletionDataResponse', + 'ImportErrorsConfig', + 'ImportMetadata', + 'ImportProductsRequest', + 'ImportProductsResponse', + 'ImportUserEventsRequest', + 'ImportUserEventsResponse', + 'ProductInlineSource', + 'ProductInputConfig', + 'UserEventImportSummary', + 'UserEventInlineSource', + 'UserEventInputConfig', + 'PredictRequest', + 'PredictResponse', + 'Product', + 'AddFulfillmentPlacesMetadata', + 'AddFulfillmentPlacesRequest', + 'AddFulfillmentPlacesResponse', + 'CreateProductRequest', + 'DeleteProductRequest', + 'GetProductRequest', + 'ListProductsRequest', + 'ListProductsResponse', + 'RemoveFulfillmentPlacesMetadata', + 'RemoveFulfillmentPlacesRequest', + 'RemoveFulfillmentPlacesResponse', + 'SetInventoryMetadata', + 'SetInventoryRequest', + 'SetInventoryResponse', + 'UpdateProductRequest', + 'PurgeMetadata', + 'PurgeUserEventsRequest', + 'PurgeUserEventsResponse', + 'SearchRequest', + 'SearchResponse', + 'CompletionDetail', + 'ProductDetail', + 'PurchaseTransaction', + 'UserEvent', + 'CollectUserEventRequest', + 'RejoinUserEventsMetadata', + 'RejoinUserEventsRequest', + 'RejoinUserEventsResponse', + 'WriteUserEventRequest', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/catalog.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/catalog.py new file mode 100644 index 00000000..77327f5a --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/catalog.py @@ -0,0 +1,130 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'ProductLevelConfig', + 'Catalog', + }, +) + + +class ProductLevelConfig(proto.Message): + r"""Configures what level the product should be uploaded with + regards to how users will be send events and how predictions + will be made. + + Attributes: + ingestion_product_type (str): + The type of [Product][google.cloud.retail.v2.Product]s + allowed to be ingested into the catalog. Acceptable values + are: + + - ``primary`` (default): You can ingest + [Product][google.cloud.retail.v2.Product]s of all types. + When ingesting a + [Product][google.cloud.retail.v2.Product], its type will + default to + [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + if unset. + - ``variant``: You can only ingest + [Product.Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product]s. This means + [Product.primary_product_id][google.cloud.retail.v2.Product.primary_product_id] + cannot be empty. + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + + If this field is ``variant`` and + [merchant_center_product_id_field][google.cloud.retail.v2.ProductLevelConfig.merchant_center_product_id_field] + is ``itemGroupId``, an INVALID_ARGUMENT error is returned. + + See `Using product + levels `__ + for more details. + merchant_center_product_id_field (str): + Which field of `Merchant Center + Product `__ + should be imported as + [Product.id][google.cloud.retail.v2.Product.id]. Acceptable + values are: + + - ``offerId`` (default): Import ``offerId`` as the product + ID. + - ``itemGroupId``: Import ``itemGroupId`` as the product + ID. Notice that Retail API will choose one item from the + ones with the same ``itemGroupId``, and use it to + represent the item group. + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + + If this field is ``itemGroupId`` and + [ingestion_product_type][google.cloud.retail.v2.ProductLevelConfig.ingestion_product_type] + is ``variant``, an INVALID_ARGUMENT error is returned. + + See `Using product + levels `__ + for more details. + """ + + ingestion_product_type = proto.Field( + proto.STRING, + number=1, + ) + merchant_center_product_id_field = proto.Field( + proto.STRING, + number=2, + ) + + +class Catalog(proto.Message): + r"""The catalog configuration. + + Attributes: + name (str): + Required. Immutable. The fully qualified + resource name of the catalog. + display_name (str): + Required. Immutable. The catalog display name. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + product_level_config (google.cloud.retail_v2.types.ProductLevelConfig): + Required. The product level configuration. + """ + + 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', + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/catalog_service.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/catalog_service.py new file mode 100644 index 00000000..32e84a43 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/catalog_service.py @@ -0,0 +1,235 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.cloud.retail_v2.types import catalog as gcr_catalog +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'ListCatalogsRequest', + 'ListCatalogsResponse', + 'UpdateCatalogRequest', + 'SetDefaultBranchRequest', + 'GetDefaultBranchRequest', + 'GetDefaultBranchResponse', + }, +) + + +class ListCatalogsRequest(proto.Message): + r"""Request for + [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] + method. + + Attributes: + parent (str): + Required. The account resource name with an associated + location. + + If the caller does not have permission to list + [Catalog][google.cloud.retail.v2.Catalog]s under this + location, regardless of whether or not this location exists, + a PERMISSION_DENIED error is returned. + page_size (int): + Maximum number of [Catalog][google.cloud.retail.v2.Catalog]s + to return. If unspecified, defaults to 50. The maximum + allowed value is 1000. Values above 1000 will be coerced to + 1000. + + If this field is negative, an INVALID_ARGUMENT is returned. + page_token (str): + A page token + [ListCatalogsResponse.next_page_token][google.cloud.retail.v2.ListCatalogsResponse.next_page_token], + received from a previous + [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] + call. Provide this to retrieve the subsequent page. + + When paginating, all other parameters provided to + [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] + must match the call that provided the page token. Otherwise, + 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, + ) + + +class ListCatalogsResponse(proto.Message): + r"""Response for + [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] + method. + + Attributes: + catalogs (Sequence[google.cloud.retail_v2.types.Catalog]): + All the customer's + [Catalog][google.cloud.retail.v2.Catalog]s. + next_page_token (str): + A token that can be sent as + [ListCatalogsRequest.page_token][google.cloud.retail.v2.ListCatalogsRequest.page_token] + to retrieve the next page. If this field is omitted, there + are no subsequent pages. + """ + + @property + def raw_page(self): + return self + + catalogs = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcr_catalog.Catalog, + ) + next_page_token = proto.Field( + proto.STRING, + number=2, + ) + + +class UpdateCatalogRequest(proto.Message): + r"""Request for + [CatalogService.UpdateCatalog][google.cloud.retail.v2.CatalogService.UpdateCatalog] + method. + + Attributes: + catalog (google.cloud.retail_v2.types.Catalog): + Required. The [Catalog][google.cloud.retail.v2.Catalog] to + update. + + If the caller does not have permission to update the + [Catalog][google.cloud.retail.v2.Catalog], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Catalog][google.cloud.retail.v2.Catalog] to update + does not exist, a NOT_FOUND error is returned. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [Catalog][google.cloud.retail.v2.Catalog] to update. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + """ + + catalog = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_catalog.Catalog, + ) + update_mask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class SetDefaultBranchRequest(proto.Message): + r"""Request message to set a specified branch as new default_branch. + + Attributes: + catalog (str): + Full resource name of the catalog, such as + ``projects/*/locations/global/catalogs/default_catalog``. + branch_id (str): + The final component of the resource name of a branch. + + This field must be one of "0", "1" or "2". Otherwise, an + INVALID_ARGUMENT error is returned. + note (str): + Some note on this request, this can be retrieved by + [CatalogService.GetDefaultBranch][google.cloud.retail.v2.CatalogService.GetDefaultBranch] + before next valid default branch set occurs. + + This field must be a UTF-8 encoded string with a length + limit of 1,000 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + """ + + catalog = proto.Field( + proto.STRING, + number=1, + ) + branch_id = proto.Field( + proto.STRING, + number=2, + ) + note = proto.Field( + proto.STRING, + number=3, + ) + + +class GetDefaultBranchRequest(proto.Message): + r"""Request message to show which branch is currently the default + branch. + + Attributes: + catalog (str): + The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog``. + """ + + catalog = proto.Field( + proto.STRING, + number=1, + ) + + +class GetDefaultBranchResponse(proto.Message): + r"""Response message of + [CatalogService.GetDefaultBranch][google.cloud.retail.v2.CatalogService.GetDefaultBranch]. + + Attributes: + branch (str): + Full resource name of the branch id currently + set as default branch. + set_time (google.protobuf.timestamp_pb2.Timestamp): + The time when this branch is set to default. + note (str): + This corresponds to + [SetDefaultBranchRequest.note][google.cloud.retail.v2.SetDefaultBranchRequest.note] + 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, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/common.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/common.py new file mode 100644 index 00000000..9e3c3c58 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/common.py @@ -0,0 +1,651 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'Audience', + 'ColorInfo', + 'CustomAttribute', + 'FulfillmentInfo', + 'Image', + 'Interval', + 'PriceInfo', + 'Rating', + 'UserInfo', + 'Promotion', + }, +) + + +class Audience(proto.Message): + r"""An intended audience of the + [Product][google.cloud.retail.v2.Product] for whom it's sold. + + Attributes: + genders (Sequence[str]): + The genders of the audience. Strongly encouraged to use the + standard values: "male", "female", "unisex". + + At most 5 values are allowed. Each value must be a UTF-8 + encoded string with a length limit of 128 characters. + Otherwise, an INVALID_ARGUMENT error is returned. + + Google Merchant Center property + `gender `__. + Schema.org property + `Product.audience.suggestedGender `__. + age_groups (Sequence[str]): + The age groups of the audience. Strongly encouraged to use + the standard values: "newborn" (up to 3 months old), + "infant" (3–12 months old), "toddler" (1–5 years old), + "kids" (5–13 years old), "adult" (typically teens or older). + + At most 5 values are allowed. Each value must be a UTF-8 + encoded string with a length limit of 128 characters. + Otherwise, an INVALID_ARGUMENT error is returned. + + Google Merchant Center property + `age_group `__. + Schema.org property + `Product.audience.suggestedMinAge `__ + and + `Product.audience.suggestedMaxAge `__. + """ + + genders = proto.RepeatedField( + proto.STRING, + number=1, + ) + age_groups = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class ColorInfo(proto.Message): + r"""The color information of a + [Product][google.cloud.retail.v2.Product]. + + Attributes: + color_families (Sequence[str]): + The standard color families. Strongly recommended to use the + following standard color groups: "Red", "Pink", "Orange", + "Yellow", "Purple", "Green", "Cyan", "Blue", "Brown", + "White", "Gray", "Black" and "Mixed". Normally it is + expected to have only 1 color family. May consider using + single "Mixed" instead of multiple values. + + A maximum of 5 values are allowed. Each value must be a + UTF-8 encoded string with a length limit of 128 characters. + Otherwise, an INVALID_ARGUMENT error is returned. + + Google Merchant Center property + `color `__. + Schema.org property + `Product.color `__. + colors (Sequence[str]): + The color display names, which may be different from + standard color family names, such as the color aliases used + in the website frontend. Normally it is expected to have + only 1 color. May consider using single "Mixed" instead of + multiple values. + + A maximum of 25 colors are allowed. Each value must be a + UTF-8 encoded string with a length limit of 128 characters. + Otherwise, an INVALID_ARGUMENT error is returned. + + Google Merchant Center property + `color `__. + Schema.org property + `Product.color `__. + """ + + color_families = proto.RepeatedField( + proto.STRING, + number=1, + ) + colors = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class CustomAttribute(proto.Message): + r"""A custom attribute that is not explicitly modeled in + [Product][google.cloud.retail.v2.Product]. + + Attributes: + text (Sequence[str]): + 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. + + 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. + numbers (Sequence[float]): + 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 + [SearchService.Search][google.cloud.retail.v2.SearchService.Search]. + + This field is ignored in a + [UserEvent][google.cloud.retail.v2.UserEvent]. + + Only set if type + [text][google.cloud.retail.v2.CustomAttribute.text] is set. + Otherwise, a INVALID_ARGUMENT error is returned. + + 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 + [SearchService.Search][google.cloud.retail.v2.SearchService.Search]. + + This field is ignored in a + [UserEvent][google.cloud.retail.v2.UserEvent]. + + See + [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter], + [SearchRequest.facet_specs][google.cloud.retail.v2.SearchRequest.facet_specs] + and + [SearchRequest.boost_spec][google.cloud.retail.v2.SearchRequest.boost_spec] + for more details. + + 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, + ) + + +class FulfillmentInfo(proto.Message): + r"""Fulfillment information, such as the store IDs for in-store + pickup or region IDs for different shipping methods. + + Attributes: + type_ (str): + The fulfillment type, including 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. + place_ids (Sequence[str]): + The IDs for this + [type][google.cloud.retail.v2.FulfillmentInfo.type], such as + the store IDs for + [FulfillmentInfo.type.pickup-in-store][google.cloud.retail.v2.FulfillmentInfo.type] + or the region IDs for + [FulfillmentInfo.type.same-day-delivery][google.cloud.retail.v2.FulfillmentInfo.type]. + + A maximum of 3000 values are allowed. Each value must be a + string with a length limit of 30 characters, matching the + pattern ``[a-zA-Z0-9_-]+``, such as "store1" or "REGION-2". + Otherwise, an INVALID_ARGUMENT error is returned. + """ + + 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. + + Attributes: + uri (str): + Required. URI of the image. + + This field must be a valid UTF-8 encoded URI with a length + limit of 5,000 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + Google Merchant Center property + `image_link `__. + Schema.org property + `Product.image `__. + height (int): + Height of the image in number of pixels. + + This field must be nonnegative. Otherwise, an + INVALID_ARGUMENT error is returned. + width (int): + Width of the image in number of pixels. + + This field must be nonnegative. Otherwise, an + 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, + ) + + +class Interval(proto.Message): + r"""A floating point interval. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + minimum (float): + Inclusive lower bound. + + This field is a member of `oneof`_ ``min``. + exclusive_minimum (float): + Exclusive lower bound. + + This field is a member of `oneof`_ ``min``. + maximum (float): + Inclusive upper bound. + + This field is a member of `oneof`_ ``max``. + exclusive_maximum (float): + Exclusive upper bound. + + 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', + ) + + +class PriceInfo(proto.Message): + r"""The price information of a + [Product][google.cloud.retail.v2.Product]. + + Attributes: + currency_code (str): + The 3-letter currency code defined in `ISO + 4217 `__. + + If this field is an unrecognizable currency code, an + INVALID_ARGUMENT error is returned. + + The + [Product.Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product]s with the same + [Product.primary_product_id][google.cloud.retail.v2.Product.primary_product_id] + must share the same + [currency_code][google.cloud.retail.v2.PriceInfo.currency_code]. + Otherwise, a FAILED_PRECONDITION error is returned. + price (float): + Price of the product. + + Google Merchant Center property + `price `__. + Schema.org property + `Offer.priceSpecification `__. + original_price (float): + Price of the product without any discount. If zero, by + default set to be the + [price][google.cloud.retail.v2.PriceInfo.price]. + cost (float): + The costs associated with the sale of a particular product. + Used for gross profit reporting. + + - Profit = [price][google.cloud.retail.v2.PriceInfo.price] + - [cost][google.cloud.retail.v2.PriceInfo.cost] + + Google Merchant Center property + `cost_of_goods_sold `__. + price_effective_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp when the + [price][google.cloud.retail.v2.PriceInfo.price] starts to be + effective. This can be set as a future timestamp, and the + [price][google.cloud.retail.v2.PriceInfo.price] is only used + for search after + [price_effective_time][google.cloud.retail.v2.PriceInfo.price_effective_time]. + If so, the + [original_price][google.cloud.retail.v2.PriceInfo.original_price] + must be set and + [original_price][google.cloud.retail.v2.PriceInfo.original_price] + is used before + [price_effective_time][google.cloud.retail.v2.PriceInfo.price_effective_time]. + + Do not set if + [price][google.cloud.retail.v2.PriceInfo.price] is always + effective because it will cause additional latency during + search. + price_expire_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp when the + [price][google.cloud.retail.v2.PriceInfo.price] stops to be + effective. The + [price][google.cloud.retail.v2.PriceInfo.price] is used for + search before + [price_expire_time][google.cloud.retail.v2.PriceInfo.price_expire_time]. + If this field is set, the + [original_price][google.cloud.retail.v2.PriceInfo.original_price] + must be set and + [original_price][google.cloud.retail.v2.PriceInfo.original_price] + is used after + [price_expire_time][google.cloud.retail.v2.PriceInfo.price_expire_time]. + + Do not set if + [price][google.cloud.retail.v2.PriceInfo.price] is always + effective because it will cause additional latency during + search. + price_range (google.cloud.retail_v2.types.PriceInfo.PriceRange): + Output only. The price range of all the child + [Product.Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product]s grouped together + on the + [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product]. Only populated + for + [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product]s. + + Note: This field is OUTPUT_ONLY for + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct]. + Do not set this field in API requests. + """ + + class PriceRange(proto.Message): + r"""The price range of all + [variant][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product] having the same + [Product.primary_product_id][google.cloud.retail.v2.Product.primary_product_id]. + + Attributes: + price (google.cloud.retail_v2.types.Interval): + The inclusive + [Product.pricing_info.price][google.cloud.retail.v2.PriceInfo.price] + interval of all + [variant][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product] having the same + [Product.primary_product_id][google.cloud.retail.v2.Product.primary_product_id]. + original_price (google.cloud.retail_v2.types.Interval): + The inclusive + [Product.pricing_info.original_price][google.cloud.retail.v2.PriceInfo.original_price] + internal of all + [variant][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product] having the same + [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_effective_time = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + price_expire_time = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + price_range = proto.Field( + proto.MESSAGE, + number=7, + message=PriceRange, + ) + + +class Rating(proto.Message): + r"""The rating of a [Product][google.cloud.retail.v2.Product]. + + Attributes: + rating_count (int): + The total number of ratings. This value is independent of + the value of + [rating_histogram][google.cloud.retail.v2.Rating.rating_histogram]. + + This value must be nonnegative. Otherwise, an + INVALID_ARGUMENT error is returned. + average_rating (float): + The average rating of the + [Product][google.cloud.retail.v2.Product]. + + The rating is scaled at 1-5. Otherwise, an INVALID_ARGUMENT + error is returned. + rating_histogram (Sequence[int]): + List of rating counts per rating value (index = rating - 1). + The list is empty if there is no rating. If the list is + non-empty, its size is always 5. Otherwise, an + INVALID_ARGUMENT error is returned. + + For example, [41, 14, 13, 47, 303]. It means that the + [Product][google.cloud.retail.v2.Product] got 41 ratings + 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, + ) + + +class UserInfo(proto.Message): + r"""Information of an end user. + + Attributes: + user_id (str): + Highly recommended for logged-in users. Unique identifier + for logged-in user, such as a user name. + + 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. + + 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. + user_agent (str): + User agent as included in the HTTP header. Required for + getting + [SearchResponse.sponsored_results][google.cloud.retail.v2.SearchResponse.sponsored_results]. + + The field must be a UTF-8 encoded string with a length limit + of 1,000 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + This should not be set when using the client side event + reporting with GTM or 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. + direct_user_request (bool): + True if the request is made directly from the end user, in + which case the + [ip_address][google.cloud.retail.v2.UserInfo.ip_address] and + [user_agent][google.cloud.retail.v2.UserInfo.user_agent] can + be populated from the HTTP request. This flag should be set + only if the API request is made directly from the end user + such as a mobile app (and not if a gateway or a server is + processing and pushing the user events). + + This should not be set when using the JavaScript tag in + [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, + ) + + +class Promotion(proto.Message): + r"""Promotion information. + + 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. + + Google Merchant Center property + `promotion `__. + """ + + promotion_id = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/completion_service.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/completion_service.py new file mode 100644 index 00000000..dfa9bfb8 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/completion_service.py @@ -0,0 +1,218 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.cloud.retail_v2.types import common + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'CompleteQueryRequest', + 'CompleteQueryResponse', + }, +) + + +class CompleteQueryRequest(proto.Message): + r"""Auto-complete parameters. + + Attributes: + catalog (str): + Required. Catalog for which the completion is performed. + + Full resource name of catalog, such as + ``projects/*/locations/global/catalogs/default_catalog``. + query (str): + Required. The query used to generate + 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. + + 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. + device_type (str): + The device type context for completion suggestions. It is + useful to apply different suggestions on different device + types, e.g. ``DESKTOP``, ``MOBILE``. If it is empty, the + suggestions are across all device types. + + Supported formats: + + - ``UNKNOWN_DEVICE_TYPE`` + + - ``DESKTOP`` + + - ``MOBILE`` + + - A customized string starts with ``OTHER_``, e.g. + ``OTHER_IPHONE``. + dataset (str): + Determines which dataset to use for fetching completion. + "user-data" will use the imported dataset through + [CompletionService.ImportCompletionData][google.cloud.retail.v2.CompletionService.ImportCompletionData]. + "cloud-retail" will use the dataset generated by cloud + retail based on user events. If leave empty, it will use the + "user-data". + + Current supported values: + + - user-data + + - cloud-retail This option requires additional + allowlisting. Before using cloud-retail, contact Cloud + Retail support team first. + max_suggestions (int): + Completion max suggestions. If left unset or set to 0, then + will fallback to the configured value + [CompletionConfig.max_suggestions][]. + + The maximum allowed max suggestions is 20. If it is set + 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, + ) + + +class CompleteQueryResponse(proto.Message): + r"""Response of the auto-complete query. + + Attributes: + completion_results (Sequence[google.cloud.retail_v2.types.CompleteQueryResponse.CompletionResult]): + Results of the matching suggestions. The + result list is ordered and the first result is + 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. + 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. + Contact Retail Search support team if you are interested in + enabling it. + + This feature is only available when + [CompleteQueryRequest.visitor_id][google.cloud.retail.v2.CompleteQueryRequest.visitor_id] + field is set and + [UserEvent][google.cloud.retail.v2.UserEvent] is imported. + The recent searches satisfy the follow rules: + + - They are ordered from latest to oldest. + - They are matched with + [CompleteQueryRequest.query][google.cloud.retail.v2.CompleteQueryRequest.query] + case insensitively. + - They are transformed to lower cases. + - They are UTF-8 safe. + + Recent searches are deduplicated. More recent searches will + be reserved when duplication happens. + """ + + class CompletionResult(proto.Message): + r"""Resource that represents completion results. + + Attributes: + suggestion (str): + The suggestion for the query. + attributes (Sequence[google.cloud.retail_v2.types.CompleteQueryResponse.CompletionResult.AttributesEntry]): + Additional custom attributes ingested through + BigQuery. + """ + + suggestion = proto.Field( + proto.STRING, + number=1, + ) + attributes = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=2, + message=common.CustomAttribute, + ) + + class RecentSearchResult(proto.Message): + r"""Recent search of this user. + + Attributes: + recent_search (str): + The recent search query. + """ + + recent_search = proto.Field( + proto.STRING, + number=1, + ) + + completion_results = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=CompletionResult, + ) + attribution_token = proto.Field( + proto.STRING, + number=2, + ) + recent_search_results = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=RecentSearchResult, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/import_config.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/import_config.py new file mode 100644 index 00000000..8eed17f4 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/import_config.py @@ -0,0 +1,677 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.cloud.retail_v2.types import product +from google.cloud.retail_v2.types import user_event +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from google.type import date_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'GcsSource', + 'BigQuerySource', + 'ProductInlineSource', + 'UserEventInlineSource', + 'ImportErrorsConfig', + 'ImportProductsRequest', + 'ImportUserEventsRequest', + 'ImportCompletionDataRequest', + 'ProductInputConfig', + 'UserEventInputConfig', + 'CompletionDataInputConfig', + 'ImportMetadata', + 'ImportProductsResponse', + 'ImportUserEventsResponse', + 'UserEventImportSummary', + 'ImportCompletionDataResponse', + }, +) + + +class GcsSource(proto.Message): + r"""Google Cloud Storage location for input content. + format. + + Attributes: + input_uris (Sequence[str]): + Required. Google Cloud Storage URIs to input files. URI can + be up to 2000 characters long. URIs can match the full + object path (for example, + ``gs://bucket/directory/object.json``) or a pattern matching + one or more files, such as ``gs://bucket/directory/*.json``. + A request can contain at most 100 files, and each file can + be up to 2 GB. See `Importing product + information `__ + for the expected file format and setup instructions. + data_schema (str): + The schema to use when parsing the data from the source. + + Supported values for product imports: + + - ``product`` (default): One JSON + [Product][google.cloud.retail.v2.Product] per line. Each + product must have a valid + [Product.id][google.cloud.retail.v2.Product.id]. + - ``product_merchant_center``: See `Importing catalog data + from Merchant + Center `__. + + Supported values for user events imports: + + - ``user_event`` (default): One JSON + [UserEvent][google.cloud.retail.v2.UserEvent] per line. + - ``user_event_ga360``: Using + https://support.google.com/analytics/answer/3437719. + """ + + input_uris = proto.RepeatedField( + proto.STRING, + number=1, + ) + data_schema = proto.Field( + proto.STRING, + number=2, + ) + + +class BigQuerySource(proto.Message): + r"""BigQuery source import data from. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + partition_date (google.type.date_pb2.Date): + BigQuery time partitioned table's \_PARTITIONDATE in + YYYY-MM-DD format. + + Only supported when + [ImportProductsRequest.reconciliation_mode][google.cloud.retail.v2.ImportProductsRequest.reconciliation_mode] + is set to ``FULL``. + + This field is a member of `oneof`_ ``partition``. + project_id (str): + The project ID (can be project # or ID) that + the BigQuery source is in with a length limit of + 128 characters. If not specified, inherits the + project ID from the parent request. + dataset_id (str): + Required. The BigQuery data set to copy the + data from with a length limit of 1,024 + characters. + table_id (str): + Required. The BigQuery table to copy the data + from with a length limit of 1,024 characters. + gcs_staging_dir (str): + Intermediate Cloud Storage directory used for + the import with a length limit of 2,000 + characters. Can be specified if one wants to + have the BigQuery export to a specific Cloud + Storage directory. + data_schema (str): + The schema to use when parsing the data from the source. + + Supported values for product imports: + + - ``product`` (default): One JSON + [Product][google.cloud.retail.v2.Product] per line. Each + product must have a valid + [Product.id][google.cloud.retail.v2.Product.id]. + - ``product_merchant_center``: See `Importing catalog data + from Merchant + Center `__. + + Supported values for user events imports: + + - ``user_event`` (default): One JSON + [UserEvent][google.cloud.retail.v2.UserEvent] per line. + - ``user_event_ga360``: Using + https://support.google.com/analytics/answer/3437719. + """ + + partition_date = proto.Field( + 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, + ) + + +class ProductInlineSource(proto.Message): + r"""The inline source for the input config for ImportProducts + method. + + Attributes: + products (Sequence[google.cloud.retail_v2.types.Product]): + Required. A list of products to update/create. Each product + must have a valid + [Product.id][google.cloud.retail.v2.Product.id]. Recommended + max of 100 items. + """ + + products = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=product.Product, + ) + + +class UserEventInlineSource(proto.Message): + r"""The inline source for the input config for ImportUserEvents + method. + + Attributes: + user_events (Sequence[google.cloud.retail_v2.types.UserEvent]): + Required. A list of user events to import. + Recommended max of 10k items. + """ + + user_events = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=user_event.UserEvent, + ) + + +class ImportErrorsConfig(proto.Message): + r"""Configuration of destination for Import related errors. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + 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. + + This field is a member of `oneof`_ ``destination``. + """ + + gcs_prefix = proto.Field( + proto.STRING, + number=1, + oneof='destination', + ) + + +class ImportProductsRequest(proto.Message): + r"""Request message for Import methods. + + Attributes: + parent (str): + Required. + ``projects/1234/locations/global/catalogs/default_catalog/branches/default_branch`` + + If no updateMask is specified, requires products.create + 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``. + input_config (google.cloud.retail_v2.types.ProductInputConfig): + Required. The desired input location of the + data. + errors_config (google.cloud.retail_v2.types.ImportErrorsConfig): + The desired location of errors incurred + during the Import. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + imported 'products' to update. If not set, will + by default update all fields. + reconciliation_mode (google.cloud.retail_v2.types.ImportProductsRequest.ReconciliationMode): + The mode of reconciliation between existing products and the + products to be imported. Defaults to + [ReconciliationMode.INCREMENTAL][google.cloud.retail.v2.ImportProductsRequest.ReconciliationMode.INCREMENTAL]. + notification_pubsub_topic (str): + Pub/Sub topic for receiving notification. If this field is + set, when the import is finished, a notification will be + sent to specified Pub/Sub topic. The message data will be + JSON string of a [Operation][google.longrunning.Operation]. + Format of the Pub/Sub topic is + ``projects/{project}/topics/{topic}``. + + Only supported when + [ImportProductsRequest.reconciliation_mode][google.cloud.retail.v2.ImportProductsRequest.reconciliation_mode] + is set to ``FULL``. + """ + class ReconciliationMode(proto.Enum): + r"""Indicates how imported products are reconciled with the + existing products created or imported before. + """ + RECONCILIATION_MODE_UNSPECIFIED = 0 + 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', + ) + update_mask = proto.Field( + 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, + ) + + +class ImportUserEventsRequest(proto.Message): + r"""Request message for the ImportUserEvents request. + + Attributes: + parent (str): + Required. + ``projects/1234/locations/global/catalogs/default_catalog`` + input_config (google.cloud.retail_v2.types.UserEventInputConfig): + Required. The desired input location of the + data. + errors_config (google.cloud.retail_v2.types.ImportErrorsConfig): + The desired location of errors incurred + during the Import. Cannot be set for inline user + 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', + ) + + +class ImportCompletionDataRequest(proto.Message): + r"""Request message for ImportCompletionData methods. + + Attributes: + parent (str): + Required. The catalog which the suggestions dataset belongs + to. + + Format: + ``projects/1234/locations/global/catalogs/default_catalog``. + input_config (google.cloud.retail_v2.types.CompletionDataInputConfig): + Required. The desired input location of the + data. + notification_pubsub_topic (str): + Pub/Sub topic for receiving notification. If this field is + set, when the import is finished, a notification will be + sent to specified Pub/Sub topic. The message data will be + JSON string of a [Operation][google.longrunning.Operation]. + Format of the Pub/Sub topic is + ``projects/{project}/topics/{topic}``. + """ + + parent = proto.Field( + proto.STRING, + number=1, + ) + input_config = proto.Field( + proto.MESSAGE, + number=2, + message='CompletionDataInputConfig', + ) + notification_pubsub_topic = proto.Field( + proto.STRING, + number=3, + ) + + +class ProductInputConfig(proto.Message): + r"""The input config source for products. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + product_inline_source (google.cloud.retail_v2.types.ProductInlineSource): + The Inline source for the input content for + products. + + This field is a member of `oneof`_ ``source``. + gcs_source (google.cloud.retail_v2.types.GcsSource): + Google Cloud Storage location for the input + content. + + This field is a member of `oneof`_ ``source``. + big_query_source (google.cloud.retail_v2.types.BigQuerySource): + BigQuery input source. + + This field is a member of `oneof`_ ``source``. + """ + + product_inline_source = proto.Field( + proto.MESSAGE, + number=1, + oneof='source', + message='ProductInlineSource', + ) + gcs_source = proto.Field( + proto.MESSAGE, + number=2, + oneof='source', + message='GcsSource', + ) + big_query_source = proto.Field( + proto.MESSAGE, + number=3, + oneof='source', + message='BigQuerySource', + ) + + +class UserEventInputConfig(proto.Message): + r"""The input config source for user events. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + user_event_inline_source (google.cloud.retail_v2.types.UserEventInlineSource): + Required. The Inline source for the input + content for UserEvents. + + This field is a member of `oneof`_ ``source``. + gcs_source (google.cloud.retail_v2.types.GcsSource): + Required. Google Cloud Storage location for + the input content. + + This field is a member of `oneof`_ ``source``. + big_query_source (google.cloud.retail_v2.types.BigQuerySource): + Required. BigQuery input source. + + This field is a member of `oneof`_ ``source``. + """ + + user_event_inline_source = proto.Field( + proto.MESSAGE, + number=1, + oneof='source', + message='UserEventInlineSource', + ) + gcs_source = proto.Field( + proto.MESSAGE, + number=2, + oneof='source', + message='GcsSource', + ) + big_query_source = proto.Field( + proto.MESSAGE, + number=3, + oneof='source', + message='BigQuerySource', + ) + + +class CompletionDataInputConfig(proto.Message): + r"""The input config source for completion data. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + big_query_source (google.cloud.retail_v2.types.BigQuerySource): + Required. BigQuery input source. + Add the IAM permission "BigQuery Data Viewer" + for cloud-retail-customer-data- + access@system.gserviceaccount.com before using + this feature otherwise an error is thrown. + + This field is a member of `oneof`_ ``source``. + """ + + big_query_source = proto.Field( + proto.MESSAGE, + number=1, + oneof='source', + message='BigQuerySource', + ) + + +class ImportMetadata(proto.Message): + r"""Metadata related to the progress of the Import operation. + This will be returned by the + google.longrunning.Operation.metadata field. + + Attributes: + create_time (google.protobuf.timestamp_pb2.Timestamp): + Operation create time. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Operation last update time. If the operation + is done, this is also the finish time. + success_count (int): + Count of entries that were processed + successfully. + failure_count (int): + 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. + notification_pubsub_topic (str): + Pub/Sub topic for receiving notification. If this field is + set, when the import is finished, a notification will be + sent to specified Pub/Sub topic. The message data will be + JSON string of a [Operation][google.longrunning.Operation]. + Format of the Pub/Sub topic is + ``projects/{project}/topics/{topic}``. + """ + + 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): + r"""Response of the + [ImportProductsRequest][google.cloud.retail.v2.ImportProductsRequest]. + If the long running operation is done, then this message is returned + by the google.longrunning.Operations.response field if the operation + was successful. + + Attributes: + error_samples (Sequence[google.rpc.status_pb2.Status]): + A sample of errors encountered while + processing the request. + errors_config (google.cloud.retail_v2.types.ImportErrorsConfig): + Echoes the destination for the complete + errors in the request if set. + """ + + error_samples = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + errors_config = proto.Field( + proto.MESSAGE, + number=2, + message='ImportErrorsConfig', + ) + + +class ImportUserEventsResponse(proto.Message): + r"""Response of the ImportUserEventsRequest. If the long running + operation was successful, then this message is returned by the + google.longrunning.Operations.response field if the operation + was successful. + + Attributes: + error_samples (Sequence[google.rpc.status_pb2.Status]): + A sample of errors encountered while + processing the request. + errors_config (google.cloud.retail_v2.types.ImportErrorsConfig): + Echoes the destination for the complete + errors if this field was set in the request. + import_summary (google.cloud.retail_v2.types.UserEventImportSummary): + Aggregated statistics of user event import + status. + """ + + error_samples = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + errors_config = proto.Field( + proto.MESSAGE, + number=2, + message='ImportErrorsConfig', + ) + import_summary = proto.Field( + proto.MESSAGE, + number=3, + message='UserEventImportSummary', + ) + + +class UserEventImportSummary(proto.Message): + r"""A summary of import result. The UserEventImportSummary + summarizes the import status for user events. + + Attributes: + joined_events_count (int): + Count of user events imported with complete + existing catalog information. + unjoined_events_count (int): + Count of user events imported, but with + catalog information not found in the imported + catalog. + """ + + joined_events_count = proto.Field( + proto.INT64, + number=1, + ) + unjoined_events_count = proto.Field( + proto.INT64, + number=2, + ) + + +class ImportCompletionDataResponse(proto.Message): + r"""Response of the + [ImportCompletionDataRequest][google.cloud.retail.v2.ImportCompletionDataRequest]. + If the long running operation is done, this message is returned by + the google.longrunning.Operations.response field if the operation is + successful. + + Attributes: + error_samples (Sequence[google.rpc.status_pb2.Status]): + A sample of errors encountered while + processing the request. + """ + + error_samples = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/prediction_service.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/prediction_service.py new file mode 100644 index 00000000..1b668c6d --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/prediction_service.py @@ -0,0 +1,260 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.cloud.retail_v2.types import user_event as gcr_user_event +from google.protobuf import struct_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'PredictRequest', + 'PredictResponse', + }, +) + + +class PredictRequest(proto.Message): + r"""Request message for Predict method. + + Attributes: + placement (str): + Required. Full resource name of the format: + {name=projects/*/locations/global/catalogs/default_catalog/placements/*} + The ID of the Recommendations AI placement. Before you can + request predictions from your model, you must create at + least one placement for it. For more information, see + `Managing + placements `__. + + The full list of available placements can be seen at + https://console.cloud.google.com/recommendation/catalogs/default_catalog/placements + user_event (google.cloud.retail_v2.types.UserEvent): + Required. Context about the user, what they + are looking at and what action they took to + trigger the predict request. Note that this user + event detail won't be ingested to userEvent + logs. Thus, a separate userEvent write request + is required for event logging. + page_size (int): + Maximum number of results to return per page. + Set this property to the number of prediction + results needed. If zero, the service will choose + a reasonable default. The maximum allowed value + is 100. Values above 100 will be coerced to 100. + page_token (str): + The previous PredictResponse.next_page_token. + filter (str): + Filter for restricting prediction results with a length + limit of 5,000 characters. Accepts values for tags and the + ``filterOutOfStockItems`` flag. + + - Tag expressions. Restricts predictions to products that + match all of the specified tags. Boolean operators ``OR`` + and ``NOT`` are supported if the expression is enclosed + in parentheses, and must be separated from the tag values + by a space. ``-"tagA"`` is also supported and is + equivalent to ``NOT "tagA"``. Tag values must be double + quoted UTF-8 encoded strings with a size limit of 1,000 + characters. + + Note: "Recently viewed" models don't support tag + filtering at the moment. + + - filterOutOfStockItems. Restricts predictions to products + that do not have a stockState value of OUT_OF_STOCK. + + Examples: + + - tag=("Red" OR "Blue") tag="New-Arrival" tag=(NOT + "promotional") + - 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``. + validate_only (bool): + Use validate only mode for this prediction + query. If set to true, a dummy model will be + used that returns arbitrary products. Note that + the validate only mode should only be used for + testing the API, or if the model is not ready. + params (Sequence[google.cloud.retail_v2.types.PredictRequest.ParamsEntry]): + Additional domain specific parameters for the predictions. + + Allowed values: + + - ``returnProduct``: Boolean. If set to true, the + associated product object will be returned in the + ``results.metadata`` field in the prediction response. + - ``returnScore``: Boolean. If set to true, the prediction + 'score' corresponding to each returned product will be + set in the ``results.metadata`` field in the prediction + response. The given 'score' indicates the probability of + an product being clicked/purchased given the user's + context and history. + - ``strictFiltering``: Boolean. True by default. If set to + false, the service will return generic (unfiltered) + popular products instead of empty if your filter blocks + all prediction results. + - ``priceRerankLevel``: String. Default empty. If set to be + non-empty, then it needs to be one of + {'no-price-reranking', 'low-price-reranking', + 'medium-price-reranking', 'high-price-reranking'}. This + gives request-level control and adjusts prediction + results based on product price. + - ``diversityLevel``: String. Default empty. If set to be + non-empty, then it needs to be one of {'no-diversity', + 'low-diversity', 'medium-diversity', 'high-diversity', + 'auto-diversity'}. This gives request-level control and + adjusts prediction results based on product category. + labels (Sequence[google.cloud.retail_v2.types.PredictRequest.LabelsEntry]): + The labels applied to a resource must meet the following + requirements: + + - Each resource can have multiple labels, up to a maximum + of 64. + - Each label must be a key-value pair. + - Keys have a minimum length of 1 character and a maximum + length of 63 characters, and cannot be empty. Values can + be empty, and have a maximum length of 63 characters. + - Keys and values can contain only lowercase letters, + numeric characters, underscores, and dashes. All + characters must use UTF-8 encoding, and international + characters are allowed. + - The key portion of a label must be unique. However, you + can use the same key with multiple resources. + - Keys must start with a lowercase letter or international + character. + + See `Google Cloud + Document `__ + 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, + ) + params = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=7, + message=struct_pb2.Value, + ) + labels = proto.MapField( + proto.STRING, + proto.STRING, + number=8, + ) + + +class PredictResponse(proto.Message): + r"""Response message for predict method. + + Attributes: + results (Sequence[google.cloud.retail_v2.types.PredictResponse.PredictionResult]): + A list of recommended products. The order + represents the ranking (from the most relevant + product to the least). + attribution_token (str): + A unique attribution token. This should be included in the + [UserEvent][google.cloud.retail.v2.UserEvent] logs resulting + from this recommendation, which enables accurate attribution + of recommendation model performance. + missing_ids (Sequence[str]): + IDs of products in the request that were + missing from the inventory. + validate_only (bool): + True if the validateOnly property was set in + the request. + """ + + class PredictionResult(proto.Message): + r"""PredictionResult represents the recommendation prediction + results. + + Attributes: + id (str): + ID of the recommended product + metadata (Sequence[google.cloud.retail_v2.types.PredictResponse.PredictionResult.MetadataEntry]): + Additional product metadata / annotations. + + Possible values: + + - ``product``: JSON representation of the product. Will be + set if ``returnProduct`` is set to true in + ``PredictRequest.params``. + - ``score``: Prediction score in double value. Will be set + if ``returnScore`` is set to true in + ``PredictRequest.params``. + """ + + id = proto.Field( + proto.STRING, + number=1, + ) + metadata = proto.MapField( + 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, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/product.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/product.py new file mode 100644 index 00000000..944233fb --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/product.py @@ -0,0 +1,689 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.cloud.retail_v2.types import common +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', + }, +) + + +class Product(proto.Message): + r"""Product captures all metadata information of items to be + recommended or searched. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + expire_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp when this product becomes unavailable for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search]. + + If it is set, the [Product][google.cloud.retail.v2.Product] + is not available for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + after + [expire_time][google.cloud.retail.v2.Product.expire_time]. + However, the product can still be retrieved by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + and + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + [expire_time][google.cloud.retail.v2.Product.expire_time] + must be later than + [available_time][google.cloud.retail.v2.Product.available_time] + and + [publish_time][google.cloud.retail.v2.Product.publish_time], + otherwise an INVALID_ARGUMENT error is thrown. + + Google Merchant Center property + `expiration_date `__. + + This field is a member of `oneof`_ ``expiration``. + ttl (google.protobuf.duration_pb2.Duration): + Input only. The TTL (time to live) of the product. + + If it is set, it must be a non-negative value, and + [expire_time][google.cloud.retail.v2.Product.expire_time] is + set as current timestamp plus + [ttl][google.cloud.retail.v2.Product.ttl]. The derived + [expire_time][google.cloud.retail.v2.Product.expire_time] is + returned in the output and + [ttl][google.cloud.retail.v2.Product.ttl] is left blank when + retrieving the [Product][google.cloud.retail.v2.Product]. + + If it is set, the product is not available for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + after current timestamp plus + [ttl][google.cloud.retail.v2.Product.ttl]. However, the + product can still be retrieved by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + and + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + This field is a member of `oneof`_ ``expiration``. + name (str): + Immutable. Full resource name of the product, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/product_id``. + id (str): + Immutable. [Product][google.cloud.retail.v2.Product] + identifier, which is the final component of + [name][google.cloud.retail.v2.Product.name]. For example, + this field is "id_1", if + [name][google.cloud.retail.v2.Product.name] is + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/id_1``. + + This field 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 + `id `__. + Schema.org Property + `Product.sku `__. + type_ (google.cloud.retail_v2.types.Product.Type): + Immutable. The type of the product. Default to + [Catalog.product_level_config.ingestion_product_type][google.cloud.retail.v2.ProductLevelConfig.ingestion_product_type] + if unset. + primary_product_id (str): + Variant group identifier. Must be an + [id][google.cloud.retail.v2.Product.id], with the same + parent branch with this product. Otherwise, an error is + thrown. + + For + [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product]s, this field can + only be empty or set to the same value as + [id][google.cloud.retail.v2.Product.id]. + + For VARIANT [Product][google.cloud.retail.v2.Product]s, this + field cannot be empty. A maximum of 2,000 products are + allowed to share the same + [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product]. Otherwise, an + INVALID_ARGUMENT error is returned. + + Google Merchant Center Property + `item_group_id `__. + 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. + gtin (str): + The Global Trade Item Number (GTIN) of the product. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + This field must be a Unigram. Otherwise, an INVALID_ARGUMENT + error is returned. + + Google Merchant Center property + `gtin `__. + Schema.org property + `Product.isbn `__ or + `Product.gtin8 `__ or + `Product.gtin12 `__ or + `Product.gtin13 `__ or + `Product.gtin14 `__. + + If the value is not a valid GTIN, an INVALID_ARGUMENT error + is returned. + categories (Sequence[str]): + Product categories. This field is repeated for supporting + one product belonging to several parallel categories. + Strongly recommended using the full path for better search / + recommendation quality. + + To represent full path of category, use '>' sign to separate + different hierarchies. If '>' is part of the category name, + please replace it with other character(s). + + For example, if a shoes product belongs to both ["Shoes & + Accessories" -> "Shoes"] and ["Sports & Fitness" -> + "Athletic Clothing" -> "Shoes"], it could be represented as: + + :: + + "categories": [ + "Shoes & Accessories > Shoes", + "Sports & Fitness > Athletic Clothing > Shoes" + ] + + Must be set for + [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product] otherwise an + INVALID_ARGUMENT error is returned. + + At most 250 values are allowed per + [Product][google.cloud.retail.v2.Product]. Empty values are + not allowed. Each value must be a UTF-8 encoded string with + a length limit of 5,000 characters. Otherwise, an + INVALID_ARGUMENT error is returned. + + Google Merchant Center property + `google_product_category `__. + Schema.org property [Product.category] + (https://schema.org/category). + title (str): + Required. Product title. + + This field must be a UTF-8 encoded string with a length + limit of 1,000 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + Google Merchant Center property + `title `__. + Schema.org property + `Product.name `__. + brands (Sequence[str]): + The brands of the product. + + A maximum of 30 brands are allowed. Each brand must be a + UTF-8 encoded string with a length limit of 1,000 + characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + Google Merchant Center property + `brand `__. + Schema.org property + `Product.brand `__. + description (str): + Product description. + + This field must be a UTF-8 encoded string with a length + limit of 5,000 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + Google Merchant Center property + `description `__. + 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]. + + For product prediction, this field is ignored and the model + automatically detects the text language. The + [Product][google.cloud.retail.v2.Product] can include text + in different languages, but duplicating + [Product][google.cloud.retail.v2.Product]s to provide text + in multiple languages can result in degraded model + performance. + + For product search this field is in use. It defaults to + "en-US" if unset. + attributes (Sequence[google.cloud.retail_v2.types.Product.AttributesEntry]): + Highly encouraged. Extra product attributes to be included. + For example, for products, this could include the store + name, vendor, style, color, etc. These are very strong + signals for recommendation model, thus we highly recommend + providing the attributes here. + + Features that can take on one of a limited number of + possible values. Two types of features can be set are: + + Textual features. some examples would be the brand/maker of + a product, or country of a customer. Numerical features. + Some examples would be the height/weight of a product, or + age of a customer. + + For example: + ``{ "vendor": {"text": ["vendor123", "vendor456"]}, "lengths_cm": {"numbers":[2.3, 15.4]}, "heights_cm": {"numbers":[8.1, 6.4]} }``. + + This field needs to pass all below criteria, otherwise an + INVALID_ARGUMENT error is returned: + + - Max entries count: 200. + - 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. + tags (Sequence[str]): + Custom tags associated with the product. + + At most 250 values are allowed per + [Product][google.cloud.retail.v2.Product]. This value must + be a UTF-8 encoded string with a length limit of 1,000 + characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + This tag can be used for filtering recommendation results by + passing the tag as part of the + [PredictRequest.filter][google.cloud.retail.v2.PredictRequest.filter]. + + 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 + `price `__. + rating (google.cloud.retail_v2.types.Rating): + The rating of this product. + available_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp when this + [Product][google.cloud.retail.v2.Product] becomes available + for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search]. + availability (google.cloud.retail_v2.types.Product.Availability): + The online availability of the + [Product][google.cloud.retail.v2.Product]. Default to + [Availability.IN_STOCK][google.cloud.retail.v2.Product.Availability.IN_STOCK]. + + Google Merchant Center Property + `availability `__. + Schema.org Property + `Offer.availability `__. + available_quantity (google.protobuf.wrappers_pb2.Int32Value): + The available quantity of the item. + fulfillment_info (Sequence[google.cloud.retail_v2.types.FulfillmentInfo]): + Fulfillment information, such as the store IDs for in-store + pickup or region IDs for different shipping methods. + + All the elements must have distinct + [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type]. + Otherwise, an INVALID_ARGUMENT error is returned. + uri (str): + Canonical URL directly linking to the product detail page. + + It is strongly recommended to provide a valid uri for the + product, otherwise the service performance could be + significantly degraded. + + This field must be a UTF-8 encoded string with a length + limit of 5,000 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + 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. + + A maximum of 300 images are allowed. + + Google Merchant Center property + `image_link `__. + Schema.org property + `Product.image `__. + audience (google.cloud.retail_v2.types.Audience): + The target group associated with a given + audience (e.g. male, veterans, car owners, + musicians, etc.) of the product. + color_info (google.cloud.retail_v2.types.ColorInfo): + The color of the product. + + Google Merchant Center property + `color `__. + Schema.org property + `Product.color `__. + sizes (Sequence[str]): + The size of the product. To represent different size systems + or size types, consider using this format: + [[[size_system:]size_type:]size_value]. + + For example, in "US:MENS:M", "US" represents size system; + "MENS" represents size type; "M" represents size value. In + "GIRLS:27", size system is empty; "GIRLS" represents size + type; "27" represents size value. In "32 inches", both size + system and size type are empty, while size value is "32 + inches". + + A maximum of 20 values are 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 + `size `__, + `size_type `__ + and + `size_system `__. + Schema.org property + `Product.size `__. + materials (Sequence[str]): + The material of the product. For example, "leather", + "wooden". + + A maximum of 20 values are allowed. Each value must be a + UTF-8 encoded string with a length limit of 128 characters. + Otherwise, an INVALID_ARGUMENT error is returned. + + Google Merchant Center property + `material `__. + Schema.org property + `Product.material `__. + patterns (Sequence[str]): + The pattern or graphic print of the product. For example, + "striped", "polka dot", "paisley". + + A maximum of 20 values are 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 + `pattern `__. + Schema.org property + `Product.pattern `__. + conditions (Sequence[str]): + The condition of the product. Strongly encouraged to use the + standard values: "new", "refurbished", "used". + + A maximum of 5 values are 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 + `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]. + 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 + products. Note that this field is different from + [available_time][google.cloud.retail.v2.Product.available_time], + given it purely describes product freshness regardless of + when it is available on search and recommendation. + retrievable_fields (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the + [Product][google.cloud.retail.v2.Product]s are returned in + [SearchResponse][google.cloud.retail.v2.SearchResponse]. + + Supported fields for all + [type][google.cloud.retail.v2.Product.type]s: + + - [audience][google.cloud.retail.v2.Product.audience] + - [availability][google.cloud.retail.v2.Product.availability] + - [brands][google.cloud.retail.v2.Product.brands] + - [color_info][google.cloud.retail.v2.Product.color_info] + - [conditions][google.cloud.retail.v2.Product.conditions] + - [gtin][google.cloud.retail.v2.Product.gtin] + - [materials][google.cloud.retail.v2.Product.materials] + - [name][google.cloud.retail.v2.Product.name] + - [patterns][google.cloud.retail.v2.Product.patterns] + - [price_info][google.cloud.retail.v2.Product.price_info] + - [rating][google.cloud.retail.v2.Product.rating] + - [sizes][google.cloud.retail.v2.Product.sizes] + - [title][google.cloud.retail.v2.Product.title] + - [uri][google.cloud.retail.v2.Product.uri] + + Supported fields only for + [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + and + [Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION]: + + - [categories][google.cloud.retail.v2.Product.categories] + - [description][google.cloud.retail.v2.Product.description] + - [images][google.cloud.retail.v2.Product.images] + + Supported fields only for + [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT]: + + - Only the first image in + [images][google.cloud.retail.v2.Product.images] + + To mark + [attributes][google.cloud.retail.v2.Product.attributes] as + retrievable, include paths of the form "attributes.key" + where "key" is the key of a custom attribute, as specified + in [attributes][google.cloud.retail.v2.Product.attributes]. + + For + [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + and + [Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION], + the following fields are always returned in + [SearchResponse][google.cloud.retail.v2.SearchResponse] by + default: + + - [name][google.cloud.retail.v2.Product.name] + + For + [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT], + the following fields are always returned in by default: + + - [name][google.cloud.retail.v2.Product.name] + - [color_info][google.cloud.retail.v2.Product.color_info] + + Maximum number of paths is 30. Otherwise, an + INVALID_ARGUMENT error is returned. + + Note: Returning more fields in + [SearchResponse][google.cloud.retail.v2.SearchResponse] may + increase response payload size and serving latency. + variants (Sequence[google.cloud.retail_v2.types.Product]): + Output only. Product variants grouped together on primary + product which share similar product attributes. It's + automatically grouped by + [primary_product_id][google.cloud.retail.v2.Product.primary_product_id] + for all the product variants. Only populated for + [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product]s. + + Note: This field is OUTPUT_ONLY for + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct]. + Do not set this field in API requests. + """ + class Type(proto.Enum): + r"""The type of this product.""" + TYPE_UNSPECIFIED = 0 + PRIMARY = 1 + VARIANT = 2 + COLLECTION = 3 + + class Availability(proto.Enum): + r"""Product availability. If this field is unspecified, the + product is assumed to be in stock. + """ + AVAILABILITY_UNSPECIFIED = 0 + IN_STOCK = 1 + OUT_OF_STOCK = 2 + PREORDER = 3 + BACKORDER = 4 + + expire_time = proto.Field( + 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, + ) + attributes = proto.MapField( + 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, + ) + available_time = proto.Field( + proto.MESSAGE, + number=18, + message=timestamp_pb2.Timestamp, + ) + availability = proto.Field( + proto.ENUM, + number=19, + enum=Availability, + ) + available_quantity = proto.Field( + 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, + ) + promotions = proto.RepeatedField( + proto.MESSAGE, + number=34, + message=common.Promotion, + ) + publish_time = proto.Field( + proto.MESSAGE, + number=33, + message=timestamp_pb2.Timestamp, + ) + retrievable_fields = proto.Field( + proto.MESSAGE, + number=30, + message=field_mask_pb2.FieldMask, + ) + variants = proto.RepeatedField( + proto.MESSAGE, + number=31, + message='Product', + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/product_service.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/product_service.py new file mode 100644 index 00000000..fb13b40c --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/product_service.py @@ -0,0 +1,654 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +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 + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'CreateProductRequest', + 'GetProductRequest', + 'UpdateProductRequest', + 'DeleteProductRequest', + 'ListProductsRequest', + 'ListProductsResponse', + 'SetInventoryRequest', + 'SetInventoryMetadata', + 'SetInventoryResponse', + 'AddFulfillmentPlacesRequest', + 'AddFulfillmentPlacesMetadata', + 'AddFulfillmentPlacesResponse', + 'RemoveFulfillmentPlacesRequest', + 'RemoveFulfillmentPlacesMetadata', + 'RemoveFulfillmentPlacesResponse', + }, +) + + +class CreateProductRequest(proto.Message): + r"""Request message for [CreateProduct][] method. + + Attributes: + parent (str): + Required. The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch``. + product (google.cloud.retail_v2.types.Product): + Required. The [Product][google.cloud.retail.v2.Product] to + create. + product_id (str): + Required. The ID to use for the + [Product][google.cloud.retail.v2.Product], which will become + the final component of the + [Product.name][google.cloud.retail.v2.Product.name]. + + If the caller does not have permission to create the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + This field must be unique among all + [Product][google.cloud.retail.v2.Product]s with the same + [parent][google.cloud.retail.v2.CreateProductRequest.parent]. + Otherwise, an ALREADY_EXISTS error is returned. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + 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, + ) + + +class GetProductRequest(proto.Message): + r"""Request message for [GetProduct][] method. + + Attributes: + name (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. + + If the requested [Product][google.cloud.retail.v2.Product] + does not exist, a NOT_FOUND error is returned. + """ + + name = proto.Field( + proto.STRING, + number=1, + ) + + +class UpdateProductRequest(proto.Message): + r"""Request message for [UpdateProduct][] method. + + Attributes: + product (google.cloud.retail_v2.types.Product): + Required. The product to update/create. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Product][google.cloud.retail.v2.Product] to update + does not exist and + [allow_missing][google.cloud.retail.v2.UpdateProductRequest.allow_missing] + is not set, a NOT_FOUND error is returned. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [Product][google.cloud.retail.v2.Product] to update. The + immutable and output only fields are NOT supported. If not + set, all supported fields (the fields that are neither + immutable nor output only) are updated. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + allow_missing (bool): + If set to true, and the + [Product][google.cloud.retail.v2.Product] is not found, a + new [Product][google.cloud.retail.v2.Product] will be + created. In this situation, ``update_mask`` is ignored. + """ + + product = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_product.Product, + ) + update_mask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + allow_missing = proto.Field( + proto.BOOL, + number=3, + ) + + +class DeleteProductRequest(proto.Message): + r"""Request message for [DeleteProduct][] method. + + Attributes: + name (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 delete the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Product][google.cloud.retail.v2.Product] to delete + does not exist, a NOT_FOUND error is returned. + + The [Product][google.cloud.retail.v2.Product] to delete can + neither be a + [Product.Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION] + [Product][google.cloud.retail.v2.Product] member nor a + [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product] with more than one + [variants][google.cloud.retail.v2.Product.Type.VARIANT]. + Otherwise, an INVALID_ARGUMENT error is returned. + + All inventory information for the named + [Product][google.cloud.retail.v2.Product] will be deleted. + """ + + name = proto.Field( + proto.STRING, + number=1, + ) + + +class ListProductsRequest(proto.Message): + r"""Request message for + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + method. + + Attributes: + parent (str): + Required. The parent branch resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/0``. + Use ``default_branch`` as the branch ID, to list products + under the default branch. + + If the caller does not have permission to list + [Product][google.cloud.retail.v2.Product]s under this + branch, regardless of whether or not this branch exists, a + PERMISSION_DENIED error is returned. + page_size (int): + Maximum number of [Product][google.cloud.retail.v2.Product]s + to return. If unspecified, defaults to 100. The maximum + allowed value is 1000. Values above 1000 will be coerced to + 1000. + + If this field is negative, an INVALID_ARGUMENT error is + returned. + page_token (str): + A page token + [ListProductsResponse.next_page_token][google.cloud.retail.v2.ListProductsResponse.next_page_token], + received from a previous + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + call. Provide this to retrieve the subsequent page. + + When paginating, all other parameters provided to + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + must match the call that provided the page token. Otherwise, + an INVALID_ARGUMENT error is returned. + filter (str): + A filter to apply on the list results. Supported features: + + - List all the products under the parent branch if + [filter][google.cloud.retail.v2.ListProductsRequest.filter] + is unset. + - List + [Product.Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product]s sharing the + same + [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product]. For example: + ``primary_product_id = "some_product_id"`` + - List [Product][google.cloud.retail.v2.Product]s bundled + in a + [Product.Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION] + [Product][google.cloud.retail.v2.Product]. For example: + ``collection_product_id = "some_product_id"`` + - List [Product][google.cloud.retail.v2.Product]s with a + partibular type. For example: ``type = "PRIMARY"`` + ``type = "VARIANT"`` ``type = "COLLECTION"`` + + If the field is unrecognizable, an INVALID_ARGUMENT error is + returned. + + If the specified + [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product] or + [Product.Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION] + [Product][google.cloud.retail.v2.Product] does not exist, a + NOT_FOUND error is returned. + read_mask (google.protobuf.field_mask_pb2.FieldMask): + The fields of [Product][google.cloud.retail.v2.Product] to + return in the responses. If not set or empty, the following + fields are returned: + + - [Product.name][google.cloud.retail.v2.Product.name] + - [Product.id][google.cloud.retail.v2.Product.id] + - [Product.title][google.cloud.retail.v2.Product.title] + - [Product.uri][google.cloud.retail.v2.Product.uri] + - [Product.images][google.cloud.retail.v2.Product.images] + - [Product.price_info][google.cloud.retail.v2.Product.price_info] + - [Product.brands][google.cloud.retail.v2.Product.brands] + + If "*" is provided, all fields are returned. + [Product.name][google.cloud.retail.v2.Product.name] is + always returned no matter what mask is set. + + If an unsupported or unknown field is provided, 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, + ) + filter = proto.Field( + proto.STRING, + number=4, + ) + read_mask = proto.Field( + proto.MESSAGE, + number=5, + message=field_mask_pb2.FieldMask, + ) + + +class ListProductsResponse(proto.Message): + r"""Response message for + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + method. + + Attributes: + products (Sequence[google.cloud.retail_v2.types.Product]): + The [Product][google.cloud.retail.v2.Product]s. + next_page_token (str): + A token that can be sent as + [ListProductsRequest.page_token][google.cloud.retail.v2.ListProductsRequest.page_token] + to retrieve the next page. If this field is omitted, there + are no subsequent pages. + """ + + @property + def raw_page(self): + return self + + products = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcr_product.Product, + ) + next_page_token = proto.Field( + proto.STRING, + number=2, + ) + + +class SetInventoryRequest(proto.Message): + r"""Request message for [SetInventory][] method. + + Attributes: + inventory (google.cloud.retail_v2.types.Product): + Required. The inventory information to update. The allowable + fields to update are: + + - [Product.price_info][google.cloud.retail.v2.Product.price_info] + - [Product.availability][google.cloud.retail.v2.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] + The updated inventory fields must be specified in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask]. + + If [SetInventoryRequest.inventory.name][] is empty or + invalid, an INVALID_ARGUMENT error is returned. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2.Product] named in + [Product.name][google.cloud.retail.v2.Product.name], + regardless of whether or not it exists, a PERMISSION_DENIED + error is returned. + + If the [Product][google.cloud.retail.v2.Product] to update + does not have existing inventory information, the provided + inventory information will be inserted. + + If the [Product][google.cloud.retail.v2.Product] to update + has existing inventory information, the provided inventory + information will be merged while respecting the last update + time for each inventory field, using the provided or default + value for + [SetInventoryRequest.set_time][google.cloud.retail.v2.SetInventoryRequest.set_time]. + + The last update time is recorded for the following inventory + fields: + + - [Product.price_info][google.cloud.retail.v2.Product.price_info] + - [Product.availability][google.cloud.retail.v2.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] + + If a full overwrite of inventory information while ignoring + timestamps is needed, [UpdateProduct][] should be invoked + 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. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned and the entire update + will be ignored. + set_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the request is issued, used to + prevent out-of-order updates on inventory fields + with the last update time recorded. 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] with name + [Product.name][google.cloud.retail.v2.Product.name] is not + found, the inventory update will still be processed and + retained for at most 1 day until 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. + """ + + 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): + r"""Metadata related to the progress of the SetInventory operation. + Currently empty because there is no meaningful metadata populated + from the [SetInventory][] method. + + """ + + +class SetInventoryResponse(proto.Message): + r"""Response of the SetInventoryRequest. Currently empty because there + is no meaningful response populated from the [SetInventory][] + method. + + """ + + +class AddFulfillmentPlacesRequest(proto.Message): + r"""Request message for [AddFulfillmentPlaces][] 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. + type_ (str): + Required. The fulfillment type, including commonly used + types (such as pickup in store and same day delivery), and + custom types. + + 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. + + This field directly corresponds to + [Product.fulfillment_info.type][]. + place_ids (Sequence[str]): + Required. The IDs for this + [type][google.cloud.retail.v2.AddFulfillmentPlacesRequest.type], + such as the store IDs for "pickup-in-store" or the region + IDs for "same-day-delivery" to be added for this + [type][google.cloud.retail.v2.AddFulfillmentPlacesRequest.type]. + Duplicate IDs will be automatically ignored. + + At least 1 value is required, and a maximum of 2000 values + are allowed. Each value must be a string with a length limit + of 10 characters, matching the pattern ``[a-zA-Z0-9_-]+``, + such as "store1" or "REGION-2". Otherwise, an + INVALID_ARGUMENT error is returned. + + If the total number of place IDs exceeds 2000 for this + [type][google.cloud.retail.v2.AddFulfillmentPlacesRequest.type] + after adding, then the update will be rejected. + add_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the fulfillment updates are + issued, used to prevent out-of-order updates on + fulfillment information. 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 + fulfillment information 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, + ) + 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): + r"""Metadata related to the progress of the AddFulfillmentPlaces + operation. Currently empty because there is no meaningful metadata + populated from the [AddFulfillmentPlaces][] method. + + """ + + +class AddFulfillmentPlacesResponse(proto.Message): + r"""Response of the AddFulfillmentPlacesRequest. Currently empty because + there is no meaningful response populated from the + [AddFulfillmentPlaces][] method. + + """ + + +class RemoveFulfillmentPlacesRequest(proto.Message): + r"""Request message for [RemoveFulfillmentPlaces][] 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. + type_ (str): + Required. The fulfillment type, including commonly used + types (such as pickup in store and same day delivery), and + custom types. + + 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. + + This field directly corresponds to + [Product.fulfillment_info.type][]. + place_ids (Sequence[str]): + Required. The IDs for this + [type][google.cloud.retail.v2.RemoveFulfillmentPlacesRequest.type], + such as the store IDs for "pickup-in-store" or the region + IDs for "same-day-delivery", to be removed for this + [type][google.cloud.retail.v2.RemoveFulfillmentPlacesRequest.type]. + + At least 1 value is required, and a maximum of 2000 values + are allowed. Each value must be a string with a length limit + of 10 characters, matching the pattern ``[a-zA-Z0-9_-]+``, + such as "store1" or "REGION-2". Otherwise, an + INVALID_ARGUMENT error is returned. + remove_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the fulfillment updates are + issued, used to prevent out-of-order updates on + fulfillment information. 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 + fulfillment information 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, + ) + 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): + r"""Metadata related to the progress of the RemoveFulfillmentPlaces + operation. Currently empty because there is no meaningful metadata + populated from the [RemoveFulfillmentPlaces][] method. + + """ + + +class RemoveFulfillmentPlacesResponse(proto.Message): + r"""Response of the RemoveFulfillmentPlacesRequest. Currently empty + because there is no meaningful response populated from the + [RemoveFulfillmentPlaces][] method. + + """ + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/purge_config.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/purge_config.py new file mode 100644 index 00000000..6c88638c --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/purge_config.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'PurgeMetadata', + 'PurgeUserEventsRequest', + 'PurgeUserEventsResponse', + }, +) + + +class PurgeMetadata(proto.Message): + r"""Metadata related to the progress of the Purge operation. + This will be returned by the + google.longrunning.Operation.metadata field. + + """ + + +class PurgeUserEventsRequest(proto.Message): + r"""Request message for PurgeUserEvents method. + + Attributes: + parent (str): + Required. The resource name of the catalog under which the + events are created. The format is + ``projects/${projectId}/locations/global/catalogs/${catalogId}`` + filter (str): + Required. The filter string to specify the events to be + deleted with a length limit of 5,000 characters. Empty + string filter is not allowed. The eligible fields for + filtering are: + + - ``eventType``: Double quoted + [UserEvent.event_type][google.cloud.retail.v2.UserEvent.event_type] + string. + - ``eventTime``: in ISO 8601 "zulu" format. + - ``visitorId``: Double quoted string. Specifying this will + delete all events associated with a visitor. + - ``userId``: Double quoted string. Specifying this will + delete all events associated with a user. + + Examples: + + - Deleting all events in a time range: + ``eventTime > "2012-04-23T18:25:43.511Z" eventTime < "2012-04-23T18:30:43.511Z"`` + - Deleting specific eventType in time range: + ``eventTime > "2012-04-23T18:25:43.511Z" eventType = "detail-page-view"`` + - Deleting all events for a specific visitor: + ``visitorId = "visitor1024"`` + + The filtering fields are assumed to have an implicit AND. + force (bool): + Actually perform the purge. If ``force`` is set to false, + the method will return the expected purge count without + 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, + ) + + +class PurgeUserEventsResponse(proto.Message): + r"""Response of the PurgeUserEventsRequest. If the long running + operation is successfully done, then this message is returned by + the google.longrunning.Operations.response field. + + Attributes: + purged_events_count (int): + The total count of events purged as a result + of the operation. + """ + + purged_events_count = proto.Field( + proto.INT64, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/search_service.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/search_service.py new file mode 100644 index 00000000..7e2664f0 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/search_service.py @@ -0,0 +1,1001 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +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 struct_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'SearchRequest', + 'SearchResponse', + }, +) + + +class SearchRequest(proto.Message): + r"""Request message for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + method. + + Attributes: + placement (str): + Required. The resource name of the search engine placement, + such as + ``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. + branch (str): + The branch resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/0``. + + Use "default_branch" as the branch ID or leave this field + empty, to search products under the default branch. + query (str): + Raw search query. + visitor_id (str): + Required. 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. + user_info (google.cloud.retail_v2.types.UserInfo): + User information. + page_size (int): + Maximum number of [Product][google.cloud.retail.v2.Product]s + to return. If unspecified, defaults to a reasonable value. + The maximum allowed value is 120. Values above 120 will be + coerced to 120. + + If this field is negative, an INVALID_ARGUMENT is returned. + page_token (str): + A page token + [SearchResponse.next_page_token][google.cloud.retail.v2.SearchResponse.next_page_token], + received from a previous + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + call. Provide this to retrieve the subsequent page. + + When paginating, all other parameters provided to + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + must match the call that provided the page token. Otherwise, + an INVALID_ARGUMENT error is returned. + offset (int): + A 0-indexed integer that specifies the current offset (that + is, starting result location, amongst the + [Product][google.cloud.retail.v2.Product]s deemed by the API + as relevant) in search results. This field is only + considered if + [page_token][google.cloud.retail.v2.SearchRequest.page_token] + is unset. + + If this field is negative, an INVALID_ARGUMENT is returned. + filter (str): + The filter syntax consists of an expression language for + constructing a predicate from one or more fields of the + products being filtered. Filter expression is + case-sensitive. See more details at this `user + guide `__. + + If this field is unrecognizable, an INVALID_ARGUMENT is + returned. + canonical_filter (str): + 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 + with + [SearchRequest.canonical_filter][google.cloud.retail.v2.SearchRequest.canonical_filter] + will be returned as a supplement of the original query. This + field is strongly recommended to achieve high search + quality. + + See + [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter] + for more details about filter syntax. + order_by (str): + The order in which products are returned. Products can be + ordered by a field in an + [Product][google.cloud.retail.v2.Product] object. Leave it + unset if ordered by relevance. OrderBy expression is + case-sensitive. See more details at this `user + guide `__. + + If this field is unrecognizable, an INVALID_ARGUMENT is + returned. + facet_specs (Sequence[google.cloud.retail_v2.types.SearchRequest.FacetSpec]): + Facet specifications for faceted search. If empty, no facets + are returned. + + A maximum of 100 values are allowed. Otherwise, an + INVALID_ARGUMENT error is returned. + dynamic_facet_spec (google.cloud.retail_v2.types.SearchRequest.DynamicFacetSpec): + 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 + guide `__. + + Notice that if both [ServingConfig.boost_control_ids][] and + [SearchRequest.boost_spec] are set, the boost conditions + from both places are evaluated. If a search request matches + multiple boost conditions, the final boost score is equal to + the sum of the boost scores from all matched boost + conditions. + query_expansion_spec (google.cloud.retail_v2.types.SearchRequest.QueryExpansionSpec): + The query expansion specification that specifies the + conditions under which query expansion will occur. See more + details at this `user + guide `__. + 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 + [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. + + For + [FulfillmentInfo][google.cloud.retail.v2.FulfillmentInfo], a + fulfillment type and a fulfillment ID must be provided in + the format of "fulfillmentType.fulfillmentId". E.g., in + "pickupInStore.store123", "pickupInStore" is fulfillment + type and "store123" is the store ID. + + Supported keys are: + + - colorFamilies + - price + - originalPrice + - discount + - variantId + - inventory(place_id,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 + [Product.attributes][google.cloud.retail.v2.Product.attributes] + map. + - pickupInStore.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] + "pickup-in-store". + - shipToStore.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] + "ship-to-store". + - sameDayDelivery.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] + "same-day-delivery". + - nextDayDelivery.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] + "next-day-delivery". + - customFulfillment1.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] + "custom-type-1". + - customFulfillment2.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] + "custom-type-2". + - customFulfillment3.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] + "custom-type-3". + - customFulfillment4.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] + "custom-type-4". + - customFulfillment5.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] + "custom-type-5". + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + page_categories (Sequence[str]): + The categories associated with a category page. Required for + category navigation queries to achieve good search quality. + The format should be the same as + [UserEvent.page_categories][google.cloud.retail.v2.UserEvent.page_categories]; + + To represent full path of category, use '>' sign to separate + different hierarchies. If '>' is part of the category name, + please replace it with other character(s). + + Category pages include special pages such as sales or + promotions. For instance, a special sale page may have the + category hierarchy: "pageCategories" : ["Sales > 2017 Black + Friday Deals"]. + search_mode (google.cloud.retail_v2.types.SearchRequest.SearchMode): + The search mode of the search request. If not + specified, a single search request triggers both + product search and faceted search. + """ + class SearchMode(proto.Enum): + r"""The search mode of each search request.""" + SEARCH_MODE_UNSPECIFIED = 0 + PRODUCT_SEARCH_ONLY = 1 + FACETED_SEARCH_ONLY = 2 + + class FacetSpec(proto.Message): + r"""A facet specification to perform faceted search. + + Attributes: + facet_key (google.cloud.retail_v2.types.SearchRequest.FacetSpec.FacetKey): + Required. The facet key specification. + limit (int): + Maximum of facet values that should be returned for this + facet. If unspecified, defaults to 20. The maximum allowed + value is 300. Values above 300 will be coerced to 300. + + If this field is negative, an INVALID_ARGUMENT is returned. + excluded_filter_keys (Sequence[str]): + List of keys to exclude when faceting. + + By default, + [FacetKey.key][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key] + is not excluded from the filter unless it is listed in this + field. + + For example, suppose there are 100 products with color facet + "Red" and 200 products with color facet "Blue". A query + containing the filter "colorFamilies:ANY("Red")" and have + "colorFamilies" as + [FacetKey.key][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key] + will by default return the "Red" with count 100. + + If this field contains "colorFamilies", then the query + returns both the "Red" with count 100 and "Blue" with count + 200, because the "colorFamilies" key is now excluded from + the filter. + + A maximum of 100 values are allowed. Otherwise, an + INVALID_ARGUMENT error is returned. + enable_dynamic_position (bool): + Enables dynamic position for this facet. If set to true, the + position of this facet among all facets in the response is + determined by Google Retail Search. It will be ordered + together with dynamic facets if dynamic facets is enabled. + If set to false, the position of this facet in the response + will be the same as in the request, and it will be ranked + before the facets with dynamic position enable and all + dynamic facets. + + For example, you may always want to have rating facet + returned in the response, but it's not necessarily to always + display the rating facet at the top. In that case, you can + set enable_dynamic_position to true so that the position of + rating facet in response will be determined by Google Retail + Search. + + Another example, assuming you have the following facets in + the request: + + - "rating", enable_dynamic_position = true + + - "price", enable_dynamic_position = false + + - "brands", enable_dynamic_position = false + + And also you have a dynamic facets enable, which will + generate a facet 'gender'. Then the final order of the + facets in the response can be ("price", "brands", "rating", + "gender") or ("price", "brands", "gender", "rating") depends + on how Google Retail Search orders "gender" and "rating" + facets. However, notice that "price" and "brands" will + always be ranked at 1st and 2nd position since their + enable_dynamic_position are false. + """ + + class FacetKey(proto.Message): + r"""Specifies how a facet is computed. + + Attributes: + key (str): + Required. Supported textual and numerical facet keys in + [Product][google.cloud.retail.v2.Product] object, over which + the facet values are computed. Facet key is case-sensitive. + + Allowed facet keys when + [FacetKey.query][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.query] + is not specified: + + - textual_field = + + - "brands" + - "categories" + - "genders" + - "ageGroups" + - "availability" + - "colorFamilies" + - "colors" + - "sizes" + - "materials" + - "patterns" + - "conditions" + - "attributes.key" + - "pickupInStore" + - "shipToStore" + - "sameDayDelivery" + - "nextDayDelivery" + - "customFulfillment1" + - "customFulfillment2" + - "customFulfillment3" + - "customFulfillment4" + - "customFulfillment5" + - "inventory(place_id,attributes.key)" + + - numerical_field = + + - "price" + - "discount" + - "rating" + - "ratingCount" + - "attributes.key" + - "inventory(place_id,price)" + - "inventory(place_id,attributes.key)". + intervals (Sequence[google.cloud.retail_v2.types.Interval]): + Set only if values should be bucketized into + intervals. Must be set for facets with numerical + values. Must not be set for facet with text + values. Maximum number of intervals is 30. + restricted_values (Sequence[str]): + Only get facet for the given restricted values. For example, + when using "pickupInStore" as key and set restricted values + to ["store123", "store456"], only facets for "store123" and + "store456" are returned. Only supported on textual fields + and fulfillments. Maximum is 20. + + Must be set for the fulfillment facet keys: + + - pickupInStore + + - shipToStore + + - sameDayDelivery + + - nextDayDelivery + + - customFulfillment1 + + - customFulfillment2 + + - customFulfillment3 + + - customFulfillment4 + + - customFulfillment5 + prefixes (Sequence[str]): + Only get facet values that start with the + given string prefix. For example, suppose + "categories" has three values "Women > Shoe", + "Women > Dress" and "Men > Shoe". If set + "prefixes" to "Women", the "categories" facet + will give only "Women > Shoe" and "Women > + Dress". Only supported on textual fields. + Maximum is 10. + contains (Sequence[str]): + Only get facet values that contains the given + strings. For example, suppose "categories" has + three values "Women > Shoe", "Women > Dress" and + "Men > Shoe". If set "contains" to "Shoe", the + "categories" facet will give only "Women > Shoe" + and "Men > Shoe". Only supported on textual + fields. Maximum is 10. + order_by (str): + The order in which [Facet.values][] are returned. + + Allowed values are: + + - "count desc", which means order by + [Facet.FacetValue.count][] descending. + + - "value desc", which means order by + [Facet.FacetValue.value][] descending. Only applies to + textual facets. + + If not set, textual values are sorted in `natural + order `__; + numerical intervals are sorted in the order given by + [FacetSpec.FacetKey.intervals][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.intervals]; + [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + are sorted in the order given by + [FacetSpec.FacetKey.restricted_values][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.restricted_values]. + query (str): + The query that is used to compute facet for the given facet + key. When provided, it will override the default behavior of + facet computation. The query syntax is the same as a filter + expression. See + [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter] + for detail syntax and limitations. Notice that there is no + limitation on + [FacetKey.key][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key] + when query is specified. + + In the response, [FacetValue.value][] will be always "1" and + [FacetValue.count][] will be the number of results that + matches the query. + + For example, you can set a customized facet for + "shipToStore", where + [FacetKey.key][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key] + is "customizedShipToStore", and + [FacetKey.query][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.query] + is "availability: ANY("IN_STOCK") AND shipToStore: + ANY("123")". Then the facet will count the products that are + both in stock and ship to store "123". + """ + + key = proto.Field( + proto.STRING, + number=1, + ) + intervals = proto.RepeatedField( + 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, + ) + + facet_key = proto.Field( + 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, + ) + + class DynamicFacetSpec(proto.Message): + r"""The specifications of dynamically generated facets. + + Attributes: + mode (google.cloud.retail_v2.types.SearchRequest.DynamicFacetSpec.Mode): + Mode of the DynamicFacet feature. Defaults to + [Mode.DISABLED][google.cloud.retail.v2.SearchRequest.DynamicFacetSpec.Mode.DISABLED] + if it's unset. + """ + class Mode(proto.Enum): + r"""Enum to control DynamicFacet mode""" + MODE_UNSPECIFIED = 0 + DISABLED = 1 + ENABLED = 2 + + mode = proto.Field( + proto.ENUM, + number=1, + enum='SearchRequest.DynamicFacetSpec.Mode', + ) + + class BoostSpec(proto.Message): + r"""Boost specification to boost certain items. + + Attributes: + condition_boost_specs (Sequence[google.cloud.retail_v2.types.SearchRequest.BoostSpec.ConditionBoostSpec]): + Condition boost specifications. If a product + matches multiple conditions in the + specifictions, boost scores from these + specifications are all applied and combined in a + non-linear way. Maximum number of specifications + is 10. + """ + + class ConditionBoostSpec(proto.Message): + r"""Boost applies to products which match a condition. + + Attributes: + condition (str): + An expression which specifies a boost condition. The syntax + and supported fields are the same as a filter expression. + See + [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter] + for detail syntax and limitations. + + Examples: + + - To boost products with product ID "product_1" or + "product_2", and color "Red" or "Blue": + + - (id: ANY("product_1", "product_2")) AND + (colorFamilies: ANY("Red","Blue")) + boost (float): + Strength of the condition boost, which should be in [-1, 1]. + Negative boost means demotion. Default is 0.0. + + Setting to 1.0 gives the item a big promotion. However, it + does not necessarily mean that the boosted item will be the + top result at all times, nor that other items will be + excluded. Results could still be shown even when none of + them matches the condition. And results that are + significantly more relevant to the search query can still + trump your heavily favored but irrelevant items. + + Setting to -1.0 gives the item a big demotion. However, + results that are deeply relevant might still be shown. The + item will have an upstream battle to get a fairly high + ranking, but it is not blocked out completely. + + Setting to 0.0 means no boost applied. The boosting + condition is ignored. + """ + + 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', + ) + + class QueryExpansionSpec(proto.Message): + r"""Specification to determine under which conditions query + expansion should occur. + + Attributes: + condition (google.cloud.retail_v2.types.SearchRequest.QueryExpansionSpec.Condition): + The condition under which query expansion should occur. + Default to + [Condition.DISABLED][google.cloud.retail.v2.SearchRequest.QueryExpansionSpec.Condition.DISABLED]. + pin_unexpanded_results (bool): + Whether to pin unexpanded results. If this + field is set to true, unexpanded products are + always at the top of the search results, + followed by the expanded results. + """ + class Condition(proto.Enum): + r"""Enum describing under which condition query expansion should + occur. + """ + CONDITION_UNSPECIFIED = 0 + DISABLED = 1 + AUTO = 3 + + condition = proto.Field( + 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, + ) + dynamic_facet_spec = proto.Field( + proto.MESSAGE, + number=21, + message=DynamicFacetSpec, + ) + boost_spec = proto.Field( + proto.MESSAGE, + number=13, + message=BoostSpec, + ) + query_expansion_spec = proto.Field( + 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, + ) + + +class SearchResponse(proto.Message): + r"""Response message for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + method. + + Attributes: + results (Sequence[google.cloud.retail_v2.types.SearchResponse.SearchResult]): + A list of matched items. The order represents + the ranking. + facets (Sequence[google.cloud.retail_v2.types.SearchResponse.Facet]): + Results of facets requested by user. + total_size (int): + The estimated total count of matched items irrespective of + pagination. The count of + [results][google.cloud.retail.v2.SearchResponse.results] + returned by pagination may be less than the + [total_size][google.cloud.retail.v2.SearchResponse.total_size] + that matches. + corrected_query (str): + If spell correction applies, the corrected + query. Otherwise, empty. + attribution_token (str): + A unique search token. This should be included in the + [UserEvent][google.cloud.retail.v2.UserEvent] logs resulting + from this search, which enables accurate attribution of + search model performance. + next_page_token (str): + A token that can be sent as + [SearchRequest.page_token][google.cloud.retail.v2.SearchRequest.page_token] + to retrieve the next page. If this field is omitted, there + are no subsequent pages. + query_expansion_info (google.cloud.retail_v2.types.SearchResponse.QueryExpansionInfo): + Query expansion information for the returned + results. + redirect_uri (str): + The URI of a customer-defined redirect page. If redirect + action is triggered, no search will be performed, and only + [redirect_uri][google.cloud.retail.v2.SearchResponse.redirect_uri] + and + [attribution_token][google.cloud.retail.v2.SearchResponse.attribution_token] + will be set in the response. + """ + + class SearchResult(proto.Message): + r"""Represents the search results. + + Attributes: + id (str): + [Product.id][google.cloud.retail.v2.Product.id] of the + searched [Product][google.cloud.retail.v2.Product]. + product (google.cloud.retail_v2.types.Product): + The product data snippet in the search response. Only + [Product.name][google.cloud.retail.v2.Product.name] is + guaranteed to be populated. + + [Product.variants][google.cloud.retail.v2.Product.variants] + contains the product variants that match the search query. + If there are multiple product variants matching the query, + top 5 most relevant product variants are returned and + ordered by relevancy. + + If relevancy can be deternmined, use + [matching_variant_fields][google.cloud.retail.v2.SearchResponse.SearchResult.matching_variant_fields] + to look up matched product variants fields. If relevancy + cannot be determined, e.g. when searching "shoe" all + products in a shoe product can be a match, 5 product + variants are returned but order is meaningless. + matching_variant_count (int): + The count of matched + [variant][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product]s. + matching_variant_fields (Sequence[google.cloud.retail_v2.types.SearchResponse.SearchResult.MatchingVariantFieldsEntry]): + If a [variant][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product] matches the search + query, this map indicates which + [Product][google.cloud.retail.v2.Product] fields are + matched. The key is the + [Product.name][google.cloud.retail.v2.Product.name], the + value is a field mask of the matched + [Product][google.cloud.retail.v2.Product] fields. If matched + attributes cannot be determined, this map will be empty. + + For example, a key "sku1" with field mask + "products.color_info" indicates there is a match between + "sku1" [ColorInfo][google.cloud.retail.v2.ColorInfo] and the + query. + variant_rollup_values (Sequence[google.cloud.retail_v2.types.SearchResponse.SearchResult.VariantRollupValuesEntry]): + The rollup matching + [variant][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product] attributes. The + key is one of the + [SearchRequest.variant_rollup_keys][google.cloud.retail.v2.SearchRequest.variant_rollup_keys]. + The values are the merged and de-duplicated + [Product][google.cloud.retail.v2.Product] attributes. Notice + that the rollup values are respect filter. For example, when + filtering by "colorFamilies:ANY("red")" and rollup + "colorFamilies", only "red" is returned. + + For textual and numerical attributes, the rollup values is a + list of string or double values with type + [google.protobuf.ListValue][google.protobuf.ListValue]. For + example, if there are two variants with colors "red" and + "blue", the rollup values are + + :: + + { key: "colorFamilies" + value { + list_value { + values { string_value: "red" } + values { string_value: "blue" } + } + } + } + + For + [FulfillmentInfo][google.cloud.retail.v2.FulfillmentInfo], + the rollup values is a double value with type + [google.protobuf.Value][google.protobuf.Value]. For example, + ``{key: "pickupInStore.store1" value { number_value: 10 }}`` + means a there are 10 variants in this product are available + 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, + ) + matching_variant_fields = proto.MapField( + 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, + ) + + class Facet(proto.Message): + r"""A facet result. + + Attributes: + key (str): + The key for this facet. E.g., "colorFamilies" + or "price" or "attributes.attr1". + values (Sequence[google.cloud.retail_v2.types.SearchResponse.Facet.FacetValue]): + The facet values for this field. + dynamic_facet (bool): + Whether the facet is dynamically generated. + """ + + class FacetValue(proto.Message): + r"""A facet value which contains value names and their count. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + value (str): + Text value of a facet, such as "Black" for + facet "colorFamilies". + + This field is a member of `oneof`_ ``facet_value``. + interval (google.cloud.retail_v2.types.Interval): + Interval value for a facet, such as [10, 20) for facet + "price". + + This field is a member of `oneof`_ ``facet_value``. + count (int): + Number of items that have this 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, + ) + count = proto.Field( + proto.INT64, + number=3, + ) + + key = proto.Field( + proto.STRING, + number=1, + ) + values = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='SearchResponse.Facet.FacetValue', + ) + dynamic_facet = proto.Field( + proto.BOOL, + number=3, + ) + + class QueryExpansionInfo(proto.Message): + r"""Information describing query expansion including whether + expansion has occurred. + + Attributes: + expanded_query (bool): + Bool describing whether query expansion has + occurred. + pinned_result_count (int): + Number of pinned results. This field will only be set when + expansion happens and + [SearchRequest.QueryExpansionSpec.pin_unexpanded_results][google.cloud.retail.v2.SearchRequest.QueryExpansionSpec.pin_unexpanded_results] + is set to true. + """ + + 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, + ) + query_expansion_info = proto.Field( + proto.MESSAGE, + number=7, + message=QueryExpansionInfo, + ) + redirect_uri = proto.Field( + proto.STRING, + number=10, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/user_event.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/user_event.py new file mode 100644 index 00000000..8d9faa33 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/user_event.py @@ -0,0 +1,492 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +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 timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'UserEvent', + 'ProductDetail', + 'CompletionDetail', + 'PurchaseTransaction', + }, +) + + +class UserEvent(proto.Message): + r"""UserEvent captures all metadata information Retail API needs + to know about how end users interact with customers' website. + + Attributes: + event_type (str): + Required. User event type. Allowed values are: + + - ``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. + - ``promotion-not-offered``: Promotion is not offered to a + user. + - ``purchase-complete``: User finishing a purchase. + - ``search``: Product search. + - ``shopping-cart-page-view``: User viewing a shopping + cart. + visitor_id (str): + Required. 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 log in/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. + + The field should not contain PII or user-data. We recommend + to use Google Analystics `Client + ID `__ + for this field. + session_id (str): + A unique identifier for tracking a visitor session with a + length limit of 128 bytes. A session is an aggregation of an + end user behavior in a time span. + + A general guideline to populate the sesion_id: + + 1. If user has no activity for 30 min, a new session_id + should be assigned. + 2. The session_id should be unique across users, suggest use + uuid or add visitor_id as prefix. + event_time (google.protobuf.timestamp_pb2.Timestamp): + Only required for + [UserEventService.ImportUserEvents][google.cloud.retail.v2.UserEventService.ImportUserEvents] + method. Timestamp of when the user event happened. + experiment_ids (Sequence[str]): + A list of identifiers for the independent + experiment groups this user event belongs to. + This is used to distinguish between user events + associated with different experiment setups + (e.g. using Retail API, using different + recommendation models). + attribution_token (str): + Highly recommended for user events that are the result of + [PredictionService.Predict][google.cloud.retail.v2.PredictionService.Predict]. + This field enables accurate attribution of recommendation + model performance. + + The value must be a valid + [PredictResponse.attribution_token][google.cloud.retail.v2.PredictResponse.attribution_token] + for user events that are the result of + [PredictionService.Predict][google.cloud.retail.v2.PredictionService.Predict]. + The value must be a valid + [SearchResponse.attribution_token][google.cloud.retail.v2.SearchResponse.attribution_token] + for user events that are the result of + [SearchService.Search][google.cloud.retail.v2.SearchService.Search]. + + This token enables us to accurately attribute page view or + purchase back to the event and the particular predict + response containing this clicked/purchased product. If user + clicks on product K in the recommendation results, pass + [PredictResponse.attribution_token][google.cloud.retail.v2.PredictResponse.attribution_token] + as a URL parameter to product K's page. When recording + events on product K's page, log the + [PredictResponse.attribution_token][google.cloud.retail.v2.PredictResponse.attribution_token] + to this field. + product_details (Sequence[google.cloud.retail_v2.types.ProductDetail]): + The main product details related to the event. + + This field is required for the following event types: + + - ``add-to-cart`` + - ``detail-page-view`` + - ``purchase-complete`` + + In a ``search`` event, this field represents the products + returned to the end user on the current page (the end user + may have not finished browsing the whole page yet). When a + new page is returned to the end user, after + pagination/filtering/ordering even for the same query, a new + ``search`` event with different + [product_details][google.cloud.retail.v2.UserEvent.product_details] + 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. + + 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. + 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. + 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 + cart before purchase. + + This can only be set for ``add-to-cart``, + ``purchase-complete``, or ``shopping-cart-page-view`` + events. + purchase_transaction (google.cloud.retail_v2.types.PurchaseTransaction): + A transaction represents the entire purchase transaction. + + Required for ``purchase-complete`` events. Other event types + should not set this field. Otherwise, an INVALID_ARGUMENT + error is returned. + search_query (str): + The user's search query. + + See + [SearchRequest.query][google.cloud.retail.v2.SearchRequest.query] + for definition. + + The value must be a UTF-8 encoded string with a length limit + of 5,000 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + At least one of + [search_query][google.cloud.retail.v2.UserEvent.search_query] + or + [page_categories][google.cloud.retail.v2.UserEvent.page_categories] + is required for ``search`` events. Other event types should + not set this field. Otherwise, an INVALID_ARGUMENT error is + returned. + filter (str): + The filter syntax consists of an expression language for + constructing a predicate from one or more fields of the + products being filtered. + + See + [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter] + for definition and syntax. + + The value must be a UTF-8 encoded string with a length limit + of 1,000 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + order_by (str): + The order in which products are returned. + + See + [SearchRequest.order_by][google.cloud.retail.v2.SearchRequest.order_by] + for definition and syntax. + + The value must be a UTF-8 encoded string with a length limit + of 1,000 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + This can only be set for ``search`` events. Other event + types should not set this field. Otherwise, an + INVALID_ARGUMENT error is returned. + offset (int): + An integer that specifies the current offset for pagination + (the 0-indexed starting location, amongst the products + deemed by the API as relevant). + + See + [SearchRequest.offset][google.cloud.retail.v2.SearchRequest.offset] + for definition. + + If this field is negative, an INVALID_ARGUMENT is returned. + + This can only be set for ``search`` events. Other event + types should not set this field. Otherwise, an + INVALID_ARGUMENT error is returned. + page_categories (Sequence[str]): + The categories associated with a category page. + + To represent full path of category, use '>' sign to separate + different hierarchies. If '>' is part of the category name, + please replace it with other character(s). + + Category pages include special pages such as sales or + promotions. For instance, a special sale page may have the + category hierarchy: "pageCategories" : ["Sales > 2017 Black + Friday Deals"]. + + Required for ``category-page-view`` events. At least one of + [search_query][google.cloud.retail.v2.UserEvent.search_query] + or + [page_categories][google.cloud.retail.v2.UserEvent.page_categories] + is required for ``search`` events. Other event types should + not set this field. Otherwise, an INVALID_ARGUMENT error is + returned. + user_info (google.cloud.retail_v2.types.UserInfo): + User information. + uri (str): + Complete URL (window.location.href) of the + user's current page. + When using the client side event reporting with + JavaScript pixel and Google Tag Manager, this + value is filled in automatically. Maximum length + 5,000 characters. + referrer_uri (str): + The referrer URL of the current page. + When using the client side event reporting with + JavaScript pixel and Google Tag Manager, this + value is filled in automatically. + page_view_id (str): + A unique ID of a web page view. + + This should be kept the same for all user events triggered + from the same pageview. For example, an item detail page + view could trigger multiple events as the user is browsing + the page. The ``pageViewId`` property should be kept the + same for all these events so that they can be grouped + together properly. + + When using the client side event reporting with JavaScript + pixel and Google Tag Manager, this value is filled in + 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, + ) + product_details = proto.RepeatedField( + proto.MESSAGE, + number=6, + message='ProductDetail', + ) + completion_detail = proto.Field( + proto.MESSAGE, + number=22, + message='CompletionDetail', + ) + attributes = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=7, + message=common.CustomAttribute, + ) + cart_id = proto.Field( + proto.STRING, + number=8, + ) + purchase_transaction = proto.Field( + 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, + ) + + +class ProductDetail(proto.Message): + r"""Detailed product information associated with a user event. + + Attributes: + product (google.cloud.retail_v2.types.Product): + Required. [Product][google.cloud.retail.v2.Product] + information. + + Required field(s): + + - [Product.id][google.cloud.retail.v2.Product.id] + + Optional override field(s): + + - [Product.price_info][google.cloud.retail.v2.Product.price_info] + + If any supported optional fields are provided, we will treat + them as a full override when looking up product information + from the catalog. Thus, it is important to ensure that the + overriding fields are accurate and complete. + + All other product fields are ignored and instead populated + via catalog lookup after event ingestion. + quantity (google.protobuf.wrappers_pb2.Int32Value): + Quantity of the product associated with the user event. + + For example, this field will be 2 if two products are added + to the shopping cart for ``purchase-complete`` event. + Required for ``add-to-cart`` and ``purchase-complete`` event + types. + """ + + 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): + r"""Detailed completion information including completion + attribution token and clicked completion info. + + Attributes: + completion_attribution_token (str): + Completion attribution token in + [CompleteQueryResponse.attribution_token][google.cloud.retail.v2.CompleteQueryResponse.attribution_token]. + selected_suggestion (str): + End user selected + [CompleteQueryResponse.CompletionResult.suggestion][google.cloud.retail.v2.CompleteQueryResponse.CompletionResult.suggestion]. + selected_position (int): + End user selected + [CompleteQueryResponse.CompletionResult.suggestion][google.cloud.retail.v2.CompleteQueryResponse.CompletionResult.suggestion] + 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, + ) + + +class PurchaseTransaction(proto.Message): + r"""A transaction represents the entire purchase transaction. + + Attributes: + id (str): + The transaction ID with a length limit of 128 + characters. + revenue (float): + Required. Total non-zero revenue or grand + total associated with the transaction. This + value include shipping, tax, or other + adjustments to total revenue that you want to + include as part of your revenue calculations. + tax (float): + All the taxes associated with the + transaction. + cost (float): + All the costs associated with the products. These can be + manufacturing costs, shipping expenses not borne by the end + user, or any other costs, such that: + + - Profit = + [revenue][google.cloud.retail.v2.PurchaseTransaction.revenue] + - [tax][google.cloud.retail.v2.PurchaseTransaction.tax] - + [cost][google.cloud.retail.v2.PurchaseTransaction.cost] + currency_code (str): + Required. Currency code. Use three-character + 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, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/user_event_service.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/user_event_service.py new file mode 100644 index 00000000..bb0a336c --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/user_event_service.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.cloud.retail_v2.types import user_event as gcr_user_event + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'WriteUserEventRequest', + 'CollectUserEventRequest', + 'RejoinUserEventsRequest', + 'RejoinUserEventsResponse', + 'RejoinUserEventsMetadata', + }, +) + + +class WriteUserEventRequest(proto.Message): + r"""Request message for WriteUserEvent method. + + Attributes: + parent (str): + Required. The parent catalog resource name, such as + ``projects/1234/locations/global/catalogs/default_catalog``. + user_event (google.cloud.retail_v2.types.UserEvent): + 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, + ) + + +class CollectUserEventRequest(proto.Message): + r"""Request message for CollectUserEvent method. + + Attributes: + parent (str): + Required. The parent catalog name, such as + ``projects/1234/locations/global/catalogs/default_catalog``. + user_event (str): + Required. URL encoded UserEvent proto with a + length limit of 2,000,000 characters. + uri (str): + The URL including cgi-parameters but + excluding the hash fragment with a length limit + of 5,000 characters. This is often more useful + than the referer URL, because many browsers only + send the domain for 3rd party requests. + ets (int): + The event timestamp in milliseconds. This + prevents browser caching of otherwise identical + get requests. The name is abbreviated to reduce + 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, + ) + + +class RejoinUserEventsRequest(proto.Message): + r"""Request message for RejoinUserEvents method. + + Attributes: + parent (str): + Required. The parent catalog resource name, such as + ``projects/1234/locations/global/catalogs/default_catalog``. + user_event_rejoin_scope (google.cloud.retail_v2.types.RejoinUserEventsRequest.UserEventRejoinScope): + The type of the user event rejoin to define the scope and + range of the user events to be rejoined with the latest + product catalog. Defaults to + USER_EVENT_REJOIN_SCOPE_UNSPECIFIED if this field is not + set, or set to an invalid integer value. + """ + class UserEventRejoinScope(proto.Enum): + r"""The scope of user events to be rejoined with the latest product + catalog. If the rejoining aims at reducing number of unjoined + events, set UserEventRejoinScope to UNJOINED_EVENTS. If the + rejoining aims at correcting product catalog information in joined + events, set UserEventRejoinScope to JOINED_EVENTS. If all events + needs to be rejoined, set UserEventRejoinScope to + USER_EVENT_REJOIN_SCOPE_UNSPECIFIED. + """ + USER_EVENT_REJOIN_SCOPE_UNSPECIFIED = 0 + JOINED_EVENTS = 1 + UNJOINED_EVENTS = 2 + + parent = proto.Field( + proto.STRING, + number=1, + ) + user_event_rejoin_scope = proto.Field( + proto.ENUM, + number=2, + enum=UserEventRejoinScope, + ) + + +class RejoinUserEventsResponse(proto.Message): + r"""Response message for RejoinUserEvents method. + + Attributes: + rejoined_user_events_count (int): + Number of user events that were joined with + latest product catalog. + """ + + rejoined_user_events_count = proto.Field( + proto.INT64, + number=1, + ) + + +class RejoinUserEventsMetadata(proto.Message): + r"""Metadata for RejoinUserEvents method. + """ + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/mypy.ini b/owl-bot-staging/v2/mypy.ini new file mode 100644 index 00000000..4505b485 --- /dev/null +++ b/owl-bot-staging/v2/mypy.ini @@ -0,0 +1,3 @@ +[mypy] +python_version = 3.6 +namespace_packages = True diff --git a/owl-bot-staging/v2/noxfile.py b/owl-bot-staging/v2/noxfile.py new file mode 100644 index 00000000..771bbfee --- /dev/null +++ b/owl-bot-staging/v2/noxfile.py @@ -0,0 +1,132 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os +import pathlib +import shutil +import subprocess +import sys + + +import nox # type: ignore + +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() + +LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" +PACKAGE_NAME = subprocess.check_output([sys.executable, "setup.py", "--name"], encoding="utf-8") + + +nox.sessions = [ + "unit", + "cover", + "mypy", + "check_lower_bounds" + # exclude update_lower_bounds from default + "docs", +] + +@nox.session(python=['3.6', '3.7', '3.8', '3.9', '3.10']) +def unit(session): + """Run the unit test suite.""" + + session.install('coverage', 'pytest', 'pytest-cov', 'asyncmock', 'pytest-asyncio') + session.install('-e', '.') + + session.run( + 'py.test', + '--quiet', + '--cov=google/cloud/retail_v2/', + '--cov-config=.coveragerc', + '--cov-report=term', + '--cov-report=html', + os.path.join('tests', 'unit', ''.join(session.posargs)) + ) + + +@nox.session(python='3.9') +def cover(session): + """Run the final coverage report. + This outputs the coverage report aggregating coverage from the unit + test runs (not system test runs), and then erases coverage data. + """ + session.install("coverage", "pytest-cov") + session.run("coverage", "report", "--show-missing", "--fail-under=100") + + session.run("coverage", "erase") + + +@nox.session(python=['3.6', '3.7', '3.8', '3.9']) +def mypy(session): + """Run the type checker.""" + session.install('mypy', 'types-pkg_resources') + session.install('.') + session.run( + 'mypy', + '--explicit-package-bases', + 'google', + ) + + +@nox.session +def update_lower_bounds(session): + """Update lower bounds in constraints.txt to match setup.py""" + session.install('google-cloud-testutils') + session.install('.') + + session.run( + 'lower-bound-checker', + 'update', + '--package-name', + PACKAGE_NAME, + '--constraints-file', + str(LOWER_BOUND_CONSTRAINTS_FILE), + ) + + +@nox.session +def check_lower_bounds(session): + """Check lower bounds in setup.py are reflected in constraints file""" + session.install('google-cloud-testutils') + session.install('.') + + session.run( + 'lower-bound-checker', + 'check', + '--package-name', + PACKAGE_NAME, + '--constraints-file', + str(LOWER_BOUND_CONSTRAINTS_FILE), + ) + +@nox.session(python='3.9') +def docs(session): + """Build the docs for this library.""" + + session.install("-e", ".") + session.install("sphinx<3.0.0", "alabaster", "recommonmark") + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-W", # warnings as errors + "-T", # show full traceback on exception + "-N", # no colors + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) diff --git a/owl-bot-staging/v2/scripts/fixup_retail_v2_keywords.py b/owl-bot-staging/v2/scripts/fixup_retail_v2_keywords.py new file mode 100644 index 00000000..2688d8b7 --- /dev/null +++ b/owl-bot-staging/v2/scripts/fixup_retail_v2_keywords.py @@ -0,0 +1,197 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import argparse +import os +import libcst as cst +import pathlib +import sys +from typing import (Any, Callable, Dict, List, Sequence, Tuple) + + +def partition( + predicate: Callable[[Any], bool], + iterator: Sequence[Any] +) -> Tuple[List[Any], List[Any]]: + """A stable, out-of-place partition.""" + results = ([], []) + + for i in iterator: + results[int(predicate(i))].append(i) + + # Returns trueList, falseList + return results[1], results[0] + + +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', ), + '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', ), + 'delete_product': ('name', ), + 'get_default_branch': ('catalog', ), + 'get_product': ('name', ), + 'import_completion_data': ('parent', 'input_config', 'notification_pubsub_topic', ), + 'import_products': ('parent', 'input_config', 'request_id', 'errors_config', 'update_mask', 'reconciliation_mode', 'notification_pubsub_topic', ), + 'import_user_events': ('parent', 'input_config', 'errors_config', ), + 'list_catalogs': ('parent', 'page_size', 'page_token', ), + 'list_products': ('parent', 'page_size', 'page_token', 'filter', 'read_mask', ), + 'predict': ('placement', 'user_event', 'page_size', 'page_token', 'filter', 'validate_only', 'params', 'labels', ), + 'purge_user_events': ('parent', 'filter', 'force', ), + 'rejoin_user_events': ('parent', 'user_event_rejoin_scope', ), + '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', ), + 'set_inventory': ('inventory', 'set_mask', 'set_time', 'allow_missing', ), + 'update_catalog': ('catalog', 'update_mask', ), + 'update_product': ('product', 'update_mask', 'allow_missing', ), + 'write_user_event': ('parent', 'user_event', ), + } + + def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: + try: + key = original.func.attr.value + kword_params = self.METHOD_TO_PARAMS[key] + except (AttributeError, KeyError): + # Either not a method from the API or too convoluted to be sure. + return updated + + # If the existing code is valid, keyword args come after positional args. + # Therefore, all positional args must map to the first parameters. + args, kwargs = partition(lambda a: not bool(a.keyword), updated.args) + if any(k.keyword.value == "request" for k in kwargs): + # We've already fixed this file, don't fix it again. + return updated + + kwargs, ctrl_kwargs = partition( + lambda a: a.keyword.value not in self.CTRL_PARAMS, + kwargs + ) + + args, ctrl_args = args[:len(kword_params)], args[len(kword_params):] + ctrl_kwargs.extend(cst.Arg(value=a.value, keyword=cst.Name(value=ctrl)) + for a, ctrl in zip(ctrl_args, self.CTRL_PARAMS)) + + request_arg = cst.Arg( + value=cst.Dict([ + cst.DictElement( + cst.SimpleString("'{}'".format(name)), +cst.Element(value=arg.value) + ) + # Note: the args + kwargs looks silly, but keep in mind that + # the control parameters had to be stripped out, and that + # those could have been passed positionally or by keyword. + for name, arg in zip(kword_params, args + kwargs)]), + keyword=cst.Name("request") + ) + + return updated.with_changes( + args=[request_arg] + ctrl_kwargs + ) + + +def fix_files( + in_dir: pathlib.Path, + out_dir: pathlib.Path, + *, + transformer=retailCallTransformer(), +): + """Duplicate the input dir to the output dir, fixing file method calls. + + Preconditions: + * in_dir is a real directory + * out_dir is a real, empty directory + """ + pyfile_gen = ( + pathlib.Path(os.path.join(root, f)) + for root, _, files in os.walk(in_dir) + for f in files if os.path.splitext(f)[1] == ".py" + ) + + for fpath in pyfile_gen: + with open(fpath, 'r') as f: + src = f.read() + + # Parse the code and insert method call fixes. + tree = cst.parse_module(src) + updated = tree.visit(transformer) + + # Create the path and directory structure for the new file. + updated_path = out_dir.joinpath(fpath.relative_to(in_dir)) + updated_path.parent.mkdir(parents=True, exist_ok=True) + + # Generate the updated source file at the corresponding path. + with open(updated_path, 'w') as f: + f.write(updated.code) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description="""Fix up source that uses the retail client library. + +The existing sources are NOT overwritten but are copied to output_dir with changes made. + +Note: This tool operates at a best-effort level at converting positional + parameters in client method calls to keyword based parameters. + Cases where it WILL FAIL include + A) * or ** expansion in a method call. + B) Calls via function or method alias (includes free function calls) + C) Indirect or dispatched calls (e.g. the method is looked up dynamically) + + These all constitute false negatives. The tool will also detect false + positives when an API method shares a name with another method. +""") + parser.add_argument( + '-d', + '--input-directory', + required=True, + dest='input_dir', + help='the input directory to walk for python files to fix up', + ) + parser.add_argument( + '-o', + '--output-directory', + required=True, + dest='output_dir', + help='the directory to output files fixed via un-flattening', + ) + args = parser.parse_args() + input_dir = pathlib.Path(args.input_dir) + output_dir = pathlib.Path(args.output_dir) + if not input_dir.is_dir(): + print( + f"input directory '{input_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if not output_dir.is_dir(): + print( + f"output directory '{output_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if os.listdir(output_dir): + print( + f"output directory '{output_dir}' is not empty", + file=sys.stderr, + ) + sys.exit(-1) + + fix_files(input_dir, output_dir) diff --git a/owl-bot-staging/v2/setup.py b/owl-bot-staging/v2/setup.py new file mode 100644 index 00000000..baa5fefe --- /dev/null +++ b/owl-bot-staging/v2/setup.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import io +import os +import setuptools # type: ignore + +version = '0.1.0' + +package_root = os.path.abspath(os.path.dirname(__file__)) + +readme_filename = os.path.join(package_root, 'README.rst') +with io.open(readme_filename, encoding='utf-8') as readme_file: + readme = readme_file.read() + +setuptools.setup( + name='google-cloud-retail', + version=version, + long_description=readme, + packages=setuptools.PEP420PackageFinder.find(), + namespace_packages=('google', 'google.cloud'), + platforms='Posix; MacOS X; Windows', + include_package_data=True, + install_requires=( + 'google-api-core[grpc] >= 1.28.0, < 3.0.0dev', + 'libcst >= 0.2.5', + 'proto-plus >= 1.19.7', + ), + python_requires='>=3.6', + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Intended Audience :: Developers', + 'Operating System :: OS Independent', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Topic :: Internet', + 'Topic :: Software Development :: Libraries :: Python Modules', + ], + zip_safe=False, +) diff --git a/owl-bot-staging/v2/tests/__init__.py b/owl-bot-staging/v2/tests/__init__.py new file mode 100644 index 00000000..b54a5fcc --- /dev/null +++ b/owl-bot-staging/v2/tests/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/owl-bot-staging/v2/tests/unit/__init__.py b/owl-bot-staging/v2/tests/unit/__init__.py new file mode 100644 index 00000000..b54a5fcc --- /dev/null +++ b/owl-bot-staging/v2/tests/unit/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/owl-bot-staging/v2/tests/unit/gapic/__init__.py b/owl-bot-staging/v2/tests/unit/gapic/__init__.py new file mode 100644 index 00000000..b54a5fcc --- /dev/null +++ b/owl-bot-staging/v2/tests/unit/gapic/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/owl-bot-staging/v2/tests/unit/gapic/retail_v2/__init__.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/__init__.py new file mode 100644 index 00000000..b54a5fcc --- /dev/null +++ b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_catalog_service.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_catalog_service.py new file mode 100644 index 00000000..331b536a --- /dev/null +++ b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_catalog_service.py @@ -0,0 +1,2184 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os +import mock + +import grpc +from grpc.experimental import aio +import math +import pytest +from proto.marshal.rules.dates import DurationRule, TimestampRule + + +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers +from google.api_core import grpc_helpers_async +from google.api_core import path_template +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.retail_v2.services.catalog_service import CatalogServiceAsyncClient +from google.cloud.retail_v2.services.catalog_service import CatalogServiceClient +from google.cloud.retail_v2.services.catalog_service import pagers +from google.cloud.retail_v2.services.catalog_service import transports +from google.cloud.retail_v2.types import catalog +from google.cloud.retail_v2.types import catalog as gcr_catalog +from google.cloud.retail_v2.types import catalog_service +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +import google.auth + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert CatalogServiceClient._get_default_mtls_endpoint(None) is None + assert CatalogServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert CatalogServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert CatalogServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert CatalogServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert CatalogServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class", [ + CatalogServiceClient, + CatalogServiceAsyncClient, +]) +def test_catalog_service_client_from_service_account_info(client_class): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == 'retail.googleapis.com:443' + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.CatalogServiceGrpcTransport, "grpc"), + (transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +def test_catalog_service_client_service_account_always_use_jwt(transport_class, transport_name): + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize("client_class", [ + CatalogServiceClient, + CatalogServiceAsyncClient, +]) +def test_catalog_service_client_from_service_account_file(client_class): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json") + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json("dummy/file/path.json") + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == 'retail.googleapis.com:443' + + +def test_catalog_service_client_get_transport_class(): + transport = CatalogServiceClient.get_transport_class() + available_transports = [ + transports.CatalogServiceGrpcTransport, + ] + assert transport in available_transports + + transport = CatalogServiceClient.get_transport_class("grpc") + assert transport == transports.CatalogServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc"), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +@mock.patch.object(CatalogServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceClient)) +@mock.patch.object(CatalogServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceAsyncClient)) +def test_catalog_service_client_client_options(client_class, transport_class, transport_name): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(CatalogServiceClient, 'get_transport_class') as gtc: + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(CatalogServiceClient, 'get_transport_class') as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class(transport=transport_name) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError): + client = client_class(transport=transport_name) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc", "true"), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc", "false"), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), +]) +@mock.patch.object(CatalogServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceClient)) +@mock.patch.object(CatalogServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_catalog_service_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + +@pytest.mark.parametrize("client_class", [ + CatalogServiceClient, CatalogServiceAsyncClient +]) +@mock.patch.object(CatalogServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceClient)) +@mock.patch.object(CatalogServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceAsyncClient)) +def test_catalog_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc"), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +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"], + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc"), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +def test_catalog_service_client_client_options_credentials_file(client_class, transport_class, transport_name): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + +def test_catalog_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2.services.catalog_service.transports.CatalogServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = CatalogServiceClient( + client_options={'api_endpoint': 'squid.clam.whelk'} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + +@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, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.ListCatalogsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_catalogs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.ListCatalogsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListCatalogsPager) + assert response.next_page_token == 'next_page_token_value' + + +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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__') as call: + client.list_catalogs() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.ListCatalogsRequest() + + +@pytest.mark.asyncio +async def test_list_catalogs_async(transport: str = 'grpc_asyncio', request_type=catalog_service.ListCatalogsRequest): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.ListCatalogsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_catalogs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.ListCatalogsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListCatalogsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_catalogs_async_from_dict(): + await test_list_catalogs_async(request_type=dict) + + +def test_list_catalogs_field_headers(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = catalog_service.ListCatalogsRequest() + + request.parent = 'parent/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__') as call: + call.return_value = catalog_service.ListCatalogsResponse() + client.list_catalogs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent/value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_list_catalogs_field_headers_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = catalog_service.ListCatalogsRequest() + + request.parent = 'parent/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.ListCatalogsResponse()) + await client.list_catalogs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent/value', + ) in kw['metadata'] + + +def test_list_catalogs_flattened(): + 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: + # Designate an appropriate return value for the call. + 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', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + + +def test_list_catalogs_flattened_error(): + 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', + ) + + +@pytest.mark.asyncio +async def test_list_catalogs_flattened_async(): + client = CatalogServiceAsyncClient( + 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: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.ListCatalogsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.ListCatalogsResponse()) + # 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', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_list_catalogs_flattened_error_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_catalogs( + catalog_service.ListCatalogsRequest(), + parent='parent_value', + ) + + +def test_list_catalogs_pager(transport_name: str = "grpc"): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + catalog_service.ListCatalogsResponse( + 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', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_catalogs(request={}) + + assert pager._metadata == metadata + + results = [i for i in pager] + assert len(results) == 6 + assert all(isinstance(i, catalog.Catalog) + for i in results) +def test_list_catalogs_pages(transport_name: str = "grpc"): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + catalog_service.ListCatalogsResponse( + 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', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], + ), + RuntimeError, + ) + pages = list(client.list_catalogs(request={}).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.asyncio +async def test_list_catalogs_async_pager(): + client = CatalogServiceAsyncClient( + 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__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + catalog_service.ListCatalogsResponse( + 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', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_catalogs(request={},) + assert async_pager.next_page_token == 'abc' + responses = [] + async for response in async_pager: + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, catalog.Catalog) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_catalogs_async_pages(): + client = CatalogServiceAsyncClient( + 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__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + catalog_service.ListCatalogsResponse( + 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', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in (await client.list_catalogs(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.parametrize("request_type", [ + catalog_service.UpdateCatalogRequest, + dict, +]) +def test_update_catalog(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.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', + ) + response = client.update_catalog(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateCatalogRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_catalog.Catalog) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_catalog), + '__call__') as call: + client.update_catalog() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateCatalogRequest() + + +@pytest.mark.asyncio +async def test_update_catalog_async(transport: str = 'grpc_asyncio', request_type=catalog_service.UpdateCatalogRequest): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.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', + )) + response = await client.update_catalog(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateCatalogRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_catalog.Catalog) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +@pytest.mark.asyncio +async def test_update_catalog_async_from_dict(): + await test_update_catalog_async(request_type=dict) + + +def test_update_catalog_field_headers(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = catalog_service.UpdateCatalogRequest() + + request.catalog.name = 'catalog.name/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_catalog), + '__call__') as call: + call.return_value = gcr_catalog.Catalog() + client.update_catalog(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', + 'catalog.name=catalog.name/value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_catalog_field_headers_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = catalog_service.UpdateCatalogRequest() + + request.catalog.name = 'catalog.name/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_catalog), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_catalog.Catalog()) + await client.update_catalog(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', + 'catalog.name=catalog.name/value', + ) in kw['metadata'] + + +def test_update_catalog_flattened(): + 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: + # Designate an appropriate return value for the call. + call.return_value = gcr_catalog.Catalog() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_catalog( + catalog=gcr_catalog.Catalog(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].catalog + mock_val = gcr_catalog.Catalog(name='name_value') + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + + +def test_update_catalog_flattened_error(): + 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.update_catalog( + catalog_service.UpdateCatalogRequest(), + catalog=gcr_catalog.Catalog(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.asyncio +async def test_update_catalog_flattened_async(): + client = CatalogServiceAsyncClient( + 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: + # Designate an appropriate return value for the call. + call.return_value = gcr_catalog.Catalog() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_catalog.Catalog()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_catalog( + catalog=gcr_catalog.Catalog(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].catalog + mock_val = gcr_catalog.Catalog(name='name_value') + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_update_catalog_flattened_error_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_catalog( + catalog_service.UpdateCatalogRequest(), + catalog=gcr_catalog.Catalog(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.SetDefaultBranchRequest, + dict, +]) +def test_set_default_branch(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.set_default_branch(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.SetDefaultBranchRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_default_branch), + '__call__') as call: + client.set_default_branch() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.SetDefaultBranchRequest() + + +@pytest.mark.asyncio +async def test_set_default_branch_async(transport: str = 'grpc_asyncio', request_type=catalog_service.SetDefaultBranchRequest): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.set_default_branch(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.SetDefaultBranchRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_set_default_branch_async_from_dict(): + await test_set_default_branch_async(request_type=dict) + + +def test_set_default_branch_field_headers(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = catalog_service.SetDefaultBranchRequest() + + request.catalog = 'catalog/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_default_branch), + '__call__') as call: + call.return_value = None + client.set_default_branch(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', + 'catalog=catalog/value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_set_default_branch_field_headers_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = catalog_service.SetDefaultBranchRequest() + + request.catalog = 'catalog/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_default_branch), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.set_default_branch(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', + 'catalog=catalog/value', + ) in kw['metadata'] + + +def test_set_default_branch_flattened(): + 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.set_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.set_default_branch( + catalog='catalog_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].catalog + mock_val = 'catalog_value' + assert arg == mock_val + + +def test_set_default_branch_flattened_error(): + 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', + ) + + +@pytest.mark.asyncio +async def test_set_default_branch_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.set_default_branch( + catalog='catalog_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].catalog + mock_val = 'catalog_value' + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_set_default_branch_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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.set_default_branch( + catalog_service.SetDefaultBranchRequest(), + catalog='catalog_value', + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.GetDefaultBranchRequest, + dict, +]) +def test_get_default_branch(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.GetDefaultBranchResponse( + branch='branch_value', + note='note_value', + ) + response = client.get_default_branch(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetDefaultBranchRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog_service.GetDefaultBranchResponse) + assert response.branch == 'branch_value' + assert response.note == 'note_value' + + +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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_default_branch), + '__call__') as call: + client.get_default_branch() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetDefaultBranchRequest() + + +@pytest.mark.asyncio +async def test_get_default_branch_async(transport: str = 'grpc_asyncio', request_type=catalog_service.GetDefaultBranchRequest): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.GetDefaultBranchResponse( + branch='branch_value', + note='note_value', + )) + response = await client.get_default_branch(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetDefaultBranchRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog_service.GetDefaultBranchResponse) + assert response.branch == 'branch_value' + assert response.note == 'note_value' + + +@pytest.mark.asyncio +async def test_get_default_branch_async_from_dict(): + await test_get_default_branch_async(request_type=dict) + + +def test_get_default_branch_field_headers(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = catalog_service.GetDefaultBranchRequest() + + request.catalog = 'catalog/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_default_branch), + '__call__') as call: + call.return_value = catalog_service.GetDefaultBranchResponse() + client.get_default_branch(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', + 'catalog=catalog/value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_get_default_branch_field_headers_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = catalog_service.GetDefaultBranchRequest() + + request.catalog = 'catalog/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_default_branch), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.GetDefaultBranchResponse()) + await client.get_default_branch(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', + 'catalog=catalog/value', + ) in kw['metadata'] + + +def test_get_default_branch_flattened(): + 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.get_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + 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', + ) + + # 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].catalog + mock_val = 'catalog_value' + assert arg == mock_val + + +def test_get_default_branch_flattened_error(): + 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', + ) + + +@pytest.mark.asyncio +async def test_get_default_branch_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.GetDefaultBranchResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.GetDefaultBranchResponse()) + # 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', + ) + + # 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].catalog + mock_val = 'catalog_value' + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_get_default_branch_flattened_error_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_default_branch( + catalog_service.GetDefaultBranchRequest(), + catalog='catalog_value', + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CatalogServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CatalogServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CatalogServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CatalogServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = CatalogServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.CatalogServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.CatalogServiceGrpcTransport, + transports.CatalogServiceGrpcAsyncIOTransport, +]) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + +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, + ) + +def test_catalog_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.CatalogServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_catalog_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2.services.catalog_service.transports.CatalogServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.CatalogServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'list_catalogs', + 'update_catalog', + 'set_default_branch', + 'get_default_branch', + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + +def test_catalog_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('google.cloud.retail_v2.services.catalog_service.transports.CatalogServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CatalogServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with("credentials.json", + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id="octopus", + ) + + +def test_catalog_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, 'default', autospec=True) as adc, mock.patch('google.cloud.retail_v2.services.catalog_service.transports.CatalogServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CatalogServiceTransport() + adc.assert_called_once() + + +def test_catalog_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + CatalogServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CatalogServiceGrpcTransport, + transports.CatalogServiceGrpcAsyncIOTransport, + ], +) +def test_catalog_service_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=( 'https://www.googleapis.com/auth/cloud-platform',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.CatalogServiceGrpcTransport, grpc_helpers), + (transports.CatalogServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_catalog_service_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class( + quota_project_id="octopus", + scopes=["1", "2"] + ) + + create_channel.assert_called_with( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.CatalogServiceGrpcTransport, transports.CatalogServiceGrpcAsyncIOTransport]) +def test_catalog_service_grpc_transport_client_cert_source_for_mtls( + transport_class +): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, + private_key=expected_key + ) + + +def test_catalog_service_host_no_port(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + ) + assert client.transport._host == 'retail.googleapis.com:443' + + +def test_catalog_service_host_with_port(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + ) + assert client.transport._host == 'retail.googleapis.com:8000' + +def test_catalog_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.CatalogServiceGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_catalog_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.CatalogServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.CatalogServiceGrpcTransport, transports.CatalogServiceGrpcAsyncIOTransport]) +def test_catalog_service_transport_channel_mtls_with_client_cert_source( + transport_class +): + with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.CatalogServiceGrpcTransport, transports.CatalogServiceGrpcAsyncIOTransport]) +def test_catalog_service_transport_channel_mtls_with_adc( + transport_class +): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_branch_path(): + project = "squid" + location = "clam" + catalog = "whelk" + branch = "octopus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) + actual = CatalogServiceClient.branch_path(project, location, catalog, branch) + assert expected == actual + + +def test_parse_branch_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "catalog": "cuttlefish", + "branch": "mussel", + } + path = CatalogServiceClient.branch_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_branch_path(path) + assert expected == actual + +def test_catalog_path(): + project = "winkle" + location = "nautilus" + catalog = "scallop" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = CatalogServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "abalone", + "location": "squid", + "catalog": "clam", + } + path = CatalogServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "whelk" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = CatalogServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "octopus", + } + path = CatalogServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "oyster" + expected = "folders/{folder}".format(folder=folder, ) + actual = CatalogServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nudibranch", + } + path = CatalogServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "cuttlefish" + expected = "organizations/{organization}".format(organization=organization, ) + actual = CatalogServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "mussel", + } + path = CatalogServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "winkle" + expected = "projects/{project}".format(project=project, ) + actual = CatalogServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nautilus", + } + path = CatalogServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "scallop" + location = "abalone" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = CatalogServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "squid", + "location": "clam", + } + path = CatalogServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object(transports.CatalogServiceTransport, '_prep_wrapped_messages') as prep: + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.CatalogServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = CatalogServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + with mock.patch.object(type(getattr(client.transport, "grpc_channel")), "close") as close: + async with client: + close.assert_not_called() + close.assert_called_once() + +def test_transport_close(): + transports = { + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + with mock.patch.object(type(getattr(client.transport, close_name)), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + +def test_client_ctx(): + transports = [ + 'grpc', + ] + for transport in transports: + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + +@pytest.mark.parametrize("client_class,transport_class", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport), +]) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) diff --git a/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_completion_service.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_completion_service.py new file mode 100644 index 00000000..3426748c --- /dev/null +++ b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_completion_service.py @@ -0,0 +1,1357 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os +import mock + +import grpc +from grpc.experimental import aio +import math +import pytest +from proto.marshal.rules.dates import DurationRule, TimestampRule + + +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import future +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers +from google.api_core import grpc_helpers_async +from google.api_core import operation_async # type: ignore +from google.api_core import operations_v1 +from google.api_core import path_template +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.retail_v2.services.completion_service import CompletionServiceAsyncClient +from google.cloud.retail_v2.services.completion_service import CompletionServiceClient +from google.cloud.retail_v2.services.completion_service import transports +from google.cloud.retail_v2.types import completion_service +from google.cloud.retail_v2.types import import_config +from google.longrunning import operations_pb2 +from google.oauth2 import service_account +from google.type import date_pb2 # type: ignore +import google.auth + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert CompletionServiceClient._get_default_mtls_endpoint(None) is None + assert CompletionServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert CompletionServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert CompletionServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert CompletionServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert CompletionServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class", [ + CompletionServiceClient, + CompletionServiceAsyncClient, +]) +def test_completion_service_client_from_service_account_info(client_class): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == 'retail.googleapis.com:443' + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.CompletionServiceGrpcTransport, "grpc"), + (transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +def test_completion_service_client_service_account_always_use_jwt(transport_class, transport_name): + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize("client_class", [ + CompletionServiceClient, + CompletionServiceAsyncClient, +]) +def test_completion_service_client_from_service_account_file(client_class): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json") + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json("dummy/file/path.json") + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == 'retail.googleapis.com:443' + + +def test_completion_service_client_get_transport_class(): + transport = CompletionServiceClient.get_transport_class() + available_transports = [ + transports.CompletionServiceGrpcTransport, + ] + assert transport in available_transports + + transport = CompletionServiceClient.get_transport_class("grpc") + assert transport == transports.CompletionServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc"), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +@mock.patch.object(CompletionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceClient)) +@mock.patch.object(CompletionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceAsyncClient)) +def test_completion_service_client_client_options(client_class, transport_class, transport_name): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(CompletionServiceClient, 'get_transport_class') as gtc: + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(CompletionServiceClient, 'get_transport_class') as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class(transport=transport_name) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError): + client = client_class(transport=transport_name) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc", "true"), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc", "false"), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), +]) +@mock.patch.object(CompletionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceClient)) +@mock.patch.object(CompletionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_completion_service_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + +@pytest.mark.parametrize("client_class", [ + CompletionServiceClient, CompletionServiceAsyncClient +]) +@mock.patch.object(CompletionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceClient)) +@mock.patch.object(CompletionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceAsyncClient)) +def test_completion_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc"), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +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"], + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc"), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +def test_completion_service_client_client_options_credentials_file(client_class, transport_class, transport_name): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + +def test_completion_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2.services.completion_service.transports.CompletionServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = CompletionServiceClient( + client_options={'api_endpoint': 'squid.clam.whelk'} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + +@pytest.mark.parametrize("request_type", [ + completion_service.CompleteQueryRequest, + dict, +]) +def test_complete_query(request_type, transport: str = 'grpc'): + client = CompletionServiceClient( + 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.complete_query), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = completion_service.CompleteQueryResponse( + attribution_token='attribution_token_value', + ) + response = client.complete_query(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == completion_service.CompleteQueryRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, completion_service.CompleteQueryResponse) + assert response.attribution_token == 'attribution_token_value' + + +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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.complete_query), + '__call__') as call: + client.complete_query() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == completion_service.CompleteQueryRequest() + + +@pytest.mark.asyncio +async def test_complete_query_async(transport: str = 'grpc_asyncio', request_type=completion_service.CompleteQueryRequest): + client = CompletionServiceAsyncClient( + 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.complete_query), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(completion_service.CompleteQueryResponse( + attribution_token='attribution_token_value', + )) + response = await client.complete_query(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == completion_service.CompleteQueryRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, completion_service.CompleteQueryResponse) + assert response.attribution_token == 'attribution_token_value' + + +@pytest.mark.asyncio +async def test_complete_query_async_from_dict(): + await test_complete_query_async(request_type=dict) + + +def test_complete_query_field_headers(): + 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. + request = completion_service.CompleteQueryRequest() + + request.catalog = 'catalog/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.complete_query), + '__call__') as call: + call.return_value = completion_service.CompleteQueryResponse() + client.complete_query(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', + 'catalog=catalog/value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_complete_query_field_headers_async(): + client = CompletionServiceAsyncClient( + 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 = completion_service.CompleteQueryRequest() + + request.catalog = 'catalog/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.complete_query), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(completion_service.CompleteQueryResponse()) + await client.complete_query(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', + 'catalog=catalog/value', + ) in kw['metadata'] + + +@pytest.mark.parametrize("request_type", [ + import_config.ImportCompletionDataRequest, + dict, +]) +def test_import_completion_data(request_type, transport: str = 'grpc'): + client = CompletionServiceClient( + 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.import_completion_data), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.import_completion_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportCompletionDataRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_completion_data), + '__call__') as call: + client.import_completion_data() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportCompletionDataRequest() + + +@pytest.mark.asyncio +async def test_import_completion_data_async(transport: str = 'grpc_asyncio', request_type=import_config.ImportCompletionDataRequest): + client = CompletionServiceAsyncClient( + 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.import_completion_data), + '__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.import_completion_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportCompletionDataRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_import_completion_data_async_from_dict(): + await test_import_completion_data_async(request_type=dict) + + +def test_import_completion_data_field_headers(): + 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. + request = import_config.ImportCompletionDataRequest() + + request.parent = 'parent/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_completion_data), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.import_completion_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent/value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_import_completion_data_field_headers_async(): + client = CompletionServiceAsyncClient( + 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 = import_config.ImportCompletionDataRequest() + + request.parent = 'parent/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_completion_data), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.import_completion_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent/value', + ) in kw['metadata'] + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CompletionServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CompletionServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CompletionServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CompletionServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = CompletionServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.CompletionServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.CompletionServiceGrpcTransport, + transports.CompletionServiceGrpcAsyncIOTransport, +]) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + +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, + ) + +def test_completion_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.CompletionServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_completion_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2.services.completion_service.transports.CompletionServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.CompletionServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'complete_query', + 'import_completion_data', + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + +def test_completion_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('google.cloud.retail_v2.services.completion_service.transports.CompletionServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CompletionServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with("credentials.json", + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id="octopus", + ) + + +def test_completion_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, 'default', autospec=True) as adc, mock.patch('google.cloud.retail_v2.services.completion_service.transports.CompletionServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CompletionServiceTransport() + adc.assert_called_once() + + +def test_completion_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + CompletionServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CompletionServiceGrpcTransport, + transports.CompletionServiceGrpcAsyncIOTransport, + ], +) +def test_completion_service_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=( 'https://www.googleapis.com/auth/cloud-platform',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.CompletionServiceGrpcTransport, grpc_helpers), + (transports.CompletionServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_completion_service_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class( + quota_project_id="octopus", + scopes=["1", "2"] + ) + + create_channel.assert_called_with( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.CompletionServiceGrpcTransport, transports.CompletionServiceGrpcAsyncIOTransport]) +def test_completion_service_grpc_transport_client_cert_source_for_mtls( + transport_class +): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, + private_key=expected_key + ) + + +def test_completion_service_host_no_port(): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + ) + assert client.transport._host == 'retail.googleapis.com:443' + + +def test_completion_service_host_with_port(): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + ) + assert client.transport._host == 'retail.googleapis.com:8000' + +def test_completion_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.CompletionServiceGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_completion_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.CompletionServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.CompletionServiceGrpcTransport, transports.CompletionServiceGrpcAsyncIOTransport]) +def test_completion_service_transport_channel_mtls_with_client_cert_source( + transport_class +): + with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.CompletionServiceGrpcTransport, transports.CompletionServiceGrpcAsyncIOTransport]) +def test_completion_service_transport_channel_mtls_with_adc( + transport_class +): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_completion_service_grpc_lro_client(): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_completion_service_grpc_lro_async_client(): + client = CompletionServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc_asyncio', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsAsyncClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_catalog_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = CompletionServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = CompletionServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = CompletionServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = CompletionServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format(folder=folder, ) + actual = CompletionServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = CompletionServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format(organization=organization, ) + actual = CompletionServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = CompletionServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format(project=project, ) + actual = CompletionServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = CompletionServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = CompletionServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = CompletionServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object(transports.CompletionServiceTransport, '_prep_wrapped_messages') as prep: + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.CompletionServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = CompletionServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = CompletionServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + with mock.patch.object(type(getattr(client.transport, "grpc_channel")), "close") as close: + async with client: + close.assert_not_called() + close.assert_called_once() + +def test_transport_close(): + transports = { + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + with mock.patch.object(type(getattr(client.transport, close_name)), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + +def test_client_ctx(): + transports = [ + 'grpc', + ] + for transport in transports: + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + +@pytest.mark.parametrize("client_class,transport_class", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport), +]) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) diff --git a/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_prediction_service.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_prediction_service.py new file mode 100644 index 00000000..cb282921 --- /dev/null +++ b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_prediction_service.py @@ -0,0 +1,1184 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os +import mock + +import grpc +from grpc.experimental import aio +import math +import pytest +from proto.marshal.rules.dates import DurationRule, TimestampRule + + +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers +from google.api_core import grpc_helpers_async +from google.api_core import path_template +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.retail_v2.services.prediction_service import PredictionServiceAsyncClient +from google.cloud.retail_v2.services.prediction_service import PredictionServiceClient +from google.cloud.retail_v2.services.prediction_service import transports +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 user_event +from google.oauth2 import service_account +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import struct_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore +import google.auth + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert PredictionServiceClient._get_default_mtls_endpoint(None) is None + assert PredictionServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert PredictionServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert PredictionServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert PredictionServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert PredictionServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class", [ + PredictionServiceClient, + PredictionServiceAsyncClient, +]) +def test_prediction_service_client_from_service_account_info(client_class): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == 'retail.googleapis.com:443' + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.PredictionServiceGrpcTransport, "grpc"), + (transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +def test_prediction_service_client_service_account_always_use_jwt(transport_class, transport_name): + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize("client_class", [ + PredictionServiceClient, + PredictionServiceAsyncClient, +]) +def test_prediction_service_client_from_service_account_file(client_class): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json") + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json("dummy/file/path.json") + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == 'retail.googleapis.com:443' + + +def test_prediction_service_client_get_transport_class(): + transport = PredictionServiceClient.get_transport_class() + available_transports = [ + transports.PredictionServiceGrpcTransport, + ] + assert transport in available_transports + + transport = PredictionServiceClient.get_transport_class("grpc") + assert transport == transports.PredictionServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc"), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +@mock.patch.object(PredictionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceClient)) +@mock.patch.object(PredictionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceAsyncClient)) +def test_prediction_service_client_client_options(client_class, transport_class, transport_name): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(PredictionServiceClient, 'get_transport_class') as gtc: + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(PredictionServiceClient, 'get_transport_class') as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class(transport=transport_name) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError): + client = client_class(transport=transport_name) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc", "true"), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc", "false"), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), +]) +@mock.patch.object(PredictionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceClient)) +@mock.patch.object(PredictionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_prediction_service_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + +@pytest.mark.parametrize("client_class", [ + PredictionServiceClient, PredictionServiceAsyncClient +]) +@mock.patch.object(PredictionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceClient)) +@mock.patch.object(PredictionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceAsyncClient)) +def test_prediction_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc"), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +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"], + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc"), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +def test_prediction_service_client_client_options_credentials_file(client_class, transport_class, transport_name): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + +def test_prediction_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2.services.prediction_service.transports.PredictionServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = PredictionServiceClient( + client_options={'api_endpoint': 'squid.clam.whelk'} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + +@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, + ) + + # 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.predict), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = prediction_service.PredictResponse( + attribution_token='attribution_token_value', + missing_ids=['missing_ids_value'], + validate_only=True, + ) + response = client.predict(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == prediction_service.PredictRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, prediction_service.PredictResponse) + assert response.attribution_token == 'attribution_token_value' + assert response.missing_ids == ['missing_ids_value'] + assert response.validate_only is True + + +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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.predict), + '__call__') as call: + client.predict() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == prediction_service.PredictRequest() + + +@pytest.mark.asyncio +async def test_predict_async(transport: str = 'grpc_asyncio', request_type=prediction_service.PredictRequest): + client = PredictionServiceAsyncClient( + 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.predict), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(prediction_service.PredictResponse( + attribution_token='attribution_token_value', + missing_ids=['missing_ids_value'], + validate_only=True, + )) + response = await client.predict(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == prediction_service.PredictRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, prediction_service.PredictResponse) + assert response.attribution_token == 'attribution_token_value' + assert response.missing_ids == ['missing_ids_value'] + assert response.validate_only is True + + +@pytest.mark.asyncio +async def test_predict_async_from_dict(): + await test_predict_async(request_type=dict) + + +def test_predict_field_headers(): + 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. + request = prediction_service.PredictRequest() + + request.placement = 'placement/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.predict), + '__call__') as call: + call.return_value = prediction_service.PredictResponse() + client.predict(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', + 'placement=placement/value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_predict_field_headers_async(): + client = PredictionServiceAsyncClient( + 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 = prediction_service.PredictRequest() + + request.placement = 'placement/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.predict), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(prediction_service.PredictResponse()) + await client.predict(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', + 'placement=placement/value', + ) in kw['metadata'] + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PredictionServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = PredictionServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = PredictionServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PredictionServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = PredictionServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.PredictionServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, +]) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + +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, + ) + +def test_prediction_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.PredictionServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_prediction_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2.services.prediction_service.transports.PredictionServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.PredictionServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'predict', + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + +def test_prediction_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('google.cloud.retail_v2.services.prediction_service.transports.PredictionServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.PredictionServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with("credentials.json", + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id="octopus", + ) + + +def test_prediction_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, 'default', autospec=True) as adc, mock.patch('google.cloud.retail_v2.services.prediction_service.transports.PredictionServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.PredictionServiceTransport() + adc.assert_called_once() + + +def test_prediction_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + PredictionServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], +) +def test_prediction_service_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=( 'https://www.googleapis.com/auth/cloud-platform',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.PredictionServiceGrpcTransport, grpc_helpers), + (transports.PredictionServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_prediction_service_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class( + quota_project_id="octopus", + scopes=["1", "2"] + ) + + create_channel.assert_called_with( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.PredictionServiceGrpcTransport, transports.PredictionServiceGrpcAsyncIOTransport]) +def test_prediction_service_grpc_transport_client_cert_source_for_mtls( + transport_class +): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, + private_key=expected_key + ) + + +def test_prediction_service_host_no_port(): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + ) + assert client.transport._host == 'retail.googleapis.com:443' + + +def test_prediction_service_host_with_port(): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + ) + assert client.transport._host == 'retail.googleapis.com:8000' + +def test_prediction_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.PredictionServiceGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_prediction_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.PredictionServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.PredictionServiceGrpcTransport, transports.PredictionServiceGrpcAsyncIOTransport]) +def test_prediction_service_transport_channel_mtls_with_client_cert_source( + transport_class +): + with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.PredictionServiceGrpcTransport, transports.PredictionServiceGrpcAsyncIOTransport]) +def test_prediction_service_transport_channel_mtls_with_adc( + transport_class +): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_product_path(): + project = "squid" + location = "clam" + catalog = "whelk" + branch = "octopus" + product = "oyster" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, product=product, ) + actual = PredictionServiceClient.product_path(project, location, catalog, branch, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "nudibranch", + "location": "cuttlefish", + "catalog": "mussel", + "branch": "winkle", + "product": "nautilus", + } + path = PredictionServiceClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_product_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "scallop" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = PredictionServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "abalone", + } + path = PredictionServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "squid" + expected = "folders/{folder}".format(folder=folder, ) + actual = PredictionServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "clam", + } + path = PredictionServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "whelk" + expected = "organizations/{organization}".format(organization=organization, ) + actual = PredictionServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "octopus", + } + path = PredictionServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "oyster" + expected = "projects/{project}".format(project=project, ) + actual = PredictionServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nudibranch", + } + path = PredictionServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "cuttlefish" + location = "mussel" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = PredictionServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "winkle", + "location": "nautilus", + } + path = PredictionServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object(transports.PredictionServiceTransport, '_prep_wrapped_messages') as prep: + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.PredictionServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = PredictionServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = PredictionServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + with mock.patch.object(type(getattr(client.transport, "grpc_channel")), "close") as close: + async with client: + close.assert_not_called() + close.assert_called_once() + +def test_transport_close(): + transports = { + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + with mock.patch.object(type(getattr(client.transport, close_name)), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + +def test_client_ctx(): + transports = [ + 'grpc', + ] + for transport in transports: + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + +@pytest.mark.parametrize("client_class,transport_class", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport), +]) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) diff --git a/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_product_service.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_product_service.py new file mode 100644 index 00000000..1ab3a754 --- /dev/null +++ b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_product_service.py @@ -0,0 +1,3551 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os +import mock + +import grpc +from grpc.experimental import aio +import math +import pytest +from proto.marshal.rules.dates import DurationRule, TimestampRule + + +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import future +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers +from google.api_core import grpc_helpers_async +from google.api_core import operation_async # type: ignore +from google.api_core import operations_v1 +from google.api_core import path_template +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.retail_v2.services.product_service import ProductServiceAsyncClient +from google.cloud.retail_v2.services.product_service import ProductServiceClient +from google.cloud.retail_v2.services.product_service import pagers +from google.cloud.retail_v2.services.product_service import transports +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 product as gcr_product +from google.cloud.retail_v2.types import product_service +from google.longrunning import operations_pb2 +from google.oauth2 import service_account +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 +from google.type import date_pb2 # type: ignore +import google.auth + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert ProductServiceClient._get_default_mtls_endpoint(None) is None + assert ProductServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ProductServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ProductServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ProductServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ProductServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class", [ + ProductServiceClient, + ProductServiceAsyncClient, +]) +def test_product_service_client_from_service_account_info(client_class): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == 'retail.googleapis.com:443' + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ProductServiceGrpcTransport, "grpc"), + (transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +def test_product_service_client_service_account_always_use_jwt(transport_class, transport_name): + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize("client_class", [ + ProductServiceClient, + ProductServiceAsyncClient, +]) +def test_product_service_client_from_service_account_file(client_class): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json") + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json("dummy/file/path.json") + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == 'retail.googleapis.com:443' + + +def test_product_service_client_get_transport_class(): + transport = ProductServiceClient.get_transport_class() + available_transports = [ + transports.ProductServiceGrpcTransport, + ] + assert transport in available_transports + + transport = ProductServiceClient.get_transport_class("grpc") + assert transport == transports.ProductServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc"), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +@mock.patch.object(ProductServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceClient)) +@mock.patch.object(ProductServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceAsyncClient)) +def test_product_service_client_client_options(client_class, transport_class, transport_name): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(ProductServiceClient, 'get_transport_class') as gtc: + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(ProductServiceClient, 'get_transport_class') as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class(transport=transport_name) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError): + client = client_class(transport=transport_name) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc", "true"), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc", "false"), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), +]) +@mock.patch.object(ProductServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceClient)) +@mock.patch.object(ProductServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_product_service_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + +@pytest.mark.parametrize("client_class", [ + ProductServiceClient, ProductServiceAsyncClient +]) +@mock.patch.object(ProductServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceClient)) +@mock.patch.object(ProductServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceAsyncClient)) +def test_product_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc"), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +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"], + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc"), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +def test_product_service_client_client_options_credentials_file(client_class, transport_class, transport_name): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + +def test_product_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2.services.product_service.transports.ProductServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ProductServiceClient( + client_options={'api_endpoint': 'squid.clam.whelk'} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + +@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, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_value'], + expire_time=timestamp_pb2.Timestamp(seconds=751), + ) + response = client.create_product(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.CreateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_value'] + + +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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + client.create_product() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.CreateProductRequest() + + +@pytest.mark.asyncio +async def test_create_product_async(transport: str = 'grpc_asyncio', request_type=product_service.CreateProductRequest): + 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.create_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_value'], + )) + response = await client.create_product(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.CreateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_value'] + + +@pytest.mark.asyncio +async def test_create_product_async_from_dict(): + await test_create_product_async(request_type=dict) + + +def test_create_product_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.CreateProductRequest() + + request.parent = 'parent/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + call.return_value = gcr_product.Product() + client.create_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent/value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_create_product_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.CreateProductRequest() + + request.parent = 'parent/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_product.Product()) + await client.create_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent/value', + ) in kw['metadata'] + + +def test_create_product_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.create_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_product.Product() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_product( + parent='parent_value', + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + product_id='product_id_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].product + mock_val = gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + assert arg == mock_val + arg = args[0].product_id + mock_val = 'product_id_value' + assert arg == mock_val + + +def test_create_product_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.create_product( + product_service.CreateProductRequest(), + parent='parent_value', + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + product_id='product_id_value', + ) + + +@pytest.mark.asyncio +async def test_create_product_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.create_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_product.Product() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_product.Product()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_product( + parent='parent_value', + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + product_id='product_id_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].product + mock_val = gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + assert arg == mock_val + arg = args[0].product_id + mock_val = 'product_id_value' + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_create_product_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.create_product( + product_service.CreateProductRequest(), + parent='parent_value', + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + product_id='product_id_value', + ) + + +@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, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product.Product( + name='name_value', + id='id_value', + type_=product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_value'], + expire_time=timestamp_pb2.Timestamp(seconds=751), + ) + response = client.get_product(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.GetProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_value'] + + +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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + client.get_product() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.GetProductRequest() + + +@pytest.mark.asyncio +async def test_get_product_async(transport: str = 'grpc_asyncio', request_type=product_service.GetProductRequest): + 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.get_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product.Product( + name='name_value', + id='id_value', + type_=product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_value'], + )) + response = await client.get_product(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.GetProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_value'] + + +@pytest.mark.asyncio +async def test_get_product_async_from_dict(): + await test_get_product_async(request_type=dict) + + +def test_get_product_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.GetProductRequest() + + request.name = 'name/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + call.return_value = product.Product() + client.get_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name/value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_get_product_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.GetProductRequest() + + request.name = 'name/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product.Product()) + await client.get_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name/value', + ) in kw['metadata'] + + +def test_get_product_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.get_product), + '__call__') as call: + # Designate an appropriate return value for the call. + 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', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_get_product_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.get_product( + product_service.GetProductRequest(), + name='name_value', + ) + + +@pytest.mark.asyncio +async def test_get_product_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.get_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product.Product() + + 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', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_get_product_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.get_product( + product_service.GetProductRequest(), + name='name_value', + ) + + +@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, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_service.ListProductsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_products(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.ListProductsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductsPager) + assert response.next_page_token == 'next_page_token_value' + + +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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + client.list_products() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.ListProductsRequest() + + +@pytest.mark.asyncio +async def test_list_products_async(transport: str = 'grpc_asyncio', request_type=product_service.ListProductsRequest): + 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.list_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_service.ListProductsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_products(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.ListProductsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_products_async_from_dict(): + await test_list_products_async(request_type=dict) + + +def test_list_products_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.ListProductsRequest() + + request.parent = 'parent/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + call.return_value = product_service.ListProductsResponse() + client.list_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent/value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_list_products_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.ListProductsRequest() + + request.parent = 'parent/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_service.ListProductsResponse()) + await client.list_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent/value', + ) in kw['metadata'] + + +def test_list_products_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.list_products), + '__call__') as call: + # Designate an appropriate return value for the call. + 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', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + + +def test_list_products_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.list_products( + product_service.ListProductsRequest(), + parent='parent_value', + ) + + +@pytest.mark.asyncio +async def test_list_products_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.list_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_service.ListProductsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_service.ListProductsResponse()) + # 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', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_list_products_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.list_products( + product_service.ListProductsRequest(), + parent='parent_value', + ) + + +def test_list_products_pager(transport_name: str = "grpc"): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_service.ListProductsResponse( + 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', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_products(request={}) + + assert pager._metadata == metadata + + results = [i for i in pager] + assert len(results) == 6 + assert all(isinstance(i, product.Product) + for i in results) +def test_list_products_pages(transport_name: str = "grpc"): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_service.ListProductsResponse( + 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', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + ], + ), + RuntimeError, + ) + pages = list(client.list_products(request={}).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.asyncio +async def test_list_products_async_pager(): + 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.list_products), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_service.ListProductsResponse( + 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', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_products(request={},) + assert async_pager.next_page_token == 'abc' + responses = [] + async for response in async_pager: + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, product.Product) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_products_async_pages(): + 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.list_products), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_service.ListProductsResponse( + 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', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in (await client.list_products(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.parametrize("request_type", [ + product_service.UpdateProductRequest, + dict, +]) +def test_update_product(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.update_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_value'], + expire_time=timestamp_pb2.Timestamp(seconds=751), + ) + response = client.update_product(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.UpdateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_value'] + + +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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + client.update_product() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.UpdateProductRequest() + + +@pytest.mark.asyncio +async def test_update_product_async(transport: str = 'grpc_asyncio', request_type=product_service.UpdateProductRequest): + 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.update_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_value'], + )) + response = await client.update_product(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.UpdateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_value'] + + +@pytest.mark.asyncio +async def test_update_product_async_from_dict(): + await test_update_product_async(request_type=dict) + + +def test_update_product_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.UpdateProductRequest() + + request.product.name = 'product.name/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + call.return_value = gcr_product.Product() + client.update_product(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.name=product.name/value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_product_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.UpdateProductRequest() + + request.product.name = 'product.name/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_product.Product()) + await client.update_product(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.name=product.name/value', + ) in kw['metadata'] + + +def test_update_product_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.update_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_product.Product() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_product( + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].product + mock_val = gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + + +def test_update_product_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.update_product( + product_service.UpdateProductRequest(), + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.asyncio +async def test_update_product_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.update_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_product.Product() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_product.Product()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_product( + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].product + mock_val = gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_update_product_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.update_product( + product_service.UpdateProductRequest(), + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@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, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_product(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.DeleteProductRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + client.delete_product() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.DeleteProductRequest() + + +@pytest.mark.asyncio +async def test_delete_product_async(transport: str = 'grpc_asyncio', request_type=product_service.DeleteProductRequest): + 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.delete_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_product(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.DeleteProductRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_product_async_from_dict(): + await test_delete_product_async(request_type=dict) + + +def test_delete_product_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.DeleteProductRequest() + + request.name = 'name/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + call.return_value = None + client.delete_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name/value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_delete_product_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.DeleteProductRequest() + + request.name = 'name/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name/value', + ) in kw['metadata'] + + +def test_delete_product_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.delete_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_product( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_delete_product_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.delete_product( + product_service.DeleteProductRequest(), + name='name_value', + ) + + +@pytest.mark.asyncio +async def test_delete_product_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.delete_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_product( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_delete_product_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.delete_product( + product_service.DeleteProductRequest(), + name='name_value', + ) + + +@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, + ) + + # 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.import_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.import_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportProductsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_products), + '__call__') as call: + client.import_products() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportProductsRequest() + + +@pytest.mark.asyncio +async def test_import_products_async(transport: str = 'grpc_asyncio', request_type=import_config.ImportProductsRequest): + 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.import_products), + '__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.import_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportProductsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_import_products_async_from_dict(): + await test_import_products_async(request_type=dict) + + +def test_import_products_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 = import_config.ImportProductsRequest() + + request.parent = 'parent/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_products), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.import_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent/value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_import_products_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 = import_config.ImportProductsRequest() + + request.parent = 'parent/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_products), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.import_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent/value', + ) in kw['metadata'] + + +@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, + ) + + # 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.set_inventory), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.set_inventory(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.SetInventoryRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_inventory), + '__call__') as call: + client.set_inventory() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.SetInventoryRequest() + + +@pytest.mark.asyncio +async def test_set_inventory_async(transport: str = 'grpc_asyncio', request_type=product_service.SetInventoryRequest): + 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.set_inventory), + '__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.set_inventory(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.SetInventoryRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_set_inventory_async_from_dict(): + await test_set_inventory_async(request_type=dict) + + +def test_set_inventory_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.SetInventoryRequest() + + request.inventory.name = 'inventory.name/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_inventory), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.set_inventory(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', + 'inventory.name=inventory.name/value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_set_inventory_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.SetInventoryRequest() + + request.inventory.name = 'inventory.name/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_inventory), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.set_inventory(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', + 'inventory.name=inventory.name/value', + ) in kw['metadata'] + + +def test_set_inventory_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.set_inventory), + '__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.set_inventory( + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].inventory + mock_val = product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + assert arg == mock_val + arg = args[0].set_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + + +def test_set_inventory_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.set_inventory( + product_service.SetInventoryRequest(), + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.asyncio +async def test_set_inventory_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.set_inventory), + '__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.set_inventory( + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].inventory + mock_val = product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + assert arg == mock_val + arg = args[0].set_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_set_inventory_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.set_inventory( + product_service.SetInventoryRequest(), + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.AddFulfillmentPlacesRequest, + dict, +]) +def test_add_fulfillment_places(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.add_fulfillment_places), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.add_fulfillment_places(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.AddFulfillmentPlacesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_fulfillment_places), + '__call__') as call: + client.add_fulfillment_places() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.AddFulfillmentPlacesRequest() + + +@pytest.mark.asyncio +async def test_add_fulfillment_places_async(transport: str = 'grpc_asyncio', request_type=product_service.AddFulfillmentPlacesRequest): + 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_fulfillment_places), + '__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_fulfillment_places(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.AddFulfillmentPlacesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_add_fulfillment_places_async_from_dict(): + await test_add_fulfillment_places_async(request_type=dict) + + +def test_add_fulfillment_places_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.AddFulfillmentPlacesRequest() + + request.product = 'product/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_fulfillment_places), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.add_fulfillment_places(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_fulfillment_places_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.AddFulfillmentPlacesRequest() + + request.product = 'product/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_fulfillment_places), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.add_fulfillment_places(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_fulfillment_places_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_fulfillment_places), + '__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_fulfillment_places( + 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_fulfillment_places_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_fulfillment_places( + product_service.AddFulfillmentPlacesRequest(), + product='product_value', + ) + + +@pytest.mark.asyncio +async def test_add_fulfillment_places_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_fulfillment_places), + '__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_fulfillment_places( + 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_fulfillment_places_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_fulfillment_places( + product_service.AddFulfillmentPlacesRequest(), + product='product_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.RemoveFulfillmentPlacesRequest, + dict, +]) +def test_remove_fulfillment_places(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_fulfillment_places), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.remove_fulfillment_places(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.RemoveFulfillmentPlacesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_fulfillment_places), + '__call__') as call: + client.remove_fulfillment_places() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.RemoveFulfillmentPlacesRequest() + + +@pytest.mark.asyncio +async def test_remove_fulfillment_places_async(transport: str = 'grpc_asyncio', request_type=product_service.RemoveFulfillmentPlacesRequest): + 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_fulfillment_places), + '__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_fulfillment_places(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.RemoveFulfillmentPlacesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_remove_fulfillment_places_async_from_dict(): + await test_remove_fulfillment_places_async(request_type=dict) + + +def test_remove_fulfillment_places_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.RemoveFulfillmentPlacesRequest() + + request.product = 'product/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_fulfillment_places), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.remove_fulfillment_places(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_fulfillment_places_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.RemoveFulfillmentPlacesRequest() + + request.product = 'product/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_fulfillment_places), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.remove_fulfillment_places(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_fulfillment_places_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_fulfillment_places), + '__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_fulfillment_places( + 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_fulfillment_places_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_fulfillment_places( + product_service.RemoveFulfillmentPlacesRequest(), + product='product_value', + ) + + +@pytest.mark.asyncio +async def test_remove_fulfillment_places_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_fulfillment_places), + '__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_fulfillment_places( + 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_fulfillment_places_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_fulfillment_places( + 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( + 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, + ) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ProductServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ProductServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ProductServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ProductServiceGrpcTransport, + transports.ProductServiceGrpcAsyncIOTransport, +]) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + +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, + ) + +def test_product_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ProductServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_product_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2.services.product_service.transports.ProductServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ProductServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'create_product', + 'get_product', + 'list_products', + 'update_product', + 'delete_product', + 'import_products', + 'set_inventory', + 'add_fulfillment_places', + 'remove_fulfillment_places', + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + +def test_product_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('google.cloud.retail_v2.services.product_service.transports.ProductServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ProductServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with("credentials.json", + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id="octopus", + ) + + +def test_product_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, 'default', autospec=True) as adc, mock.patch('google.cloud.retail_v2.services.product_service.transports.ProductServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ProductServiceTransport() + adc.assert_called_once() + + +def test_product_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + ProductServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ProductServiceGrpcTransport, + transports.ProductServiceGrpcAsyncIOTransport, + ], +) +def test_product_service_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=( 'https://www.googleapis.com/auth/cloud-platform',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.ProductServiceGrpcTransport, grpc_helpers), + (transports.ProductServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_product_service_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class( + quota_project_id="octopus", + scopes=["1", "2"] + ) + + create_channel.assert_called_with( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ProductServiceGrpcTransport, transports.ProductServiceGrpcAsyncIOTransport]) +def test_product_service_grpc_transport_client_cert_source_for_mtls( + transport_class +): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, + private_key=expected_key + ) + + +def test_product_service_host_no_port(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + ) + assert client.transport._host == 'retail.googleapis.com:443' + + +def test_product_service_host_with_port(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + ) + assert client.transport._host == 'retail.googleapis.com:8000' + +def test_product_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ProductServiceGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_product_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ProductServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.ProductServiceGrpcTransport, transports.ProductServiceGrpcAsyncIOTransport]) +def test_product_service_transport_channel_mtls_with_client_cert_source( + transport_class +): + with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.ProductServiceGrpcTransport, transports.ProductServiceGrpcAsyncIOTransport]) +def test_product_service_transport_channel_mtls_with_adc( + transport_class +): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_product_service_grpc_lro_client(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_product_service_grpc_lro_async_client(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc_asyncio', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsAsyncClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_branch_path(): + project = "squid" + location = "clam" + catalog = "whelk" + branch = "octopus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) + actual = ProductServiceClient.branch_path(project, location, catalog, branch) + assert expected == actual + + +def test_parse_branch_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "catalog": "cuttlefish", + "branch": "mussel", + } + path = ProductServiceClient.branch_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_branch_path(path) + assert expected == actual + +def test_product_path(): + project = "winkle" + location = "nautilus" + catalog = "scallop" + branch = "abalone" + product = "squid" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, product=product, ) + actual = ProductServiceClient.product_path(project, location, catalog, branch, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "clam", + "location": "whelk", + "catalog": "octopus", + "branch": "oyster", + "product": "nudibranch", + } + path = ProductServiceClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_product_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ProductServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = ProductServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format(folder=folder, ) + actual = ProductServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = ProductServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ProductServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = ProductServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format(project=project, ) + actual = ProductServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = ProductServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ProductServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = ProductServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object(transports.ProductServiceTransport, '_prep_wrapped_messages') as prep: + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ProductServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = ProductServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + with mock.patch.object(type(getattr(client.transport, "grpc_channel")), "close") as close: + async with client: + close.assert_not_called() + close.assert_called_once() + +def test_transport_close(): + transports = { + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + with mock.patch.object(type(getattr(client.transport, close_name)), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + +def test_client_ctx(): + transports = [ + 'grpc', + ] + for transport in transports: + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + +@pytest.mark.parametrize("client_class,transport_class", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport), +]) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) diff --git a/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_search_service.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_search_service.py new file mode 100644 index 00000000..31eba051 --- /dev/null +++ b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_search_service.py @@ -0,0 +1,1398 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os +import mock + +import grpc +from grpc.experimental import aio +import math +import pytest +from proto.marshal.rules.dates import DurationRule, TimestampRule + + +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers +from google.api_core import grpc_helpers_async +from google.api_core import path_template +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.retail_v2.services.search_service import SearchServiceAsyncClient +from google.cloud.retail_v2.services.search_service import SearchServiceClient +from google.cloud.retail_v2.services.search_service import pagers +from google.cloud.retail_v2.services.search_service import transports +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import search_service +from google.oauth2 import service_account +import google.auth + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert SearchServiceClient._get_default_mtls_endpoint(None) is None + assert SearchServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert SearchServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert SearchServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert SearchServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert SearchServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class", [ + SearchServiceClient, + SearchServiceAsyncClient, +]) +def test_search_service_client_from_service_account_info(client_class): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == 'retail.googleapis.com:443' + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.SearchServiceGrpcTransport, "grpc"), + (transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +def test_search_service_client_service_account_always_use_jwt(transport_class, transport_name): + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize("client_class", [ + SearchServiceClient, + SearchServiceAsyncClient, +]) +def test_search_service_client_from_service_account_file(client_class): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json") + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json("dummy/file/path.json") + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == 'retail.googleapis.com:443' + + +def test_search_service_client_get_transport_class(): + transport = SearchServiceClient.get_transport_class() + available_transports = [ + transports.SearchServiceGrpcTransport, + ] + assert transport in available_transports + + transport = SearchServiceClient.get_transport_class("grpc") + assert transport == transports.SearchServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc"), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +@mock.patch.object(SearchServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceClient)) +@mock.patch.object(SearchServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceAsyncClient)) +def test_search_service_client_client_options(client_class, transport_class, transport_name): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(SearchServiceClient, 'get_transport_class') as gtc: + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(SearchServiceClient, 'get_transport_class') as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class(transport=transport_name) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError): + client = client_class(transport=transport_name) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc", "true"), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc", "false"), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), +]) +@mock.patch.object(SearchServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceClient)) +@mock.patch.object(SearchServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_search_service_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + +@pytest.mark.parametrize("client_class", [ + SearchServiceClient, SearchServiceAsyncClient +]) +@mock.patch.object(SearchServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceClient)) +@mock.patch.object(SearchServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceAsyncClient)) +def test_search_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc"), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +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"], + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc"), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +def test_search_service_client_client_options_credentials_file(client_class, transport_class, transport_name): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + +def test_search_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2.services.search_service.transports.SearchServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = SearchServiceClient( + client_options={'api_endpoint': 'squid.clam.whelk'} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + +@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, + ) + + # 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.search), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = search_service.SearchResponse( + total_size=1086, + corrected_query='corrected_query_value', + attribution_token='attribution_token_value', + next_page_token='next_page_token_value', + redirect_uri='redirect_uri_value', + ) + response = client.search(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == search_service.SearchRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchPager) + assert response.total_size == 1086 + assert response.corrected_query == 'corrected_query_value' + assert response.attribution_token == 'attribution_token_value' + assert response.next_page_token == 'next_page_token_value' + assert response.redirect_uri == 'redirect_uri_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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search), + '__call__') as call: + client.search() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == search_service.SearchRequest() + + +@pytest.mark.asyncio +async def test_search_async(transport: str = 'grpc_asyncio', request_type=search_service.SearchRequest): + client = SearchServiceAsyncClient( + 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.search), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(search_service.SearchResponse( + total_size=1086, + corrected_query='corrected_query_value', + attribution_token='attribution_token_value', + next_page_token='next_page_token_value', + redirect_uri='redirect_uri_value', + )) + response = await client.search(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == search_service.SearchRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchAsyncPager) + assert response.total_size == 1086 + assert response.corrected_query == 'corrected_query_value' + assert response.attribution_token == 'attribution_token_value' + assert response.next_page_token == 'next_page_token_value' + assert response.redirect_uri == 'redirect_uri_value' + + +@pytest.mark.asyncio +async def test_search_async_from_dict(): + await test_search_async(request_type=dict) + + +def test_search_field_headers(): + 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. + request = search_service.SearchRequest() + + request.placement = 'placement/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search), + '__call__') as call: + call.return_value = search_service.SearchResponse() + client.search(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', + 'placement=placement/value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_search_field_headers_async(): + client = SearchServiceAsyncClient( + 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 = search_service.SearchRequest() + + request.placement = 'placement/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(search_service.SearchResponse()) + await client.search(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', + 'placement=placement/value', + ) in kw['metadata'] + + +def test_search_pager(transport_name: str = "grpc"): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + next_page_token='abc', + ), + search_service.SearchResponse( + results=[], + next_page_token='def', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], + next_page_token='ghi', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('placement', ''), + )), + ) + pager = client.search(request={}) + + assert pager._metadata == metadata + + results = [i for i in pager] + assert len(results) == 6 + assert all(isinstance(i, search_service.SearchResponse.SearchResult) + for i in results) +def test_search_pages(transport_name: str = "grpc"): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + next_page_token='abc', + ), + search_service.SearchResponse( + results=[], + next_page_token='def', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], + next_page_token='ghi', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + ), + RuntimeError, + ) + pages = list(client.search(request={}).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.asyncio +async def test_search_async_pager(): + client = SearchServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + next_page_token='abc', + ), + search_service.SearchResponse( + results=[], + next_page_token='def', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], + next_page_token='ghi', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + ), + RuntimeError, + ) + async_pager = await client.search(request={},) + assert async_pager.next_page_token == 'abc' + responses = [] + async for response in async_pager: + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, search_service.SearchResponse.SearchResult) + for i in responses) + + +@pytest.mark.asyncio +async def test_search_async_pages(): + client = SearchServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + next_page_token='abc', + ), + search_service.SearchResponse( + results=[], + next_page_token='def', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], + next_page_token='ghi', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in (await client.search(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SearchServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = SearchServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = SearchServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SearchServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = SearchServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.SearchServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.SearchServiceGrpcTransport, + transports.SearchServiceGrpcAsyncIOTransport, +]) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + +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, + ) + +def test_search_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.SearchServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_search_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2.services.search_service.transports.SearchServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.SearchServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'search', + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + +def test_search_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('google.cloud.retail_v2.services.search_service.transports.SearchServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.SearchServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with("credentials.json", + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id="octopus", + ) + + +def test_search_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, 'default', autospec=True) as adc, mock.patch('google.cloud.retail_v2.services.search_service.transports.SearchServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.SearchServiceTransport() + adc.assert_called_once() + + +def test_search_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + SearchServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.SearchServiceGrpcTransport, + transports.SearchServiceGrpcAsyncIOTransport, + ], +) +def test_search_service_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=( 'https://www.googleapis.com/auth/cloud-platform',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.SearchServiceGrpcTransport, grpc_helpers), + (transports.SearchServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_search_service_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class( + quota_project_id="octopus", + scopes=["1", "2"] + ) + + create_channel.assert_called_with( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.SearchServiceGrpcTransport, transports.SearchServiceGrpcAsyncIOTransport]) +def test_search_service_grpc_transport_client_cert_source_for_mtls( + transport_class +): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, + private_key=expected_key + ) + + +def test_search_service_host_no_port(): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + ) + assert client.transport._host == 'retail.googleapis.com:443' + + +def test_search_service_host_with_port(): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + ) + assert client.transport._host == 'retail.googleapis.com:8000' + +def test_search_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.SearchServiceGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_search_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.SearchServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.SearchServiceGrpcTransport, transports.SearchServiceGrpcAsyncIOTransport]) +def test_search_service_transport_channel_mtls_with_client_cert_source( + transport_class +): + with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.SearchServiceGrpcTransport, transports.SearchServiceGrpcAsyncIOTransport]) +def test_search_service_transport_channel_mtls_with_adc( + transport_class +): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_branch_path(): + project = "squid" + location = "clam" + catalog = "whelk" + branch = "octopus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) + actual = SearchServiceClient.branch_path(project, location, catalog, branch) + assert expected == actual + + +def test_parse_branch_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "catalog": "cuttlefish", + "branch": "mussel", + } + path = SearchServiceClient.branch_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_branch_path(path) + assert expected == actual + +def test_product_path(): + project = "winkle" + location = "nautilus" + catalog = "scallop" + branch = "abalone" + product = "squid" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, product=product, ) + actual = SearchServiceClient.product_path(project, location, catalog, branch, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "clam", + "location": "whelk", + "catalog": "octopus", + "branch": "oyster", + "product": "nudibranch", + } + path = SearchServiceClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_product_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = SearchServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = SearchServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format(folder=folder, ) + actual = SearchServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = SearchServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format(organization=organization, ) + actual = SearchServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = SearchServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format(project=project, ) + actual = SearchServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = SearchServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = SearchServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = SearchServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object(transports.SearchServiceTransport, '_prep_wrapped_messages') as prep: + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.SearchServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = SearchServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = SearchServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + with mock.patch.object(type(getattr(client.transport, "grpc_channel")), "close") as close: + async with client: + close.assert_not_called() + close.assert_called_once() + +def test_transport_close(): + transports = { + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + with mock.patch.object(type(getattr(client.transport, close_name)), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + +def test_client_ctx(): + transports = [ + 'grpc', + ] + for transport in transports: + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + +@pytest.mark.parametrize("client_class,transport_class", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport), +]) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) diff --git a/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_user_event_service.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_user_event_service.py new file mode 100644 index 00000000..0bee3646 --- /dev/null +++ b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_user_event_service.py @@ -0,0 +1,1896 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os +import mock + +import grpc +from grpc.experimental import aio +import math +import pytest +from proto.marshal.rules.dates import DurationRule, TimestampRule + + +from google.api import httpbody_pb2 # type: ignore +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import future +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers +from google.api_core import grpc_helpers_async +from google.api_core import operation_async # type: ignore +from google.api_core import operations_v1 +from google.api_core import path_template +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.retail_v2.services.user_event_service import UserEventServiceAsyncClient +from google.cloud.retail_v2.services.user_event_service import UserEventServiceClient +from google.cloud.retail_v2.services.user_event_service import transports +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 purge_config +from google.cloud.retail_v2.types import user_event +from google.cloud.retail_v2.types import user_event_service +from google.longrunning import operations_pb2 +from google.oauth2 import service_account +from google.protobuf import any_pb2 # type: ignore +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 +from google.type import date_pb2 # type: ignore +import google.auth + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert UserEventServiceClient._get_default_mtls_endpoint(None) is None + assert UserEventServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert UserEventServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert UserEventServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert UserEventServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert UserEventServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class", [ + UserEventServiceClient, + UserEventServiceAsyncClient, +]) +def test_user_event_service_client_from_service_account_info(client_class): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == 'retail.googleapis.com:443' + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.UserEventServiceGrpcTransport, "grpc"), + (transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +def test_user_event_service_client_service_account_always_use_jwt(transport_class, transport_name): + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize("client_class", [ + UserEventServiceClient, + UserEventServiceAsyncClient, +]) +def test_user_event_service_client_from_service_account_file(client_class): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json") + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json("dummy/file/path.json") + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == 'retail.googleapis.com:443' + + +def test_user_event_service_client_get_transport_class(): + transport = UserEventServiceClient.get_transport_class() + available_transports = [ + transports.UserEventServiceGrpcTransport, + ] + assert transport in available_transports + + transport = UserEventServiceClient.get_transport_class("grpc") + assert transport == transports.UserEventServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc"), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +@mock.patch.object(UserEventServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceClient)) +@mock.patch.object(UserEventServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceAsyncClient)) +def test_user_event_service_client_client_options(client_class, transport_class, transport_name): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(UserEventServiceClient, 'get_transport_class') as gtc: + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(UserEventServiceClient, 'get_transport_class') as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class(transport=transport_name) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError): + client = client_class(transport=transport_name) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc", "true"), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc", "false"), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), +]) +@mock.patch.object(UserEventServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceClient)) +@mock.patch.object(UserEventServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_user_event_service_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + +@pytest.mark.parametrize("client_class", [ + UserEventServiceClient, UserEventServiceAsyncClient +]) +@mock.patch.object(UserEventServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceClient)) +@mock.patch.object(UserEventServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceAsyncClient)) +def test_user_event_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc"), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +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"], + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc"), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio"), +]) +def test_user_event_service_client_client_options_credentials_file(client_class, transport_class, transport_name): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + +def test_user_event_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2.services.user_event_service.transports.UserEventServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = UserEventServiceClient( + client_options={'api_endpoint': 'squid.clam.whelk'} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + +@pytest.mark.parametrize("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, + ) + + # 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.write_user_event), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = user_event.UserEvent( + event_type='event_type_value', + visitor_id='visitor_id_value', + session_id='session_id_value', + experiment_ids=['experiment_ids_value'], + attribution_token='attribution_token_value', + cart_id='cart_id_value', + search_query='search_query_value', + filter='filter_value', + order_by='order_by_value', + offset=647, + page_categories=['page_categories_value'], + uri='uri_value', + referrer_uri='referrer_uri_value', + page_view_id='page_view_id_value', + ) + response = client.write_user_event(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.WriteUserEventRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, user_event.UserEvent) + assert response.event_type == 'event_type_value' + assert response.visitor_id == 'visitor_id_value' + assert response.session_id == 'session_id_value' + assert response.experiment_ids == ['experiment_ids_value'] + assert response.attribution_token == 'attribution_token_value' + assert response.cart_id == 'cart_id_value' + assert response.search_query == 'search_query_value' + assert response.filter == 'filter_value' + assert response.order_by == 'order_by_value' + assert response.offset == 647 + assert response.page_categories == ['page_categories_value'] + assert response.uri == 'uri_value' + assert response.referrer_uri == 'referrer_uri_value' + assert response.page_view_id == 'page_view_id_value' + + +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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_user_event), + '__call__') as call: + client.write_user_event() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.WriteUserEventRequest() + + +@pytest.mark.asyncio +async def test_write_user_event_async(transport: str = 'grpc_asyncio', request_type=user_event_service.WriteUserEventRequest): + client = UserEventServiceAsyncClient( + 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.write_user_event), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(user_event.UserEvent( + event_type='event_type_value', + visitor_id='visitor_id_value', + session_id='session_id_value', + experiment_ids=['experiment_ids_value'], + attribution_token='attribution_token_value', + cart_id='cart_id_value', + search_query='search_query_value', + filter='filter_value', + order_by='order_by_value', + offset=647, + page_categories=['page_categories_value'], + uri='uri_value', + referrer_uri='referrer_uri_value', + page_view_id='page_view_id_value', + )) + response = await client.write_user_event(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.WriteUserEventRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, user_event.UserEvent) + assert response.event_type == 'event_type_value' + assert response.visitor_id == 'visitor_id_value' + assert response.session_id == 'session_id_value' + assert response.experiment_ids == ['experiment_ids_value'] + assert response.attribution_token == 'attribution_token_value' + assert response.cart_id == 'cart_id_value' + assert response.search_query == 'search_query_value' + assert response.filter == 'filter_value' + assert response.order_by == 'order_by_value' + assert response.offset == 647 + assert response.page_categories == ['page_categories_value'] + assert response.uri == 'uri_value' + assert response.referrer_uri == 'referrer_uri_value' + assert response.page_view_id == 'page_view_id_value' + + +@pytest.mark.asyncio +async def test_write_user_event_async_from_dict(): + await test_write_user_event_async(request_type=dict) + + +def test_write_user_event_field_headers(): + 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. + request = user_event_service.WriteUserEventRequest() + + request.parent = 'parent/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_user_event), + '__call__') as call: + call.return_value = user_event.UserEvent() + client.write_user_event(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent/value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_write_user_event_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = user_event_service.WriteUserEventRequest() + + request.parent = 'parent/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_user_event), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(user_event.UserEvent()) + await client.write_user_event(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent/value', + ) in kw['metadata'] + + +@pytest.mark.parametrize("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, + ) + + # 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.collect_user_event), + '__call__') 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', + ) + response = client.collect_user_event(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.CollectUserEventRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, httpbody_pb2.HttpBody) + assert response.content_type == 'content_type_value' + assert response.data == b'data_blob' + + +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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.collect_user_event), + '__call__') as call: + client.collect_user_event() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.CollectUserEventRequest() + + +@pytest.mark.asyncio +async def test_collect_user_event_async(transport: str = 'grpc_asyncio', request_type=user_event_service.CollectUserEventRequest): + client = UserEventServiceAsyncClient( + 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.collect_user_event), + '__call__') 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', + )) + response = await client.collect_user_event(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.CollectUserEventRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, httpbody_pb2.HttpBody) + assert response.content_type == 'content_type_value' + assert response.data == b'data_blob' + + +@pytest.mark.asyncio +async def test_collect_user_event_async_from_dict(): + await test_collect_user_event_async(request_type=dict) + + +def test_collect_user_event_field_headers(): + 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. + request = user_event_service.CollectUserEventRequest() + + request.parent = 'parent/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.collect_user_event), + '__call__') as call: + call.return_value = httpbody_pb2.HttpBody() + client.collect_user_event(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent/value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_collect_user_event_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = user_event_service.CollectUserEventRequest() + + request.parent = 'parent/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.collect_user_event), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(httpbody_pb2.HttpBody()) + await client.collect_user_event(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent/value', + ) in kw['metadata'] + + +@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, + ) + + # 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.purge_user_events), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.purge_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == purge_config.PurgeUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_user_events), + '__call__') as call: + client.purge_user_events() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == purge_config.PurgeUserEventsRequest() + + +@pytest.mark.asyncio +async def test_purge_user_events_async(transport: str = 'grpc_asyncio', request_type=purge_config.PurgeUserEventsRequest): + client = UserEventServiceAsyncClient( + 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.purge_user_events), + '__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.purge_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == purge_config.PurgeUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_purge_user_events_async_from_dict(): + await test_purge_user_events_async(request_type=dict) + + +def test_purge_user_events_field_headers(): + 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. + request = purge_config.PurgeUserEventsRequest() + + request.parent = 'parent/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_user_events), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.purge_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent/value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_purge_user_events_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = purge_config.PurgeUserEventsRequest() + + request.parent = 'parent/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_user_events), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.purge_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent/value', + ) in kw['metadata'] + + +@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, + ) + + # 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.import_user_events), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.import_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_user_events), + '__call__') as call: + client.import_user_events() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportUserEventsRequest() + + +@pytest.mark.asyncio +async def test_import_user_events_async(transport: str = 'grpc_asyncio', request_type=import_config.ImportUserEventsRequest): + client = UserEventServiceAsyncClient( + 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.import_user_events), + '__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.import_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_import_user_events_async_from_dict(): + await test_import_user_events_async(request_type=dict) + + +def test_import_user_events_field_headers(): + 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. + request = import_config.ImportUserEventsRequest() + + request.parent = 'parent/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_user_events), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.import_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent/value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_import_user_events_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = import_config.ImportUserEventsRequest() + + request.parent = 'parent/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_user_events), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.import_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent/value', + ) in kw['metadata'] + + +@pytest.mark.parametrize("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, + ) + + # 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.rejoin_user_events), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.rejoin_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.RejoinUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +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', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.rejoin_user_events), + '__call__') as call: + client.rejoin_user_events() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.RejoinUserEventsRequest() + + +@pytest.mark.asyncio +async def test_rejoin_user_events_async(transport: str = 'grpc_asyncio', request_type=user_event_service.RejoinUserEventsRequest): + client = UserEventServiceAsyncClient( + 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.rejoin_user_events), + '__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.rejoin_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.RejoinUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_rejoin_user_events_async_from_dict(): + await test_rejoin_user_events_async(request_type=dict) + + +def test_rejoin_user_events_field_headers(): + 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. + request = user_event_service.RejoinUserEventsRequest() + + request.parent = 'parent/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.rejoin_user_events), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.rejoin_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent/value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_rejoin_user_events_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = user_event_service.RejoinUserEventsRequest() + + request.parent = 'parent/value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.rejoin_user_events), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.rejoin_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent/value', + ) in kw['metadata'] + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = UserEventServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = UserEventServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = UserEventServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = UserEventServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = UserEventServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.UserEventServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.UserEventServiceGrpcTransport, + transports.UserEventServiceGrpcAsyncIOTransport, +]) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + +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, + ) + +def test_user_event_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.UserEventServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_user_event_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2.services.user_event_service.transports.UserEventServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.UserEventServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'write_user_event', + 'collect_user_event', + 'purge_user_events', + 'import_user_events', + 'rejoin_user_events', + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + +def test_user_event_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('google.cloud.retail_v2.services.user_event_service.transports.UserEventServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.UserEventServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with("credentials.json", + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id="octopus", + ) + + +def test_user_event_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, 'default', autospec=True) as adc, mock.patch('google.cloud.retail_v2.services.user_event_service.transports.UserEventServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.UserEventServiceTransport() + adc.assert_called_once() + + +def test_user_event_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + UserEventServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.UserEventServiceGrpcTransport, + transports.UserEventServiceGrpcAsyncIOTransport, + ], +) +def test_user_event_service_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=( 'https://www.googleapis.com/auth/cloud-platform',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.UserEventServiceGrpcTransport, grpc_helpers), + (transports.UserEventServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_user_event_service_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class( + quota_project_id="octopus", + scopes=["1", "2"] + ) + + create_channel.assert_called_with( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.UserEventServiceGrpcTransport, transports.UserEventServiceGrpcAsyncIOTransport]) +def test_user_event_service_grpc_transport_client_cert_source_for_mtls( + transport_class +): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, + private_key=expected_key + ) + + +def test_user_event_service_host_no_port(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + ) + assert client.transport._host == 'retail.googleapis.com:443' + + +def test_user_event_service_host_with_port(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + ) + assert client.transport._host == 'retail.googleapis.com:8000' + +def test_user_event_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.UserEventServiceGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_user_event_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.UserEventServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.UserEventServiceGrpcTransport, transports.UserEventServiceGrpcAsyncIOTransport]) +def test_user_event_service_transport_channel_mtls_with_client_cert_source( + transport_class +): + with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.UserEventServiceGrpcTransport, transports.UserEventServiceGrpcAsyncIOTransport]) +def test_user_event_service_transport_channel_mtls_with_adc( + transport_class +): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_user_event_service_grpc_lro_client(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_user_event_service_grpc_lro_async_client(): + client = UserEventServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc_asyncio', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsAsyncClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_catalog_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = UserEventServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = UserEventServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_product_path(): + project = "cuttlefish" + location = "mussel" + catalog = "winkle" + branch = "nautilus" + product = "scallop" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, product=product, ) + actual = UserEventServiceClient.product_path(project, location, catalog, branch, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "abalone", + "location": "squid", + "catalog": "clam", + "branch": "whelk", + "product": "octopus", + } + path = UserEventServiceClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_product_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "oyster" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = UserEventServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "nudibranch", + } + path = UserEventServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "cuttlefish" + expected = "folders/{folder}".format(folder=folder, ) + actual = UserEventServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "mussel", + } + path = UserEventServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "winkle" + expected = "organizations/{organization}".format(organization=organization, ) + actual = UserEventServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nautilus", + } + path = UserEventServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "scallop" + expected = "projects/{project}".format(project=project, ) + actual = UserEventServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "abalone", + } + path = UserEventServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "squid" + location = "clam" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = UserEventServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "whelk", + "location": "octopus", + } + path = UserEventServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object(transports.UserEventServiceTransport, '_prep_wrapped_messages') as prep: + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.UserEventServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = UserEventServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = UserEventServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + with mock.patch.object(type(getattr(client.transport, "grpc_channel")), "close") as close: + async with client: + close.assert_not_called() + close.assert_called_once() + +def test_transport_close(): + transports = { + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + with mock.patch.object(type(getattr(client.transport, close_name)), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + +def test_client_ctx(): + transports = [ + 'grpc', + ] + for transport in transports: + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + +@pytest.mark.parametrize("client_class,transport_class", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport), +]) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) From b11f7607b8d5a0e20ce94df163ab68956371a818 Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Mon, 24 Jan 2022 20:13:04 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- .../services/catalog_service/async_client.py | 38 +- .../services/catalog_service/client.py | 127 +- .../completion_service/async_client.py | 38 +- .../services/completion_service/client.py | 127 +- .../prediction_service/async_client.py | 38 +- .../services/prediction_service/client.py | 127 +- .../services/product_service/async_client.py | 38 +- .../services/product_service/client.py | 127 +- .../services/search_service/async_client.py | 38 +- .../services/search_service/client.py | 127 +- .../user_event_service/async_client.py | 38 +- .../services/user_event_service/client.py | 127 +- owl-bot-staging/v2/.coveragerc | 17 - owl-bot-staging/v2/MANIFEST.in | 2 - owl-bot-staging/v2/README.rst | 49 - owl-bot-staging/v2/docs/conf.py | 376 -- owl-bot-staging/v2/docs/index.rst | 7 - .../v2/docs/retail_v2/catalog_service.rst | 10 - .../v2/docs/retail_v2/completion_service.rst | 6 - .../v2/docs/retail_v2/prediction_service.rst | 6 - .../v2/docs/retail_v2/product_service.rst | 10 - .../v2/docs/retail_v2/search_service.rst | 10 - .../v2/docs/retail_v2/services.rst | 11 - owl-bot-staging/v2/docs/retail_v2/types.rst | 7 - .../v2/docs/retail_v2/user_event_service.rst | 6 - .../v2/google/cloud/retail/__init__.py | 179 - .../v2/google/cloud/retail/py.typed | 2 - .../v2/google/cloud/retail_v2/__init__.py | 180 - .../cloud/retail_v2/gapic_metadata.json | 313 -- .../v2/google/cloud/retail_v2/py.typed | 2 - .../cloud/retail_v2/services/__init__.py | 15 - .../services/catalog_service/__init__.py | 22 - .../services/catalog_service/async_client.py | 587 --- .../services/catalog_service/client.py | 792 ---- .../services/catalog_service/pagers.py | 140 - .../catalog_service/transports/__init__.py | 33 - .../catalog_service/transports/base.py | 189 - .../catalog_service/transports/grpc.py | 381 -- .../transports/grpc_asyncio.py | 385 -- .../services/completion_service/__init__.py | 22 - .../completion_service/async_client.py | 346 -- .../services/completion_service/client.py | 544 --- .../completion_service/transports/__init__.py | 33 - .../completion_service/transports/base.py | 167 - .../completion_service/transports/grpc.py | 318 -- .../transports/grpc_asyncio.py | 322 -- .../services/prediction_service/__init__.py | 22 - .../prediction_service/async_client.py | 255 -- .../services/prediction_service/client.py | 452 --- .../prediction_service/transports/__init__.py | 33 - .../prediction_service/transports/base.py | 145 - .../prediction_service/transports/grpc.py | 254 -- .../transports/grpc_asyncio.py | 258 -- .../services/product_service/__init__.py | 22 - .../services/product_service/async_client.py | 1190 ------ .../services/product_service/client.py | 1389 ------- .../services/product_service/pagers.py | 140 - .../product_service/transports/__init__.py | 33 - .../product_service/transports/base.py | 275 -- .../product_service/transports/grpc.py | 574 --- .../transports/grpc_asyncio.py | 578 --- .../services/search_service/__init__.py | 22 - .../services/search_service/async_client.py | 286 -- .../services/search_service/client.py | 492 --- .../services/search_service/pagers.py | 139 - .../search_service/transports/__init__.py | 33 - .../search_service/transports/base.py | 145 - .../search_service/transports/grpc.py | 264 -- .../search_service/transports/grpc_asyncio.py | 268 -- .../services/user_event_service/__init__.py | 22 - .../user_event_service/async_client.py | 610 --- .../services/user_event_service/client.py | 806 ---- .../user_event_service/transports/__init__.py | 33 - .../user_event_service/transports/base.py | 226 -- .../user_event_service/transports/grpc.py | 406 -- .../transports/grpc_asyncio.py | 410 -- .../google/cloud/retail_v2/types/__init__.py | 178 - .../google/cloud/retail_v2/types/catalog.py | 130 - .../cloud/retail_v2/types/catalog_service.py | 235 -- .../v2/google/cloud/retail_v2/types/common.py | 651 --- .../retail_v2/types/completion_service.py | 218 - .../cloud/retail_v2/types/import_config.py | 677 ---- .../retail_v2/types/prediction_service.py | 260 -- .../google/cloud/retail_v2/types/product.py | 689 ---- .../cloud/retail_v2/types/product_service.py | 654 --- .../cloud/retail_v2/types/purge_config.py | 107 - .../cloud/retail_v2/types/search_service.py | 1001 ----- .../cloud/retail_v2/types/user_event.py | 492 --- .../retail_v2/types/user_event_service.py | 154 - owl-bot-staging/v2/mypy.ini | 3 - owl-bot-staging/v2/noxfile.py | 132 - .../v2/scripts/fixup_retail_v2_keywords.py | 197 - owl-bot-staging/v2/setup.py | 54 - owl-bot-staging/v2/tests/__init__.py | 16 - owl-bot-staging/v2/tests/unit/__init__.py | 16 - .../v2/tests/unit/gapic/__init__.py | 16 - .../v2/tests/unit/gapic/retail_v2/__init__.py | 16 - .../gapic/retail_v2/test_catalog_service.py | 2184 ---------- .../retail_v2/test_completion_service.py | 1357 ------- .../retail_v2/test_prediction_service.py | 1184 ------ .../gapic/retail_v2/test_product_service.py | 3551 ----------------- .../gapic/retail_v2/test_search_service.py | 1398 ------- .../retail_v2/test_user_event_service.py | 1896 --------- .../gapic/retail_v2/test_catalog_service.py | 128 + .../retail_v2/test_completion_service.py | 131 + .../retail_v2/test_prediction_service.py | 131 + .../gapic/retail_v2/test_product_service.py | 128 + .../gapic/retail_v2/test_search_service.py | 128 + .../retail_v2/test_user_event_service.py | 128 + 109 files changed, 1500 insertions(+), 33001 deletions(-) delete mode 100644 owl-bot-staging/v2/.coveragerc delete mode 100644 owl-bot-staging/v2/MANIFEST.in delete mode 100644 owl-bot-staging/v2/README.rst delete mode 100644 owl-bot-staging/v2/docs/conf.py delete mode 100644 owl-bot-staging/v2/docs/index.rst delete mode 100644 owl-bot-staging/v2/docs/retail_v2/catalog_service.rst delete mode 100644 owl-bot-staging/v2/docs/retail_v2/completion_service.rst delete mode 100644 owl-bot-staging/v2/docs/retail_v2/prediction_service.rst delete mode 100644 owl-bot-staging/v2/docs/retail_v2/product_service.rst delete mode 100644 owl-bot-staging/v2/docs/retail_v2/search_service.rst delete mode 100644 owl-bot-staging/v2/docs/retail_v2/services.rst delete mode 100644 owl-bot-staging/v2/docs/retail_v2/types.rst delete mode 100644 owl-bot-staging/v2/docs/retail_v2/user_event_service.rst delete mode 100644 owl-bot-staging/v2/google/cloud/retail/__init__.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail/py.typed delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/__init__.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/gapic_metadata.json delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/py.typed delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/__init__.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/__init__.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/async_client.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/client.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/pagers.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/__init__.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/base.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc_asyncio.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/__init__.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/async_client.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/client.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/__init__.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/base.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc_asyncio.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/__init__.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/async_client.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/client.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/__init__.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/base.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc_asyncio.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/__init__.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/async_client.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/client.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/pagers.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/__init__.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/base.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc_asyncio.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/__init__.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/async_client.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/client.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/pagers.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/__init__.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/base.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc_asyncio.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/__init__.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/async_client.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/client.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/__init__.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/base.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc_asyncio.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/__init__.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/catalog.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/catalog_service.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/common.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/completion_service.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/import_config.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/prediction_service.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/product.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/product_service.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/purge_config.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/search_service.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/user_event.py delete mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/user_event_service.py delete mode 100644 owl-bot-staging/v2/mypy.ini delete mode 100644 owl-bot-staging/v2/noxfile.py delete mode 100644 owl-bot-staging/v2/scripts/fixup_retail_v2_keywords.py delete mode 100644 owl-bot-staging/v2/setup.py delete mode 100644 owl-bot-staging/v2/tests/__init__.py delete mode 100644 owl-bot-staging/v2/tests/unit/__init__.py delete mode 100644 owl-bot-staging/v2/tests/unit/gapic/__init__.py delete mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/__init__.py delete mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_catalog_service.py delete mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_completion_service.py delete mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_prediction_service.py delete mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_product_service.py delete mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_search_service.py delete mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_user_event_service.py 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 2dd8181b..f794eaa6 100644 --- a/google/cloud/retail_v2/services/catalog_service/async_client.py +++ b/google/cloud/retail_v2/services/catalog_service/async_client.py @@ -16,7 +16,7 @@ from collections import OrderedDict import functools import re -from typing import Dict, Sequence, Tuple, Type, Union +from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources from google.api_core.client_options import ClientOptions @@ -112,6 +112,42 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CatalogServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + @property def transport(self) -> CatalogServiceTransport: """Returns the transport used by the client instance. diff --git a/google/cloud/retail_v2/services/catalog_service/client.py b/google/cloud/retail_v2/services/catalog_service/client.py index d4e80150..a29aa6dd 100644 --- a/google/cloud/retail_v2/services/catalog_service/client.py +++ b/google/cloud/retail_v2/services/catalog_service/client.py @@ -254,6 +254,73 @@ def parse_common_location_path(path: str) -> Dict[str, str]: m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) return m.groupdict() if m else {} + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + def __init__( self, *, @@ -304,57 +371,22 @@ def __init__( if client_options is None: client_options = client_options_lib.ClientOptions() - # Create SSL credentials for mutual TLS if needed. - if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( - "true", - "false", - ): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - use_client_cert = ( - os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source( + client_options ) - client_cert_source_func = None - is_mtls = False - if use_client_cert: - if client_options.client_cert_source: - is_mtls = True - client_cert_source_func = client_options.client_cert_source - else: - is_mtls = mtls.has_default_client_cert_source() - if is_mtls: - client_cert_source_func = mtls.default_client_cert_source() - else: - client_cert_source_func = None - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - else: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_mtls_env == "never": - api_endpoint = self.DEFAULT_ENDPOINT - elif use_mtls_env == "always": - api_endpoint = self.DEFAULT_MTLS_ENDPOINT - elif use_mtls_env == "auto": - if is_mtls: - api_endpoint = self.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = self.DEFAULT_ENDPOINT - else: - raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " - "values: never, auto, always" - ) + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError( + "client_options.api_key and credentials are mutually exclusive" + ) # Save or instantiate the transport. # Ordinarily, we provide the transport, but allowing a custom transport # instance provides an extensibility point for unusual situations. if isinstance(transport, CatalogServiceTransport): # transport is a CatalogServiceTransport instance. - if credentials or client_options.credentials_file: + if credentials or client_options.credentials_file or api_key_value: raise ValueError( "When providing a transport instance, " "provide its credentials directly." @@ -366,6 +398,15 @@ def __init__( ) self._transport = transport else: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + Transport = type(self).get_transport_class(transport) self._transport = Transport( credentials=credentials, 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 ace60f72..ccc69c90 100644 --- a/google/cloud/retail_v2/services/completion_service/async_client.py +++ b/google/cloud/retail_v2/services/completion_service/async_client.py @@ -16,7 +16,7 @@ from collections import OrderedDict import functools import re -from typing import Dict, Sequence, Tuple, Type, Union +from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources from google.api_core.client_options import ClientOptions @@ -114,6 +114,42 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CompletionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + @property def transport(self) -> CompletionServiceTransport: """Returns the transport used by the client instance. diff --git a/google/cloud/retail_v2/services/completion_service/client.py b/google/cloud/retail_v2/services/completion_service/client.py index 755181e1..a6b14eb1 100644 --- a/google/cloud/retail_v2/services/completion_service/client.py +++ b/google/cloud/retail_v2/services/completion_service/client.py @@ -244,6 +244,73 @@ def parse_common_location_path(path: str) -> Dict[str, str]: m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) return m.groupdict() if m else {} + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + def __init__( self, *, @@ -294,57 +361,22 @@ def __init__( if client_options is None: client_options = client_options_lib.ClientOptions() - # Create SSL credentials for mutual TLS if needed. - if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( - "true", - "false", - ): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - use_client_cert = ( - os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source( + client_options ) - client_cert_source_func = None - is_mtls = False - if use_client_cert: - if client_options.client_cert_source: - is_mtls = True - client_cert_source_func = client_options.client_cert_source - else: - is_mtls = mtls.has_default_client_cert_source() - if is_mtls: - client_cert_source_func = mtls.default_client_cert_source() - else: - client_cert_source_func = None - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - else: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_mtls_env == "never": - api_endpoint = self.DEFAULT_ENDPOINT - elif use_mtls_env == "always": - api_endpoint = self.DEFAULT_MTLS_ENDPOINT - elif use_mtls_env == "auto": - if is_mtls: - api_endpoint = self.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = self.DEFAULT_ENDPOINT - else: - raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " - "values: never, auto, always" - ) + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError( + "client_options.api_key and credentials are mutually exclusive" + ) # Save or instantiate the transport. # Ordinarily, we provide the transport, but allowing a custom transport # instance provides an extensibility point for unusual situations. if isinstance(transport, CompletionServiceTransport): # transport is a CompletionServiceTransport instance. - if credentials or client_options.credentials_file: + if credentials or client_options.credentials_file or api_key_value: raise ValueError( "When providing a transport instance, " "provide its credentials directly." @@ -356,6 +388,15 @@ def __init__( ) self._transport = transport else: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + Transport = type(self).get_transport_class(transport) self._transport = Transport( credentials=credentials, 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 0b52c1e8..ab312589 100644 --- a/google/cloud/retail_v2/services/prediction_service/async_client.py +++ b/google/cloud/retail_v2/services/prediction_service/async_client.py @@ -16,7 +16,7 @@ from collections import OrderedDict import functools import re -from typing import Dict, Sequence, Tuple, Type, Union +from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources from google.api_core.client_options import ClientOptions @@ -105,6 +105,42 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return PredictionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + @property def transport(self) -> PredictionServiceTransport: """Returns the transport used by the client instance. diff --git a/google/cloud/retail_v2/services/prediction_service/client.py b/google/cloud/retail_v2/services/prediction_service/client.py index bb10f758..47b8f3b2 100644 --- a/google/cloud/retail_v2/services/prediction_service/client.py +++ b/google/cloud/retail_v2/services/prediction_service/client.py @@ -241,6 +241,73 @@ def parse_common_location_path(path: str) -> Dict[str, str]: m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) return m.groupdict() if m else {} + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + def __init__( self, *, @@ -291,57 +358,22 @@ def __init__( if client_options is None: client_options = client_options_lib.ClientOptions() - # Create SSL credentials for mutual TLS if needed. - if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( - "true", - "false", - ): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - use_client_cert = ( - os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source( + client_options ) - client_cert_source_func = None - is_mtls = False - if use_client_cert: - if client_options.client_cert_source: - is_mtls = True - client_cert_source_func = client_options.client_cert_source - else: - is_mtls = mtls.has_default_client_cert_source() - if is_mtls: - client_cert_source_func = mtls.default_client_cert_source() - else: - client_cert_source_func = None - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - else: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_mtls_env == "never": - api_endpoint = self.DEFAULT_ENDPOINT - elif use_mtls_env == "always": - api_endpoint = self.DEFAULT_MTLS_ENDPOINT - elif use_mtls_env == "auto": - if is_mtls: - api_endpoint = self.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = self.DEFAULT_ENDPOINT - else: - raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " - "values: never, auto, always" - ) + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError( + "client_options.api_key and credentials are mutually exclusive" + ) # Save or instantiate the transport. # Ordinarily, we provide the transport, but allowing a custom transport # instance provides an extensibility point for unusual situations. if isinstance(transport, PredictionServiceTransport): # transport is a PredictionServiceTransport instance. - if credentials or client_options.credentials_file: + if credentials or client_options.credentials_file or api_key_value: raise ValueError( "When providing a transport instance, " "provide its credentials directly." @@ -353,6 +385,15 @@ def __init__( ) self._transport = transport else: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + Transport = type(self).get_transport_class(transport) self._transport = Transport( credentials=credentials, 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 e8790c60..8d12b92c 100644 --- a/google/cloud/retail_v2/services/product_service/async_client.py +++ b/google/cloud/retail_v2/services/product_service/async_client.py @@ -16,7 +16,7 @@ from collections import OrderedDict import functools import re -from typing import Dict, Sequence, Tuple, Type, Union +from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources from google.api_core.client_options import ClientOptions @@ -120,6 +120,42 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ProductServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + @property def transport(self) -> ProductServiceTransport: """Returns the transport used by the client instance. diff --git a/google/cloud/retail_v2/services/product_service/client.py b/google/cloud/retail_v2/services/product_service/client.py index 0b694e29..aefdc866 100644 --- a/google/cloud/retail_v2/services/product_service/client.py +++ b/google/cloud/retail_v2/services/product_service/client.py @@ -268,6 +268,73 @@ def parse_common_location_path(path: str) -> Dict[str, str]: m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) return m.groupdict() if m else {} + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + def __init__( self, *, @@ -318,57 +385,22 @@ def __init__( if client_options is None: client_options = client_options_lib.ClientOptions() - # Create SSL credentials for mutual TLS if needed. - if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( - "true", - "false", - ): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - use_client_cert = ( - os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source( + client_options ) - client_cert_source_func = None - is_mtls = False - if use_client_cert: - if client_options.client_cert_source: - is_mtls = True - client_cert_source_func = client_options.client_cert_source - else: - is_mtls = mtls.has_default_client_cert_source() - if is_mtls: - client_cert_source_func = mtls.default_client_cert_source() - else: - client_cert_source_func = None - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - else: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_mtls_env == "never": - api_endpoint = self.DEFAULT_ENDPOINT - elif use_mtls_env == "always": - api_endpoint = self.DEFAULT_MTLS_ENDPOINT - elif use_mtls_env == "auto": - if is_mtls: - api_endpoint = self.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = self.DEFAULT_ENDPOINT - else: - raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " - "values: never, auto, always" - ) + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError( + "client_options.api_key and credentials are mutually exclusive" + ) # Save or instantiate the transport. # Ordinarily, we provide the transport, but allowing a custom transport # instance provides an extensibility point for unusual situations. if isinstance(transport, ProductServiceTransport): # transport is a ProductServiceTransport instance. - if credentials or client_options.credentials_file: + if credentials or client_options.credentials_file or api_key_value: raise ValueError( "When providing a transport instance, " "provide its credentials directly." @@ -380,6 +412,15 @@ def __init__( ) self._transport = transport else: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + Transport = type(self).get_transport_class(transport) self._transport = Transport( credentials=credentials, 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 d88d199d..3321e0e4 100644 --- a/google/cloud/retail_v2/services/search_service/async_client.py +++ b/google/cloud/retail_v2/services/search_service/async_client.py @@ -16,7 +16,7 @@ from collections import OrderedDict import functools import re -from typing import Dict, Sequence, Tuple, Type, Union +from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources from google.api_core.client_options import ClientOptions @@ -114,6 +114,42 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return SearchServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + @property def transport(self) -> SearchServiceTransport: """Returns the transport used by the client instance. diff --git a/google/cloud/retail_v2/services/search_service/client.py b/google/cloud/retail_v2/services/search_service/client.py index 5dee1c9a..ca4af13d 100644 --- a/google/cloud/retail_v2/services/search_service/client.py +++ b/google/cloud/retail_v2/services/search_service/client.py @@ -260,6 +260,73 @@ def parse_common_location_path(path: str) -> Dict[str, str]: m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) return m.groupdict() if m else {} + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + def __init__( self, *, @@ -310,57 +377,22 @@ def __init__( if client_options is None: client_options = client_options_lib.ClientOptions() - # Create SSL credentials for mutual TLS if needed. - if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( - "true", - "false", - ): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - use_client_cert = ( - os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source( + client_options ) - client_cert_source_func = None - is_mtls = False - if use_client_cert: - if client_options.client_cert_source: - is_mtls = True - client_cert_source_func = client_options.client_cert_source - else: - is_mtls = mtls.has_default_client_cert_source() - if is_mtls: - client_cert_source_func = mtls.default_client_cert_source() - else: - client_cert_source_func = None - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - else: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_mtls_env == "never": - api_endpoint = self.DEFAULT_ENDPOINT - elif use_mtls_env == "always": - api_endpoint = self.DEFAULT_MTLS_ENDPOINT - elif use_mtls_env == "auto": - if is_mtls: - api_endpoint = self.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = self.DEFAULT_ENDPOINT - else: - raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " - "values: never, auto, always" - ) + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError( + "client_options.api_key and credentials are mutually exclusive" + ) # Save or instantiate the transport. # Ordinarily, we provide the transport, but allowing a custom transport # instance provides an extensibility point for unusual situations. if isinstance(transport, SearchServiceTransport): # transport is a SearchServiceTransport instance. - if credentials or client_options.credentials_file: + if credentials or client_options.credentials_file or api_key_value: raise ValueError( "When providing a transport instance, " "provide its credentials directly." @@ -372,6 +404,15 @@ def __init__( ) self._transport = transport else: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + Transport = type(self).get_transport_class(transport) self._transport = Transport( credentials=credentials, 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 986ac748..6ff57bd1 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 @@ -16,7 +16,7 @@ from collections import OrderedDict import functools import re -from typing import Dict, Sequence, Tuple, Type, Union +from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources from google.api_core.client_options import ClientOptions @@ -118,6 +118,42 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return UserEventServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + @property def transport(self) -> UserEventServiceTransport: """Returns the transport used by the client instance. 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 5d70cf57..915d13c5 100644 --- a/google/cloud/retail_v2/services/user_event_service/client.py +++ b/google/cloud/retail_v2/services/user_event_service/client.py @@ -266,6 +266,73 @@ def parse_common_location_path(path: str) -> Dict[str, str]: m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) return m.groupdict() if m else {} + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + def __init__( self, *, @@ -316,57 +383,22 @@ def __init__( if client_options is None: client_options = client_options_lib.ClientOptions() - # Create SSL credentials for mutual TLS if needed. - if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( - "true", - "false", - ): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - use_client_cert = ( - os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source( + client_options ) - client_cert_source_func = None - is_mtls = False - if use_client_cert: - if client_options.client_cert_source: - is_mtls = True - client_cert_source_func = client_options.client_cert_source - else: - is_mtls = mtls.has_default_client_cert_source() - if is_mtls: - client_cert_source_func = mtls.default_client_cert_source() - else: - client_cert_source_func = None - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - else: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_mtls_env == "never": - api_endpoint = self.DEFAULT_ENDPOINT - elif use_mtls_env == "always": - api_endpoint = self.DEFAULT_MTLS_ENDPOINT - elif use_mtls_env == "auto": - if is_mtls: - api_endpoint = self.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = self.DEFAULT_ENDPOINT - else: - raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " - "values: never, auto, always" - ) + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError( + "client_options.api_key and credentials are mutually exclusive" + ) # Save or instantiate the transport. # Ordinarily, we provide the transport, but allowing a custom transport # instance provides an extensibility point for unusual situations. if isinstance(transport, UserEventServiceTransport): # transport is a UserEventServiceTransport instance. - if credentials or client_options.credentials_file: + if credentials or client_options.credentials_file or api_key_value: raise ValueError( "When providing a transport instance, " "provide its credentials directly." @@ -378,6 +410,15 @@ def __init__( ) self._transport = transport else: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + Transport = type(self).get_transport_class(transport) self._transport = Transport( credentials=credentials, diff --git a/owl-bot-staging/v2/.coveragerc b/owl-bot-staging/v2/.coveragerc deleted file mode 100644 index a8b114f0..00000000 --- a/owl-bot-staging/v2/.coveragerc +++ /dev/null @@ -1,17 +0,0 @@ -[run] -branch = True - -[report] -show_missing = True -omit = - google/cloud/retail/__init__.py -exclude_lines = - # Re-enable the standard pragma - pragma: NO COVER - # Ignore debug-only repr - def __repr__ - # Ignore pkg_resources exceptions. - # This is added at the module level as a safeguard for if someone - # generates the code and tries to run it without pip installing. This - # makes it virtually impossible to test properly. - except pkg_resources.DistributionNotFound diff --git a/owl-bot-staging/v2/MANIFEST.in b/owl-bot-staging/v2/MANIFEST.in deleted file mode 100644 index 985b915c..00000000 --- a/owl-bot-staging/v2/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -recursive-include google/cloud/retail *.py -recursive-include google/cloud/retail_v2 *.py diff --git a/owl-bot-staging/v2/README.rst b/owl-bot-staging/v2/README.rst deleted file mode 100644 index cb039760..00000000 --- a/owl-bot-staging/v2/README.rst +++ /dev/null @@ -1,49 +0,0 @@ -Python Client for Google Cloud Retail API -================================================= - -Quick Start ------------ - -In order to use this library, you first need to go through the following steps: - -1. `Select or create a Cloud Platform project.`_ -2. `Enable billing for your project.`_ -3. Enable the Google Cloud Retail API. -4. `Setup Authentication.`_ - -.. _Select or create a Cloud Platform project.: https://console.cloud.google.com/project -.. _Enable billing for your project.: https://cloud.google.com/billing/docs/how-to/modify-project#enable_billing_for_a_project -.. _Setup Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html - -Installation -~~~~~~~~~~~~ - -Install this library in a `virtualenv`_ using pip. `virtualenv`_ is a tool to -create isolated Python environments. The basic problem it addresses is one of -dependencies and versions, and indirectly permissions. - -With `virtualenv`_, it's possible to install this library without needing system -install permissions, and without clashing with the installed system -dependencies. - -.. _`virtualenv`: https://virtualenv.pypa.io/en/latest/ - - -Mac/Linux -^^^^^^^^^ - -.. code-block:: console - - python3 -m venv - source /bin/activate - /bin/pip install /path/to/library - - -Windows -^^^^^^^ - -.. code-block:: console - - python3 -m venv - \Scripts\activate - \Scripts\pip.exe install \path\to\library diff --git a/owl-bot-staging/v2/docs/conf.py b/owl-bot-staging/v2/docs/conf.py deleted file mode 100644 index 649b2123..00000000 --- a/owl-bot-staging/v2/docs/conf.py +++ /dev/null @@ -1,376 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -# google-cloud-retail documentation build configuration file -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys -import os -import shlex - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath("..")) - -__version__ = "0.1.0" - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -needs_sphinx = "1.6.3" - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - "sphinx.ext.autodoc", - "sphinx.ext.autosummary", - "sphinx.ext.intersphinx", - "sphinx.ext.coverage", - "sphinx.ext.napoleon", - "sphinx.ext.todo", - "sphinx.ext.viewcode", -] - -# autodoc/autosummary flags -autoclass_content = "both" -autodoc_default_flags = ["members"] -autosummary_generate = True - - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# Allow markdown includes (so releases.md can include CHANGLEOG.md) -# http://www.sphinx-doc.org/en/master/markdown.html -source_parsers = {".md": "recommonmark.parser.CommonMarkParser"} - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -source_suffix = [".rst", ".md"] - -# The encoding of source files. -# source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = "index" - -# General information about the project. -project = u"google-cloud-retail" -copyright = u"2020, Google, LLC" -author = u"Google APIs" # TODO: autogenerate this bit - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The full version, including alpha/beta/rc tags. -release = __version__ -# The short X.Y version. -version = ".".join(release.split(".")[0:2]) - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -# today = '' -# Else, today_fmt is used as the format for a strftime call. -# today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ["_build"] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -# default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -# add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -# add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -# show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = "sphinx" - -# A list of ignored prefixes for module index sorting. -# modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -# keep_warnings = False - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = True - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = "alabaster" - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -html_theme_options = { - "description": "Google Cloud Client Libraries for Python", - "github_user": "googleapis", - "github_repo": "google-cloud-python", - "github_banner": True, - "font_family": "'Roboto', Georgia, sans", - "head_font_family": "'Roboto', Georgia, serif", - "code_font_family": "'Roboto Mono', 'Consolas', monospace", -} - -# Add any paths that contain custom themes here, relative to this directory. -# html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -# html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -# html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -# html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -# html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -# html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -# html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -# html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -# html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -# html_additional_pages = {} - -# If false, no module index is generated. -# html_domain_indices = True - -# If false, no index is generated. -# html_use_index = True - -# If true, the index is split into individual pages for each letter. -# html_split_index = False - -# If true, links to the reST sources are added to the pages. -# html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -# html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -# html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -# html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -# html_file_suffix = None - -# Language to be used for generating the HTML full-text search index. -# Sphinx supports the following languages: -# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' -# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' -# html_search_language = 'en' - -# A dictionary with options for the search language support, empty by default. -# Now only 'ja' uses this config value -# html_search_options = {'type': 'default'} - -# The name of a javascript file (relative to the configuration directory) that -# implements a search results scorer. If empty, the default will be used. -# html_search_scorer = 'scorer.js' - -# Output file base name for HTML help builder. -htmlhelp_basename = "google-cloud-retail-doc" - -# -- Options for warnings ------------------------------------------------------ - - -suppress_warnings = [ - # Temporarily suppress this to avoid "more than one target found for - # cross-reference" warning, which are intractable for us to avoid while in - # a mono-repo. - # See https://github.com/sphinx-doc/sphinx/blob - # /2a65ffeef5c107c19084fabdd706cdff3f52d93c/sphinx/domains/python.py#L843 - "ref.python" -] - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # 'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). - # 'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. - # 'preamble': '', - # Latex figure (float) alignment - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - ( - master_doc, - "google-cloud-retail.tex", - u"google-cloud-retail Documentation", - author, - "manual", - ) -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -# latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -# latex_use_parts = False - -# If true, show page references after internal links. -# latex_show_pagerefs = False - -# If true, show URL addresses after external links. -# latex_show_urls = False - -# Documents to append as an appendix to all manuals. -# latex_appendices = [] - -# If false, no module index is generated. -# latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ( - master_doc, - "google-cloud-retail", - u"Google Cloud Retail Documentation", - [author], - 1, - ) -] - -# If true, show URL addresses after external links. -# man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ( - master_doc, - "google-cloud-retail", - u"google-cloud-retail Documentation", - author, - "google-cloud-retail", - "GAPIC library for Google Cloud Retail API", - "APIs", - ) -] - -# Documents to append as an appendix to all manuals. -# texinfo_appendices = [] - -# If false, no module index is generated. -# texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -# texinfo_no_detailmenu = False - - -# Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = { - "python": ("http://python.readthedocs.org/en/latest/", None), - "gax": ("https://gax-python.readthedocs.org/en/latest/", None), - "google-auth": ("https://google-auth.readthedocs.io/en/stable", None), - "google-gax": ("https://gax-python.readthedocs.io/en/latest/", None), - "google.api_core": ("https://googleapis.dev/python/google-api-core/latest/", None), - "grpc": ("https://grpc.io/grpc/python/", None), - "requests": ("http://requests.kennethreitz.org/en/stable/", None), - "proto": ("https://proto-plus-python.readthedocs.io/en/stable", None), - "protobuf": ("https://googleapis.dev/python/protobuf/latest/", None), -} - - -# Napoleon settings -napoleon_google_docstring = True -napoleon_numpy_docstring = True -napoleon_include_private_with_doc = False -napoleon_include_special_with_doc = True -napoleon_use_admonition_for_examples = False -napoleon_use_admonition_for_notes = False -napoleon_use_admonition_for_references = False -napoleon_use_ivar = False -napoleon_use_param = True -napoleon_use_rtype = True diff --git a/owl-bot-staging/v2/docs/index.rst b/owl-bot-staging/v2/docs/index.rst deleted file mode 100644 index c70f61bc..00000000 --- a/owl-bot-staging/v2/docs/index.rst +++ /dev/null @@ -1,7 +0,0 @@ -API Reference -------------- -.. toctree:: - :maxdepth: 2 - - retail_v2/services - retail_v2/types diff --git a/owl-bot-staging/v2/docs/retail_v2/catalog_service.rst b/owl-bot-staging/v2/docs/retail_v2/catalog_service.rst deleted file mode 100644 index 5b7227d9..00000000 --- a/owl-bot-staging/v2/docs/retail_v2/catalog_service.rst +++ /dev/null @@ -1,10 +0,0 @@ -CatalogService --------------------------------- - -.. automodule:: google.cloud.retail_v2.services.catalog_service - :members: - :inherited-members: - -.. automodule:: google.cloud.retail_v2.services.catalog_service.pagers - :members: - :inherited-members: diff --git a/owl-bot-staging/v2/docs/retail_v2/completion_service.rst b/owl-bot-staging/v2/docs/retail_v2/completion_service.rst deleted file mode 100644 index 551f89ed..00000000 --- a/owl-bot-staging/v2/docs/retail_v2/completion_service.rst +++ /dev/null @@ -1,6 +0,0 @@ -CompletionService ------------------------------------ - -.. automodule:: google.cloud.retail_v2.services.completion_service - :members: - :inherited-members: diff --git a/owl-bot-staging/v2/docs/retail_v2/prediction_service.rst b/owl-bot-staging/v2/docs/retail_v2/prediction_service.rst deleted file mode 100644 index 12ffb6ee..00000000 --- a/owl-bot-staging/v2/docs/retail_v2/prediction_service.rst +++ /dev/null @@ -1,6 +0,0 @@ -PredictionService ------------------------------------ - -.. automodule:: google.cloud.retail_v2.services.prediction_service - :members: - :inherited-members: diff --git a/owl-bot-staging/v2/docs/retail_v2/product_service.rst b/owl-bot-staging/v2/docs/retail_v2/product_service.rst deleted file mode 100644 index 0b8fa911..00000000 --- a/owl-bot-staging/v2/docs/retail_v2/product_service.rst +++ /dev/null @@ -1,10 +0,0 @@ -ProductService --------------------------------- - -.. automodule:: google.cloud.retail_v2.services.product_service - :members: - :inherited-members: - -.. automodule:: google.cloud.retail_v2.services.product_service.pagers - :members: - :inherited-members: diff --git a/owl-bot-staging/v2/docs/retail_v2/search_service.rst b/owl-bot-staging/v2/docs/retail_v2/search_service.rst deleted file mode 100644 index af72819d..00000000 --- a/owl-bot-staging/v2/docs/retail_v2/search_service.rst +++ /dev/null @@ -1,10 +0,0 @@ -SearchService -------------------------------- - -.. automodule:: google.cloud.retail_v2.services.search_service - :members: - :inherited-members: - -.. automodule:: google.cloud.retail_v2.services.search_service.pagers - :members: - :inherited-members: diff --git a/owl-bot-staging/v2/docs/retail_v2/services.rst b/owl-bot-staging/v2/docs/retail_v2/services.rst deleted file mode 100644 index f86138d7..00000000 --- a/owl-bot-staging/v2/docs/retail_v2/services.rst +++ /dev/null @@ -1,11 +0,0 @@ -Services for Google Cloud Retail v2 API -======================================= -.. toctree:: - :maxdepth: 2 - - catalog_service - completion_service - prediction_service - product_service - search_service - user_event_service diff --git a/owl-bot-staging/v2/docs/retail_v2/types.rst b/owl-bot-staging/v2/docs/retail_v2/types.rst deleted file mode 100644 index 54951beb..00000000 --- a/owl-bot-staging/v2/docs/retail_v2/types.rst +++ /dev/null @@ -1,7 +0,0 @@ -Types for Google Cloud Retail v2 API -==================================== - -.. automodule:: google.cloud.retail_v2.types - :members: - :undoc-members: - :show-inheritance: diff --git a/owl-bot-staging/v2/docs/retail_v2/user_event_service.rst b/owl-bot-staging/v2/docs/retail_v2/user_event_service.rst deleted file mode 100644 index 00e214a9..00000000 --- a/owl-bot-staging/v2/docs/retail_v2/user_event_service.rst +++ /dev/null @@ -1,6 +0,0 @@ -UserEventService ----------------------------------- - -.. automodule:: google.cloud.retail_v2.services.user_event_service - :members: - :inherited-members: diff --git a/owl-bot-staging/v2/google/cloud/retail/__init__.py b/owl-bot-staging/v2/google/cloud/retail/__init__.py deleted file mode 100644 index f2ff862d..00000000 --- a/owl-bot-staging/v2/google/cloud/retail/__init__.py +++ /dev/null @@ -1,179 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -from google.cloud.retail_v2.services.catalog_service.client import CatalogServiceClient -from google.cloud.retail_v2.services.catalog_service.async_client import CatalogServiceAsyncClient -from google.cloud.retail_v2.services.completion_service.client import CompletionServiceClient -from google.cloud.retail_v2.services.completion_service.async_client import CompletionServiceAsyncClient -from google.cloud.retail_v2.services.prediction_service.client import PredictionServiceClient -from google.cloud.retail_v2.services.prediction_service.async_client import PredictionServiceAsyncClient -from google.cloud.retail_v2.services.product_service.client import ProductServiceClient -from google.cloud.retail_v2.services.product_service.async_client import ProductServiceAsyncClient -from google.cloud.retail_v2.services.search_service.client import SearchServiceClient -from google.cloud.retail_v2.services.search_service.async_client import SearchServiceAsyncClient -from google.cloud.retail_v2.services.user_event_service.client import UserEventServiceClient -from google.cloud.retail_v2.services.user_event_service.async_client import UserEventServiceAsyncClient - -from google.cloud.retail_v2.types.catalog import Catalog -from google.cloud.retail_v2.types.catalog import ProductLevelConfig -from google.cloud.retail_v2.types.catalog_service import GetDefaultBranchRequest -from google.cloud.retail_v2.types.catalog_service import GetDefaultBranchResponse -from google.cloud.retail_v2.types.catalog_service import ListCatalogsRequest -from google.cloud.retail_v2.types.catalog_service import ListCatalogsResponse -from google.cloud.retail_v2.types.catalog_service import SetDefaultBranchRequest -from google.cloud.retail_v2.types.catalog_service import UpdateCatalogRequest -from google.cloud.retail_v2.types.common import Audience -from google.cloud.retail_v2.types.common import ColorInfo -from google.cloud.retail_v2.types.common import CustomAttribute -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 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 -from google.cloud.retail_v2.types.completion_service import CompleteQueryResponse -from google.cloud.retail_v2.types.import_config import BigQuerySource -from google.cloud.retail_v2.types.import_config import CompletionDataInputConfig -from google.cloud.retail_v2.types.import_config import GcsSource -from google.cloud.retail_v2.types.import_config import ImportCompletionDataRequest -from google.cloud.retail_v2.types.import_config import ImportCompletionDataResponse -from google.cloud.retail_v2.types.import_config import ImportErrorsConfig -from google.cloud.retail_v2.types.import_config import ImportMetadata -from google.cloud.retail_v2.types.import_config import ImportProductsRequest -from google.cloud.retail_v2.types.import_config import ImportProductsResponse -from google.cloud.retail_v2.types.import_config import ImportUserEventsRequest -from google.cloud.retail_v2.types.import_config import ImportUserEventsResponse -from google.cloud.retail_v2.types.import_config import ProductInlineSource -from google.cloud.retail_v2.types.import_config import ProductInputConfig -from google.cloud.retail_v2.types.import_config import UserEventImportSummary -from google.cloud.retail_v2.types.import_config import UserEventInlineSource -from google.cloud.retail_v2.types.import_config import UserEventInputConfig -from google.cloud.retail_v2.types.prediction_service import PredictRequest -from google.cloud.retail_v2.types.prediction_service import PredictResponse -from google.cloud.retail_v2.types.product import Product -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 CreateProductRequest -from google.cloud.retail_v2.types.product_service import DeleteProductRequest -from google.cloud.retail_v2.types.product_service import GetProductRequest -from google.cloud.retail_v2.types.product_service import ListProductsRequest -from google.cloud.retail_v2.types.product_service import ListProductsResponse -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 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.purge_config import PurgeMetadata -from google.cloud.retail_v2.types.purge_config import PurgeUserEventsRequest -from google.cloud.retail_v2.types.purge_config import PurgeUserEventsResponse -from google.cloud.retail_v2.types.search_service import SearchRequest -from google.cloud.retail_v2.types.search_service import SearchResponse -from google.cloud.retail_v2.types.user_event import CompletionDetail -from google.cloud.retail_v2.types.user_event import ProductDetail -from google.cloud.retail_v2.types.user_event import PurchaseTransaction -from google.cloud.retail_v2.types.user_event import UserEvent -from google.cloud.retail_v2.types.user_event_service import CollectUserEventRequest -from google.cloud.retail_v2.types.user_event_service import RejoinUserEventsMetadata -from google.cloud.retail_v2.types.user_event_service import RejoinUserEventsRequest -from google.cloud.retail_v2.types.user_event_service import RejoinUserEventsResponse -from google.cloud.retail_v2.types.user_event_service import WriteUserEventRequest - -__all__ = ('CatalogServiceClient', - 'CatalogServiceAsyncClient', - 'CompletionServiceClient', - 'CompletionServiceAsyncClient', - 'PredictionServiceClient', - 'PredictionServiceAsyncClient', - 'ProductServiceClient', - 'ProductServiceAsyncClient', - 'SearchServiceClient', - 'SearchServiceAsyncClient', - 'UserEventServiceClient', - 'UserEventServiceAsyncClient', - 'Catalog', - 'ProductLevelConfig', - 'GetDefaultBranchRequest', - 'GetDefaultBranchResponse', - 'ListCatalogsRequest', - 'ListCatalogsResponse', - 'SetDefaultBranchRequest', - 'UpdateCatalogRequest', - 'Audience', - 'ColorInfo', - 'CustomAttribute', - 'FulfillmentInfo', - 'Image', - 'Interval', - 'PriceInfo', - 'Promotion', - 'Rating', - 'UserInfo', - 'CompleteQueryRequest', - 'CompleteQueryResponse', - 'BigQuerySource', - 'CompletionDataInputConfig', - 'GcsSource', - 'ImportCompletionDataRequest', - 'ImportCompletionDataResponse', - 'ImportErrorsConfig', - 'ImportMetadata', - 'ImportProductsRequest', - 'ImportProductsResponse', - 'ImportUserEventsRequest', - 'ImportUserEventsResponse', - 'ProductInlineSource', - 'ProductInputConfig', - 'UserEventImportSummary', - 'UserEventInlineSource', - 'UserEventInputConfig', - 'PredictRequest', - 'PredictResponse', - 'Product', - 'AddFulfillmentPlacesMetadata', - 'AddFulfillmentPlacesRequest', - 'AddFulfillmentPlacesResponse', - 'CreateProductRequest', - 'DeleteProductRequest', - 'GetProductRequest', - 'ListProductsRequest', - 'ListProductsResponse', - 'RemoveFulfillmentPlacesMetadata', - 'RemoveFulfillmentPlacesRequest', - 'RemoveFulfillmentPlacesResponse', - 'SetInventoryMetadata', - 'SetInventoryRequest', - 'SetInventoryResponse', - 'UpdateProductRequest', - 'PurgeMetadata', - 'PurgeUserEventsRequest', - 'PurgeUserEventsResponse', - 'SearchRequest', - 'SearchResponse', - 'CompletionDetail', - 'ProductDetail', - 'PurchaseTransaction', - 'UserEvent', - 'CollectUserEventRequest', - 'RejoinUserEventsMetadata', - 'RejoinUserEventsRequest', - 'RejoinUserEventsResponse', - 'WriteUserEventRequest', -) diff --git a/owl-bot-staging/v2/google/cloud/retail/py.typed b/owl-bot-staging/v2/google/cloud/retail/py.typed deleted file mode 100644 index fda82836..00000000 --- a/owl-bot-staging/v2/google/cloud/retail/py.typed +++ /dev/null @@ -1,2 +0,0 @@ -# Marker file for PEP 561. -# The google-cloud-retail package uses inline types. diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/__init__.py deleted file mode 100644 index 9bd379b4..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/__init__.py +++ /dev/null @@ -1,180 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -from .services.catalog_service import CatalogServiceClient -from .services.catalog_service import CatalogServiceAsyncClient -from .services.completion_service import CompletionServiceClient -from .services.completion_service import CompletionServiceAsyncClient -from .services.prediction_service import PredictionServiceClient -from .services.prediction_service import PredictionServiceAsyncClient -from .services.product_service import ProductServiceClient -from .services.product_service import ProductServiceAsyncClient -from .services.search_service import SearchServiceClient -from .services.search_service import SearchServiceAsyncClient -from .services.user_event_service import UserEventServiceClient -from .services.user_event_service import UserEventServiceAsyncClient - -from .types.catalog import Catalog -from .types.catalog import ProductLevelConfig -from .types.catalog_service import GetDefaultBranchRequest -from .types.catalog_service import GetDefaultBranchResponse -from .types.catalog_service import ListCatalogsRequest -from .types.catalog_service import ListCatalogsResponse -from .types.catalog_service import SetDefaultBranchRequest -from .types.catalog_service import UpdateCatalogRequest -from .types.common import Audience -from .types.common import ColorInfo -from .types.common import CustomAttribute -from .types.common import FulfillmentInfo -from .types.common import Image -from .types.common import Interval -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 -from .types.completion_service import CompleteQueryResponse -from .types.import_config import BigQuerySource -from .types.import_config import CompletionDataInputConfig -from .types.import_config import GcsSource -from .types.import_config import ImportCompletionDataRequest -from .types.import_config import ImportCompletionDataResponse -from .types.import_config import ImportErrorsConfig -from .types.import_config import ImportMetadata -from .types.import_config import ImportProductsRequest -from .types.import_config import ImportProductsResponse -from .types.import_config import ImportUserEventsRequest -from .types.import_config import ImportUserEventsResponse -from .types.import_config import ProductInlineSource -from .types.import_config import ProductInputConfig -from .types.import_config import UserEventImportSummary -from .types.import_config import UserEventInlineSource -from .types.import_config import UserEventInputConfig -from .types.prediction_service import PredictRequest -from .types.prediction_service import PredictResponse -from .types.product import Product -from .types.product_service import AddFulfillmentPlacesMetadata -from .types.product_service import AddFulfillmentPlacesRequest -from .types.product_service import AddFulfillmentPlacesResponse -from .types.product_service import CreateProductRequest -from .types.product_service import DeleteProductRequest -from .types.product_service import GetProductRequest -from .types.product_service import ListProductsRequest -from .types.product_service import ListProductsResponse -from .types.product_service import RemoveFulfillmentPlacesMetadata -from .types.product_service import RemoveFulfillmentPlacesRequest -from .types.product_service import RemoveFulfillmentPlacesResponse -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.purge_config import PurgeMetadata -from .types.purge_config import PurgeUserEventsRequest -from .types.purge_config import PurgeUserEventsResponse -from .types.search_service import SearchRequest -from .types.search_service import SearchResponse -from .types.user_event import CompletionDetail -from .types.user_event import ProductDetail -from .types.user_event import PurchaseTransaction -from .types.user_event import UserEvent -from .types.user_event_service import CollectUserEventRequest -from .types.user_event_service import RejoinUserEventsMetadata -from .types.user_event_service import RejoinUserEventsRequest -from .types.user_event_service import RejoinUserEventsResponse -from .types.user_event_service import WriteUserEventRequest - -__all__ = ( - 'CatalogServiceAsyncClient', - 'CompletionServiceAsyncClient', - 'PredictionServiceAsyncClient', - 'ProductServiceAsyncClient', - 'SearchServiceAsyncClient', - 'UserEventServiceAsyncClient', -'AddFulfillmentPlacesMetadata', -'AddFulfillmentPlacesRequest', -'AddFulfillmentPlacesResponse', -'Audience', -'BigQuerySource', -'Catalog', -'CatalogServiceClient', -'CollectUserEventRequest', -'ColorInfo', -'CompleteQueryRequest', -'CompleteQueryResponse', -'CompletionDataInputConfig', -'CompletionDetail', -'CompletionServiceClient', -'CreateProductRequest', -'CustomAttribute', -'DeleteProductRequest', -'FulfillmentInfo', -'GcsSource', -'GetDefaultBranchRequest', -'GetDefaultBranchResponse', -'GetProductRequest', -'Image', -'ImportCompletionDataRequest', -'ImportCompletionDataResponse', -'ImportErrorsConfig', -'ImportMetadata', -'ImportProductsRequest', -'ImportProductsResponse', -'ImportUserEventsRequest', -'ImportUserEventsResponse', -'Interval', -'ListCatalogsRequest', -'ListCatalogsResponse', -'ListProductsRequest', -'ListProductsResponse', -'PredictRequest', -'PredictResponse', -'PredictionServiceClient', -'PriceInfo', -'Product', -'ProductDetail', -'ProductInlineSource', -'ProductInputConfig', -'ProductLevelConfig', -'ProductServiceClient', -'Promotion', -'PurchaseTransaction', -'PurgeMetadata', -'PurgeUserEventsRequest', -'PurgeUserEventsResponse', -'Rating', -'RejoinUserEventsMetadata', -'RejoinUserEventsRequest', -'RejoinUserEventsResponse', -'RemoveFulfillmentPlacesMetadata', -'RemoveFulfillmentPlacesRequest', -'RemoveFulfillmentPlacesResponse', -'SearchRequest', -'SearchResponse', -'SearchServiceClient', -'SetDefaultBranchRequest', -'SetInventoryMetadata', -'SetInventoryRequest', -'SetInventoryResponse', -'UpdateCatalogRequest', -'UpdateProductRequest', -'UserEvent', -'UserEventImportSummary', -'UserEventInlineSource', -'UserEventInputConfig', -'UserEventServiceClient', -'UserInfo', -'WriteUserEventRequest', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/gapic_metadata.json b/owl-bot-staging/v2/google/cloud/retail_v2/gapic_metadata.json deleted file mode 100644 index 088fcc42..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/gapic_metadata.json +++ /dev/null @@ -1,313 +0,0 @@ - { - "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", - "language": "python", - "libraryPackage": "google.cloud.retail_v2", - "protoPackage": "google.cloud.retail.v2", - "schema": "1.0", - "services": { - "CatalogService": { - "clients": { - "grpc": { - "libraryClient": "CatalogServiceClient", - "rpcs": { - "GetDefaultBranch": { - "methods": [ - "get_default_branch" - ] - }, - "ListCatalogs": { - "methods": [ - "list_catalogs" - ] - }, - "SetDefaultBranch": { - "methods": [ - "set_default_branch" - ] - }, - "UpdateCatalog": { - "methods": [ - "update_catalog" - ] - } - } - }, - "grpc-async": { - "libraryClient": "CatalogServiceAsyncClient", - "rpcs": { - "GetDefaultBranch": { - "methods": [ - "get_default_branch" - ] - }, - "ListCatalogs": { - "methods": [ - "list_catalogs" - ] - }, - "SetDefaultBranch": { - "methods": [ - "set_default_branch" - ] - }, - "UpdateCatalog": { - "methods": [ - "update_catalog" - ] - } - } - } - } - }, - "CompletionService": { - "clients": { - "grpc": { - "libraryClient": "CompletionServiceClient", - "rpcs": { - "CompleteQuery": { - "methods": [ - "complete_query" - ] - }, - "ImportCompletionData": { - "methods": [ - "import_completion_data" - ] - } - } - }, - "grpc-async": { - "libraryClient": "CompletionServiceAsyncClient", - "rpcs": { - "CompleteQuery": { - "methods": [ - "complete_query" - ] - }, - "ImportCompletionData": { - "methods": [ - "import_completion_data" - ] - } - } - } - } - }, - "PredictionService": { - "clients": { - "grpc": { - "libraryClient": "PredictionServiceClient", - "rpcs": { - "Predict": { - "methods": [ - "predict" - ] - } - } - }, - "grpc-async": { - "libraryClient": "PredictionServiceAsyncClient", - "rpcs": { - "Predict": { - "methods": [ - "predict" - ] - } - } - } - } - }, - "ProductService": { - "clients": { - "grpc": { - "libraryClient": "ProductServiceClient", - "rpcs": { - "AddFulfillmentPlaces": { - "methods": [ - "add_fulfillment_places" - ] - }, - "CreateProduct": { - "methods": [ - "create_product" - ] - }, - "DeleteProduct": { - "methods": [ - "delete_product" - ] - }, - "GetProduct": { - "methods": [ - "get_product" - ] - }, - "ImportProducts": { - "methods": [ - "import_products" - ] - }, - "ListProducts": { - "methods": [ - "list_products" - ] - }, - "RemoveFulfillmentPlaces": { - "methods": [ - "remove_fulfillment_places" - ] - }, - "SetInventory": { - "methods": [ - "set_inventory" - ] - }, - "UpdateProduct": { - "methods": [ - "update_product" - ] - } - } - }, - "grpc-async": { - "libraryClient": "ProductServiceAsyncClient", - "rpcs": { - "AddFulfillmentPlaces": { - "methods": [ - "add_fulfillment_places" - ] - }, - "CreateProduct": { - "methods": [ - "create_product" - ] - }, - "DeleteProduct": { - "methods": [ - "delete_product" - ] - }, - "GetProduct": { - "methods": [ - "get_product" - ] - }, - "ImportProducts": { - "methods": [ - "import_products" - ] - }, - "ListProducts": { - "methods": [ - "list_products" - ] - }, - "RemoveFulfillmentPlaces": { - "methods": [ - "remove_fulfillment_places" - ] - }, - "SetInventory": { - "methods": [ - "set_inventory" - ] - }, - "UpdateProduct": { - "methods": [ - "update_product" - ] - } - } - } - } - }, - "SearchService": { - "clients": { - "grpc": { - "libraryClient": "SearchServiceClient", - "rpcs": { - "Search": { - "methods": [ - "search" - ] - } - } - }, - "grpc-async": { - "libraryClient": "SearchServiceAsyncClient", - "rpcs": { - "Search": { - "methods": [ - "search" - ] - } - } - } - } - }, - "UserEventService": { - "clients": { - "grpc": { - "libraryClient": "UserEventServiceClient", - "rpcs": { - "CollectUserEvent": { - "methods": [ - "collect_user_event" - ] - }, - "ImportUserEvents": { - "methods": [ - "import_user_events" - ] - }, - "PurgeUserEvents": { - "methods": [ - "purge_user_events" - ] - }, - "RejoinUserEvents": { - "methods": [ - "rejoin_user_events" - ] - }, - "WriteUserEvent": { - "methods": [ - "write_user_event" - ] - } - } - }, - "grpc-async": { - "libraryClient": "UserEventServiceAsyncClient", - "rpcs": { - "CollectUserEvent": { - "methods": [ - "collect_user_event" - ] - }, - "ImportUserEvents": { - "methods": [ - "import_user_events" - ] - }, - "PurgeUserEvents": { - "methods": [ - "purge_user_events" - ] - }, - "RejoinUserEvents": { - "methods": [ - "rejoin_user_events" - ] - }, - "WriteUserEvent": { - "methods": [ - "write_user_event" - ] - } - } - } - } - } - } -} diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/py.typed b/owl-bot-staging/v2/google/cloud/retail_v2/py.typed deleted file mode 100644 index fda82836..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/py.typed +++ /dev/null @@ -1,2 +0,0 @@ -# Marker file for PEP 561. -# The google-cloud-retail package uses inline types. diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/__init__.py deleted file mode 100644 index 4de65971..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/__init__.py deleted file mode 100644 index 316640d9..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .client import CatalogServiceClient -from .async_client import CatalogServiceAsyncClient - -__all__ = ( - 'CatalogServiceClient', - 'CatalogServiceAsyncClient', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/async_client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/async_client.py deleted file mode 100644 index 0510e57a..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/async_client.py +++ /dev/null @@ -1,587 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -import functools -import re -from typing import Dict, Optional, Sequence, Tuple, Type, Union -import pkg_resources - -from google.api_core.client_options import ClientOptions -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object] # type: ignore - -from google.cloud.retail_v2.services.catalog_service import pagers -from google.cloud.retail_v2.types import catalog -from google.cloud.retail_v2.types import catalog as gcr_catalog -from google.cloud.retail_v2.types import catalog_service -from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore -from .transports.base import CatalogServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc_asyncio import CatalogServiceGrpcAsyncIOTransport -from .client import CatalogServiceClient - - -class CatalogServiceAsyncClient: - """Service for managing catalog configuration.""" - - _client: CatalogServiceClient - - DEFAULT_ENDPOINT = CatalogServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = CatalogServiceClient.DEFAULT_MTLS_ENDPOINT - - branch_path = staticmethod(CatalogServiceClient.branch_path) - parse_branch_path = staticmethod(CatalogServiceClient.parse_branch_path) - catalog_path = staticmethod(CatalogServiceClient.catalog_path) - parse_catalog_path = staticmethod(CatalogServiceClient.parse_catalog_path) - common_billing_account_path = staticmethod(CatalogServiceClient.common_billing_account_path) - parse_common_billing_account_path = staticmethod(CatalogServiceClient.parse_common_billing_account_path) - common_folder_path = staticmethod(CatalogServiceClient.common_folder_path) - parse_common_folder_path = staticmethod(CatalogServiceClient.parse_common_folder_path) - common_organization_path = staticmethod(CatalogServiceClient.common_organization_path) - parse_common_organization_path = staticmethod(CatalogServiceClient.parse_common_organization_path) - common_project_path = staticmethod(CatalogServiceClient.common_project_path) - parse_common_project_path = staticmethod(CatalogServiceClient.parse_common_project_path) - common_location_path = staticmethod(CatalogServiceClient.common_location_path) - parse_common_location_path = staticmethod(CatalogServiceClient.parse_common_location_path) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CatalogServiceAsyncClient: The constructed client. - """ - return CatalogServiceClient.from_service_account_info.__func__(CatalogServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CatalogServiceAsyncClient: The constructed client. - """ - return CatalogServiceClient.from_service_account_file.__func__(CatalogServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[ClientOptions] = None): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variabel is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CatalogServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CatalogServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CatalogServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - get_transport_class = functools.partial(type(CatalogServiceClient).get_transport_class, type(CatalogServiceClient)) - - def __init__(self, *, - credentials: ga_credentials.Credentials = None, - transport: Union[str, CatalogServiceTransport] = "grpc_asyncio", - client_options: ClientOptions = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the catalog service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Union[str, ~.CatalogServiceTransport]): The - transport to use. If set to None, a transport is chosen - automatically. - client_options (ClientOptions): Custom options for the client. It - won't take effect if a ``transport`` instance is provided. - (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT - environment variable can also be used to override the endpoint: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CatalogServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - - ) - - async def list_catalogs(self, - request: Union[catalog_service.ListCatalogsRequest, dict] = None, - *, - parent: str = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> pagers.ListCatalogsAsyncPager: - r"""Lists all the [Catalog][google.cloud.retail.v2.Catalog]s - associated with the project. - - Args: - request (Union[google.cloud.retail_v2.types.ListCatalogsRequest, dict]): - The request object. Request for - [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] - method. - parent (:class:`str`): - Required. The account resource name with an associated - location. - - If the caller does not have permission to list - [Catalog][google.cloud.retail.v2.Catalog]s under this - location, regardless of whether or not this location - exists, a PERMISSION_DENIED error is returned. - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.services.catalog_service.pagers.ListCatalogsAsyncPager: - Response for - [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] - method. - - Iterating over this object will yield results and - resolve additional pages automatically. - - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent]) - if request is not None and has_flattened_params: - raise ValueError("If the `request` argument is set, then none of " - "the individual field arguments should be set.") - - request = catalog_service.ListCatalogsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if parent is not None: - request.parent = parent - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.list_catalogs, - default_timeout=None, - client_info=DEFAULT_CLIENT_INFO, - ) - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("parent", request.parent), - )), - ) - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__aiter__` convenience method. - response = pagers.ListCatalogsAsyncPager( - method=rpc, - request=request, - response=response, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def update_catalog(self, - request: Union[catalog_service.UpdateCatalogRequest, dict] = None, - *, - catalog: gcr_catalog.Catalog = None, - update_mask: field_mask_pb2.FieldMask = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> gcr_catalog.Catalog: - r"""Updates the [Catalog][google.cloud.retail.v2.Catalog]s. - - Args: - request (Union[google.cloud.retail_v2.types.UpdateCatalogRequest, dict]): - The request object. Request for - [CatalogService.UpdateCatalog][google.cloud.retail.v2.CatalogService.UpdateCatalog] - method. - catalog (:class:`google.cloud.retail_v2.types.Catalog`): - Required. The [Catalog][google.cloud.retail.v2.Catalog] - to update. - - If the caller does not have permission to update the - [Catalog][google.cloud.retail.v2.Catalog], regardless of - whether or not it exists, a PERMISSION_DENIED error is - returned. - - If the [Catalog][google.cloud.retail.v2.Catalog] to - update does not exist, a NOT_FOUND error is returned. - - This corresponds to the ``catalog`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): - Indicates which fields in the provided - [Catalog][google.cloud.retail.v2.Catalog] to update. - - If an unsupported or unknown field is provided, an - INVALID_ARGUMENT error is returned. - - This corresponds to the ``update_mask`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.types.Catalog: - The catalog configuration. - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([catalog, update_mask]) - if request is not None and has_flattened_params: - raise ValueError("If the `request` argument is set, then none of " - "the individual field arguments should be set.") - - request = catalog_service.UpdateCatalogRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if catalog is not None: - request.catalog = catalog - if update_mask is not None: - request.update_mask = update_mask - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.update_catalog, - 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(( - ("catalog.name", request.catalog.name), - )), - ) - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def set_default_branch(self, - request: Union[catalog_service.SetDefaultBranchRequest, dict] = None, - *, - catalog: str = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> None: - r"""Set a specified branch id as default branch. API methods such as - [SearchService.Search][google.cloud.retail.v2.SearchService.Search], - [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct], - [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] - will treat requests using "default_branch" to the actual branch - id set as default. - - For example, if ``projects/*/locations/*/catalogs/*/branches/1`` - is set as default, setting - [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] - to ``projects/*/locations/*/catalogs/*/branches/default_branch`` - is equivalent to setting - [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] - to ``projects/*/locations/*/catalogs/*/branches/1``. - - Using multiple branches can be useful when developers would like - to have a staging branch to test and verify for future usage. - When it becomes ready, developers switch on the staging branch - using this API while keeping using - ``projects/*/locations/*/catalogs/*/branches/default_branch`` as - [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] - to route the traffic to this staging branch. - - CAUTION: If you have live predict/search traffic, switching the - default branch could potentially cause outages if the ID space - of the new branch is very different from the old one. - - More specifically: - - - PredictionService will only return product IDs from branch - {newBranch}. - - SearchService will only return product IDs from branch - {newBranch} (if branch is not explicitly set). - - 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. - - Args: - request (Union[google.cloud.retail_v2.types.SetDefaultBranchRequest, dict]): - The request object. Request message to set a specified - branch as new default_branch. - catalog (:class:`str`): - Full resource name of the catalog, such as - ``projects/*/locations/global/catalogs/default_catalog``. - - This corresponds to the ``catalog`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([catalog]) - 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 = catalog_service.SetDefaultBranchRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if catalog is not None: - request.catalog = catalog - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.set_default_branch, - 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(( - ("catalog", request.catalog), - )), - ) - - # Send the request. - await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - async def get_default_branch(self, - request: Union[catalog_service.GetDefaultBranchRequest, dict] = None, - *, - catalog: str = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> catalog_service.GetDefaultBranchResponse: - r"""Get which branch is currently default branch set by - [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. - - Args: - request (Union[google.cloud.retail_v2.types.GetDefaultBranchRequest, dict]): - The request object. Request message to show which branch - is currently the default branch. - catalog (:class:`str`): - The parent catalog resource name, such as - ``projects/*/locations/global/catalogs/default_catalog``. - - This corresponds to the ``catalog`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.types.GetDefaultBranchResponse: - Response message of - [CatalogService.GetDefaultBranch][google.cloud.retail.v2.CatalogService.GetDefaultBranch]. - - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([catalog]) - 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 = catalog_service.GetDefaultBranchRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if catalog is not None: - request.catalog = catalog - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.get_default_branch, - 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(( - ("catalog", request.catalog), - )), - ) - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self): - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - -try: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution( - "google-cloud-retail", - ).version, - ) -except pkg_resources.DistributionNotFound: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() - - -__all__ = ( - "CatalogServiceAsyncClient", -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/client.py deleted file mode 100644 index baf571c1..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/client.py +++ /dev/null @@ -1,792 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -import os -import re -from typing import Dict, Optional, Sequence, Tuple, Type, Union -import pkg_resources - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object] # type: ignore - -from google.cloud.retail_v2.services.catalog_service import pagers -from google.cloud.retail_v2.types import catalog -from google.cloud.retail_v2.types import catalog as gcr_catalog -from google.cloud.retail_v2.types import catalog_service -from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore -from .transports.base import CatalogServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import CatalogServiceGrpcTransport -from .transports.grpc_asyncio import CatalogServiceGrpcAsyncIOTransport - - -class CatalogServiceClientMeta(type): - """Metaclass for the CatalogService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - _transport_registry = OrderedDict() # type: Dict[str, Type[CatalogServiceTransport]] - _transport_registry["grpc"] = CatalogServiceGrpcTransport - _transport_registry["grpc_asyncio"] = CatalogServiceGrpcAsyncIOTransport - - def get_transport_class(cls, - label: str = None, - ) -> Type[CatalogServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CatalogServiceClient(metaclass=CatalogServiceClientMeta): - """Service for managing catalog configuration.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - DEFAULT_ENDPOINT = "retail.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CatalogServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info(info) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CatalogServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CatalogServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CatalogServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - 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, ) - - @staticmethod - def parse_branch_path(path: str) -> Dict[str,str]: - """Parses a branch path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def catalog_path(project: str,location: str,catalog: str,) -> str: - """Returns a fully-qualified catalog string.""" - return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) - - @staticmethod - def parse_catalog_path(path: str) -> Dict[str,str]: - """Parses a catalog path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path(billing_account: str, ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str,str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path(folder: str, ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format(folder=folder, ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str,str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path(organization: str, ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format(organization=organization, ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str,str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path(project: str, ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format(project=project, ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str,str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path(project: str, location: str, ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format(project=project, location=location, ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str,str]: - """Parse a location path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variabel is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError("Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`") - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError("Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`") - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - def __init__(self, *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Union[str, CatalogServiceTransport, None] = None, - client_options: Optional[client_options_lib.ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the catalog service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Union[str, CatalogServiceTransport]): The - transport to use. If set to None, a transport is chosen - automatically. - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. It won't take effect if a ``transport`` instance is provided. - (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT - environment variable can also be used to override the endpoint: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - if isinstance(client_options, dict): - client_options = client_options_lib.from_dict(client_options) - if client_options is None: - client_options = client_options_lib.ClientOptions() - - api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options) - - api_key_value = getattr(client_options, "api_key", None) - if api_key_value and credentials: - raise ValueError("client_options.api_key and credentials are mutually exclusive") - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - if isinstance(transport, CatalogServiceTransport): - # transport is a CatalogServiceTransport instance. - if credentials or client_options.credentials_file or api_key_value: - raise ValueError("When providing a transport instance, " - "provide its credentials directly.") - if client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = transport - else: - import google.auth._default # type: ignore - - if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"): - credentials = google.auth._default.get_api_key_credentials(api_key_value) - - Transport = type(self).get_transport_class(transport) - self._transport = Transport( - credentials=credentials, - credentials_file=client_options.credentials_file, - host=api_endpoint, - scopes=client_options.scopes, - client_cert_source_for_mtls=client_cert_source_func, - quota_project_id=client_options.quota_project_id, - client_info=client_info, - always_use_jwt_access=True, - ) - - def list_catalogs(self, - request: Union[catalog_service.ListCatalogsRequest, dict] = None, - *, - parent: str = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> pagers.ListCatalogsPager: - r"""Lists all the [Catalog][google.cloud.retail.v2.Catalog]s - associated with the project. - - Args: - request (Union[google.cloud.retail_v2.types.ListCatalogsRequest, dict]): - The request object. Request for - [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] - method. - parent (str): - Required. The account resource name with an associated - location. - - If the caller does not have permission to list - [Catalog][google.cloud.retail.v2.Catalog]s under this - location, regardless of whether or not this location - exists, a PERMISSION_DENIED error is returned. - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.services.catalog_service.pagers.ListCatalogsPager: - Response for - [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] - method. - - Iterating over this object will yield results and - resolve additional pages automatically. - - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent]) - if request is not None and has_flattened_params: - raise ValueError('If the `request` argument is set, then none of ' - 'the individual field arguments should be set.') - - # Minor optimization to avoid making a copy if the user passes - # in a catalog_service.ListCatalogsRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, catalog_service.ListCatalogsRequest): - request = catalog_service.ListCatalogsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if parent is not None: - request.parent = parent - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.list_catalogs] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("parent", request.parent), - )), - ) - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__iter__` convenience method. - response = pagers.ListCatalogsPager( - method=rpc, - request=request, - response=response, - metadata=metadata, - ) - - # Done; return the response. - return response - - def update_catalog(self, - request: Union[catalog_service.UpdateCatalogRequest, dict] = None, - *, - catalog: gcr_catalog.Catalog = None, - update_mask: field_mask_pb2.FieldMask = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> gcr_catalog.Catalog: - r"""Updates the [Catalog][google.cloud.retail.v2.Catalog]s. - - Args: - request (Union[google.cloud.retail_v2.types.UpdateCatalogRequest, dict]): - The request object. Request for - [CatalogService.UpdateCatalog][google.cloud.retail.v2.CatalogService.UpdateCatalog] - method. - catalog (google.cloud.retail_v2.types.Catalog): - Required. The [Catalog][google.cloud.retail.v2.Catalog] - to update. - - If the caller does not have permission to update the - [Catalog][google.cloud.retail.v2.Catalog], regardless of - whether or not it exists, a PERMISSION_DENIED error is - returned. - - If the [Catalog][google.cloud.retail.v2.Catalog] to - update does not exist, a NOT_FOUND error is returned. - - This corresponds to the ``catalog`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - update_mask (google.protobuf.field_mask_pb2.FieldMask): - Indicates which fields in the provided - [Catalog][google.cloud.retail.v2.Catalog] to update. - - If an unsupported or unknown field is provided, an - INVALID_ARGUMENT error is returned. - - This corresponds to the ``update_mask`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.types.Catalog: - The catalog configuration. - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([catalog, update_mask]) - if request is not None and has_flattened_params: - raise ValueError('If the `request` argument is set, then none of ' - 'the individual field arguments should be set.') - - # Minor optimization to avoid making a copy if the user passes - # in a catalog_service.UpdateCatalogRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, catalog_service.UpdateCatalogRequest): - request = catalog_service.UpdateCatalogRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if catalog is not None: - request.catalog = catalog - if update_mask is not None: - request.update_mask = update_mask - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.update_catalog] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("catalog.name", request.catalog.name), - )), - ) - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def set_default_branch(self, - request: Union[catalog_service.SetDefaultBranchRequest, dict] = None, - *, - catalog: str = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> None: - r"""Set a specified branch id as default branch. API methods such as - [SearchService.Search][google.cloud.retail.v2.SearchService.Search], - [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct], - [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] - will treat requests using "default_branch" to the actual branch - id set as default. - - For example, if ``projects/*/locations/*/catalogs/*/branches/1`` - is set as default, setting - [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] - to ``projects/*/locations/*/catalogs/*/branches/default_branch`` - is equivalent to setting - [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] - to ``projects/*/locations/*/catalogs/*/branches/1``. - - Using multiple branches can be useful when developers would like - to have a staging branch to test and verify for future usage. - When it becomes ready, developers switch on the staging branch - using this API while keeping using - ``projects/*/locations/*/catalogs/*/branches/default_branch`` as - [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] - to route the traffic to this staging branch. - - CAUTION: If you have live predict/search traffic, switching the - default branch could potentially cause outages if the ID space - of the new branch is very different from the old one. - - More specifically: - - - PredictionService will only return product IDs from branch - {newBranch}. - - SearchService will only return product IDs from branch - {newBranch} (if branch is not explicitly set). - - 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. - - Args: - request (Union[google.cloud.retail_v2.types.SetDefaultBranchRequest, dict]): - The request object. Request message to set a specified - branch as new default_branch. - catalog (str): - Full resource name of the catalog, such as - ``projects/*/locations/global/catalogs/default_catalog``. - - This corresponds to the ``catalog`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([catalog]) - 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 catalog_service.SetDefaultBranchRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, catalog_service.SetDefaultBranchRequest): - request = catalog_service.SetDefaultBranchRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if catalog is not None: - request.catalog = catalog - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.set_default_branch] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("catalog", request.catalog), - )), - ) - - # Send the request. - rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - def get_default_branch(self, - request: Union[catalog_service.GetDefaultBranchRequest, dict] = None, - *, - catalog: str = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> catalog_service.GetDefaultBranchResponse: - r"""Get which branch is currently default branch set by - [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. - - Args: - request (Union[google.cloud.retail_v2.types.GetDefaultBranchRequest, dict]): - The request object. Request message to show which branch - is currently the default branch. - catalog (str): - The parent catalog resource name, such as - ``projects/*/locations/global/catalogs/default_catalog``. - - This corresponds to the ``catalog`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.types.GetDefaultBranchResponse: - Response message of - [CatalogService.GetDefaultBranch][google.cloud.retail.v2.CatalogService.GetDefaultBranch]. - - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([catalog]) - 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 catalog_service.GetDefaultBranchRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, catalog_service.GetDefaultBranchRequest): - request = catalog_service.GetDefaultBranchRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if catalog is not None: - request.catalog = catalog - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.get_default_branch] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("catalog", request.catalog), - )), - ) - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self): - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - - -try: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution( - "google-cloud-retail", - ).version, - ) -except pkg_resources.DistributionNotFound: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() - - -__all__ = ( - "CatalogServiceClient", -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/pagers.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/pagers.py deleted file mode 100644 index 2ca8b45a..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/pagers.py +++ /dev/null @@ -1,140 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from typing import Any, AsyncIterator, Awaitable, Callable, Sequence, Tuple, Optional, Iterator - -from google.cloud.retail_v2.types import catalog -from google.cloud.retail_v2.types import catalog_service - - -class ListCatalogsPager: - """A pager for iterating through ``list_catalogs`` requests. - - This class thinly wraps an initial - :class:`google.cloud.retail_v2.types.ListCatalogsResponse` object, and - provides an ``__iter__`` method to iterate through its - ``catalogs`` field. - - If there are more pages, the ``__iter__`` method will make additional - ``ListCatalogs`` requests and continue to iterate - through the ``catalogs`` field on the - corresponding responses. - - All the usual :class:`google.cloud.retail_v2.types.ListCatalogsResponse` - attributes are available on the pager. If multiple requests are made, only - the most recent response is retained, and thus used for attribute lookup. - """ - def __init__(self, - method: Callable[..., catalog_service.ListCatalogsResponse], - request: catalog_service.ListCatalogsRequest, - response: catalog_service.ListCatalogsResponse, - *, - metadata: Sequence[Tuple[str, str]] = ()): - """Instantiate the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.cloud.retail_v2.types.ListCatalogsRequest): - The initial request object. - response (google.cloud.retail_v2.types.ListCatalogsResponse): - The initial response object. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - self._method = method - self._request = catalog_service.ListCatalogsRequest(request) - self._response = response - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - def pages(self) -> Iterator[catalog_service.ListCatalogsResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = self._method(self._request, metadata=self._metadata) - yield self._response - - def __iter__(self) -> Iterator[catalog.Catalog]: - for page in self.pages: - yield from page.catalogs - - def __repr__(self) -> str: - return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) - - -class ListCatalogsAsyncPager: - """A pager for iterating through ``list_catalogs`` requests. - - This class thinly wraps an initial - :class:`google.cloud.retail_v2.types.ListCatalogsResponse` object, and - provides an ``__aiter__`` method to iterate through its - ``catalogs`` field. - - If there are more pages, the ``__aiter__`` method will make additional - ``ListCatalogs`` requests and continue to iterate - through the ``catalogs`` field on the - corresponding responses. - - All the usual :class:`google.cloud.retail_v2.types.ListCatalogsResponse` - attributes are available on the pager. If multiple requests are made, only - the most recent response is retained, and thus used for attribute lookup. - """ - def __init__(self, - method: Callable[..., Awaitable[catalog_service.ListCatalogsResponse]], - request: catalog_service.ListCatalogsRequest, - response: catalog_service.ListCatalogsResponse, - *, - metadata: Sequence[Tuple[str, str]] = ()): - """Instantiates the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.cloud.retail_v2.types.ListCatalogsRequest): - The initial request object. - response (google.cloud.retail_v2.types.ListCatalogsResponse): - The initial response object. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - self._method = method - self._request = catalog_service.ListCatalogsRequest(request) - self._response = response - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - async def pages(self) -> AsyncIterator[catalog_service.ListCatalogsResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = await self._method(self._request, metadata=self._metadata) - yield self._response - def __aiter__(self) -> AsyncIterator[catalog.Catalog]: - async def async_generator(): - async for page in self.pages: - for response in page.catalogs: - yield response - - return async_generator() - - def __repr__(self) -> str: - return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/__init__.py deleted file mode 100644 index 7d55f7e9..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from typing import Dict, Type - -from .base import CatalogServiceTransport -from .grpc import CatalogServiceGrpcTransport -from .grpc_asyncio import CatalogServiceGrpcAsyncIOTransport - - -# Compile a registry of transports. -_transport_registry = OrderedDict() # type: Dict[str, Type[CatalogServiceTransport]] -_transport_registry['grpc'] = CatalogServiceGrpcTransport -_transport_registry['grpc_asyncio'] = CatalogServiceGrpcAsyncIOTransport - -__all__ = ( - 'CatalogServiceTransport', - 'CatalogServiceGrpcTransport', - 'CatalogServiceGrpcAsyncIOTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/base.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/base.py deleted file mode 100644 index 3853f48b..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/base.py +++ /dev/null @@ -1,189 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Dict, Optional, Sequence, Union -import pkg_resources - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore - -from google.cloud.retail_v2.types import catalog as gcr_catalog -from google.cloud.retail_v2.types import catalog_service -from google.protobuf import empty_pb2 # type: ignore - -try: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution( - 'google-cloud-retail', - ).version, - ) -except pkg_resources.DistributionNotFound: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() - - -class CatalogServiceTransport(abc.ABC): - """Abstract transport class for CatalogService.""" - - AUTH_SCOPES = ( - 'https://www.googleapis.com/auth/cloud-platform', - ) - - DEFAULT_HOST: str = 'retail.googleapis.com' - def __init__( - self, *, - host: str = DEFAULT_HOST, - credentials: ga_credentials.Credentials = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to. - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ':' not in host: - host += ':443' - self._host = host - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs("'credentials_file' and 'credentials' are mutually exclusive") - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id - ) - elif credentials is None: - credentials, _ = google.auth.default(**scopes_kwargs, quota_project_id=quota_project_id) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if always_use_jwt_access and isinstance(credentials, service_account.Credentials) and hasattr(service_account.Credentials, "with_always_use_jwt_access"): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - 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.update_catalog: gapic_v1.method.wrap_method( - 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.get_default_branch: gapic_v1.method.wrap_method( - 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! - """ - raise NotImplementedError() - - @property - def list_catalogs(self) -> Callable[ - [catalog_service.ListCatalogsRequest], - Union[ - catalog_service.ListCatalogsResponse, - Awaitable[catalog_service.ListCatalogsResponse] - ]]: - raise NotImplementedError() - - @property - def update_catalog(self) -> Callable[ - [catalog_service.UpdateCatalogRequest], - Union[ - gcr_catalog.Catalog, - Awaitable[gcr_catalog.Catalog] - ]]: - raise NotImplementedError() - - @property - def set_default_branch(self) -> Callable[ - [catalog_service.SetDefaultBranchRequest], - Union[ - empty_pb2.Empty, - Awaitable[empty_pb2.Empty] - ]]: - raise NotImplementedError() - - @property - def get_default_branch(self) -> Callable[ - [catalog_service.GetDefaultBranchRequest], - Union[ - catalog_service.GetDefaultBranchResponse, - Awaitable[catalog_service.GetDefaultBranchResponse] - ]]: - raise NotImplementedError() - - -__all__ = ( - 'CatalogServiceTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc.py deleted file mode 100644 index c0245324..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc.py +++ /dev/null @@ -1,381 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -import google.auth # type: ignore -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore - -import grpc # type: ignore - -from google.cloud.retail_v2.types import catalog as gcr_catalog -from google.cloud.retail_v2.types import catalog_service -from google.protobuf import empty_pb2 # type: ignore -from .base import CatalogServiceTransport, DEFAULT_CLIENT_INFO - - -class CatalogServiceGrpcTransport(CatalogServiceTransport): - """gRPC backend transport for CatalogService. - - Service for managing catalog configuration. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - _stubs: Dict[str, Callable] - - def __init__(self, *, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: str = None, - scopes: Sequence[str] = None, - channel: grpc.Channel = None, - api_mtls_endpoint: str = None, - client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, - client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to. - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if ``channel`` is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if ``channel`` is provided. - channel (Optional[grpc.Channel]): A ``Channel`` instance through - which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if ``channel`` is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if ``channel`` or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn("client_cert_source is deprecated", DeprecationWarning) - - if channel: - # Ignore credentials if a channel was passed. - credentials = False - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - else: - self._ssl_channel_credentials = SslCredentials().ssl_credentials - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - ) - - if not self._grpc_channel: - self._grpc_channel = type(self).create_channel( - self._host, - credentials=self._credentials, - credentials_file=credentials_file, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Wrap messages. This must be done after self._grpc_channel exists - self._prep_wrapped_messages(client_info) - - @classmethod - def create_channel(cls, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: str = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service. - """ - return self._grpc_channel - - @property - def list_catalogs(self) -> Callable[ - [catalog_service.ListCatalogsRequest], - catalog_service.ListCatalogsResponse]: - r"""Return a callable for the list catalogs method over gRPC. - - Lists all the [Catalog][google.cloud.retail.v2.Catalog]s - associated with the project. - - Returns: - Callable[[~.ListCatalogsRequest], - ~.ListCatalogsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if 'list_catalogs' not in self._stubs: - self._stubs['list_catalogs'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.CatalogService/ListCatalogs', - request_serializer=catalog_service.ListCatalogsRequest.serialize, - response_deserializer=catalog_service.ListCatalogsResponse.deserialize, - ) - return self._stubs['list_catalogs'] - - @property - def update_catalog(self) -> Callable[ - [catalog_service.UpdateCatalogRequest], - gcr_catalog.Catalog]: - r"""Return a callable for the update catalog method over gRPC. - - Updates the [Catalog][google.cloud.retail.v2.Catalog]s. - - Returns: - Callable[[~.UpdateCatalogRequest], - ~.Catalog]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if 'update_catalog' not in self._stubs: - self._stubs['update_catalog'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.CatalogService/UpdateCatalog', - request_serializer=catalog_service.UpdateCatalogRequest.serialize, - response_deserializer=gcr_catalog.Catalog.deserialize, - ) - return self._stubs['update_catalog'] - - @property - def set_default_branch(self) -> Callable[ - [catalog_service.SetDefaultBranchRequest], - empty_pb2.Empty]: - r"""Return a callable for the set default branch method over gRPC. - - Set a specified branch id as default branch. API methods such as - [SearchService.Search][google.cloud.retail.v2.SearchService.Search], - [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct], - [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] - will treat requests using "default_branch" to the actual branch - id set as default. - - For example, if ``projects/*/locations/*/catalogs/*/branches/1`` - is set as default, setting - [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] - to ``projects/*/locations/*/catalogs/*/branches/default_branch`` - is equivalent to setting - [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] - to ``projects/*/locations/*/catalogs/*/branches/1``. - - Using multiple branches can be useful when developers would like - to have a staging branch to test and verify for future usage. - When it becomes ready, developers switch on the staging branch - using this API while keeping using - ``projects/*/locations/*/catalogs/*/branches/default_branch`` as - [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] - to route the traffic to this staging branch. - - CAUTION: If you have live predict/search traffic, switching the - default branch could potentially cause outages if the ID space - of the new branch is very different from the old one. - - More specifically: - - - PredictionService will only return product IDs from branch - {newBranch}. - - SearchService will only return product IDs from branch - {newBranch} (if branch is not explicitly set). - - 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]: - 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 'set_default_branch' not in self._stubs: - self._stubs['set_default_branch'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.CatalogService/SetDefaultBranch', - request_serializer=catalog_service.SetDefaultBranchRequest.serialize, - response_deserializer=empty_pb2.Empty.FromString, - ) - return self._stubs['set_default_branch'] - - @property - def get_default_branch(self) -> Callable[ - [catalog_service.GetDefaultBranchRequest], - catalog_service.GetDefaultBranchResponse]: - r"""Return a callable for the get default branch method over gRPC. - - Get which branch is currently default branch set by - [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]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if 'get_default_branch' not in self._stubs: - self._stubs['get_default_branch'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.CatalogService/GetDefaultBranch', - request_serializer=catalog_service.GetDefaultBranchRequest.serialize, - response_deserializer=catalog_service.GetDefaultBranchResponse.deserialize, - ) - return self._stubs['get_default_branch'] - - def close(self): - self.grpc_channel.close() - -__all__ = ( - 'CatalogServiceGrpcTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc_asyncio.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc_asyncio.py deleted file mode 100644 index 96a62e1a..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,385 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore - -import grpc # type: ignore -from grpc.experimental import aio # type: ignore - -from google.cloud.retail_v2.types import catalog as gcr_catalog -from google.cloud.retail_v2.types import catalog_service -from google.protobuf import empty_pb2 # type: ignore -from .base import CatalogServiceTransport, DEFAULT_CLIENT_INFO -from .grpc import CatalogServiceGrpcTransport - - -class CatalogServiceGrpcAsyncIOTransport(CatalogServiceTransport): - """gRPC AsyncIO backend transport for CatalogService. - - Service for managing catalog configuration. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel(cls, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs - ) - - def __init__(self, *, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: aio.Channel = None, - api_mtls_endpoint: str = None, - client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, - client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, - quota_project_id=None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to. - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if ``channel`` is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[aio.Channel]): A ``Channel`` instance through - which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if ``channel`` is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if ``channel`` or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn("client_cert_source is deprecated", DeprecationWarning) - - if channel: - # Ignore credentials if a channel was passed. - credentials = False - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - else: - self._ssl_channel_credentials = SslCredentials().ssl_credentials - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - ) - - if not self._grpc_channel: - self._grpc_channel = type(self).create_channel( - self._host, - credentials=self._credentials, - credentials_file=credentials_file, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Wrap messages. This must be done after self._grpc_channel exists - self._prep_wrapped_messages(client_info) - - @property - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def list_catalogs(self) -> Callable[ - [catalog_service.ListCatalogsRequest], - Awaitable[catalog_service.ListCatalogsResponse]]: - r"""Return a callable for the list catalogs method over gRPC. - - Lists all the [Catalog][google.cloud.retail.v2.Catalog]s - associated with the project. - - Returns: - Callable[[~.ListCatalogsRequest], - Awaitable[~.ListCatalogsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if 'list_catalogs' not in self._stubs: - self._stubs['list_catalogs'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.CatalogService/ListCatalogs', - request_serializer=catalog_service.ListCatalogsRequest.serialize, - response_deserializer=catalog_service.ListCatalogsResponse.deserialize, - ) - return self._stubs['list_catalogs'] - - @property - def update_catalog(self) -> Callable[ - [catalog_service.UpdateCatalogRequest], - Awaitable[gcr_catalog.Catalog]]: - r"""Return a callable for the update catalog method over gRPC. - - Updates the [Catalog][google.cloud.retail.v2.Catalog]s. - - Returns: - Callable[[~.UpdateCatalogRequest], - Awaitable[~.Catalog]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if 'update_catalog' not in self._stubs: - self._stubs['update_catalog'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.CatalogService/UpdateCatalog', - request_serializer=catalog_service.UpdateCatalogRequest.serialize, - response_deserializer=gcr_catalog.Catalog.deserialize, - ) - return self._stubs['update_catalog'] - - @property - def set_default_branch(self) -> Callable[ - [catalog_service.SetDefaultBranchRequest], - Awaitable[empty_pb2.Empty]]: - r"""Return a callable for the set default branch method over gRPC. - - Set a specified branch id as default branch. API methods such as - [SearchService.Search][google.cloud.retail.v2.SearchService.Search], - [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct], - [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] - will treat requests using "default_branch" to the actual branch - id set as default. - - For example, if ``projects/*/locations/*/catalogs/*/branches/1`` - is set as default, setting - [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] - to ``projects/*/locations/*/catalogs/*/branches/default_branch`` - is equivalent to setting - [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] - to ``projects/*/locations/*/catalogs/*/branches/1``. - - Using multiple branches can be useful when developers would like - to have a staging branch to test and verify for future usage. - When it becomes ready, developers switch on the staging branch - using this API while keeping using - ``projects/*/locations/*/catalogs/*/branches/default_branch`` as - [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] - to route the traffic to this staging branch. - - CAUTION: If you have live predict/search traffic, switching the - default branch could potentially cause outages if the ID space - of the new branch is very different from the old one. - - More specifically: - - - PredictionService will only return product IDs from branch - {newBranch}. - - SearchService will only return product IDs from branch - {newBranch} (if branch is not explicitly set). - - 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]]: - 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 'set_default_branch' not in self._stubs: - self._stubs['set_default_branch'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.CatalogService/SetDefaultBranch', - request_serializer=catalog_service.SetDefaultBranchRequest.serialize, - response_deserializer=empty_pb2.Empty.FromString, - ) - return self._stubs['set_default_branch'] - - @property - def get_default_branch(self) -> Callable[ - [catalog_service.GetDefaultBranchRequest], - Awaitable[catalog_service.GetDefaultBranchResponse]]: - r"""Return a callable for the get default branch method over gRPC. - - Get which branch is currently default branch set by - [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]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if 'get_default_branch' not in self._stubs: - self._stubs['get_default_branch'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.CatalogService/GetDefaultBranch', - request_serializer=catalog_service.GetDefaultBranchRequest.serialize, - response_deserializer=catalog_service.GetDefaultBranchResponse.deserialize, - ) - return self._stubs['get_default_branch'] - - def close(self): - return self.grpc_channel.close() - - -__all__ = ( - 'CatalogServiceGrpcAsyncIOTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/__init__.py deleted file mode 100644 index dbedd175..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .client import CompletionServiceClient -from .async_client import CompletionServiceAsyncClient - -__all__ = ( - 'CompletionServiceClient', - 'CompletionServiceAsyncClient', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/async_client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/async_client.py deleted file mode 100644 index 51d1be06..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/async_client.py +++ /dev/null @@ -1,346 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -import functools -import re -from typing import Dict, Optional, Sequence, Tuple, Type, Union -import pkg_resources - -from google.api_core.client_options import ClientOptions -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object] # type: ignore - -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore -from google.cloud.retail_v2.types import completion_service -from google.cloud.retail_v2.types import import_config -from .transports.base import CompletionServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc_asyncio import CompletionServiceGrpcAsyncIOTransport -from .client import CompletionServiceClient - - -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. - """ - - _client: CompletionServiceClient - - DEFAULT_ENDPOINT = CompletionServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = CompletionServiceClient.DEFAULT_MTLS_ENDPOINT - - catalog_path = staticmethod(CompletionServiceClient.catalog_path) - parse_catalog_path = staticmethod(CompletionServiceClient.parse_catalog_path) - common_billing_account_path = staticmethod(CompletionServiceClient.common_billing_account_path) - parse_common_billing_account_path = staticmethod(CompletionServiceClient.parse_common_billing_account_path) - common_folder_path = staticmethod(CompletionServiceClient.common_folder_path) - parse_common_folder_path = staticmethod(CompletionServiceClient.parse_common_folder_path) - common_organization_path = staticmethod(CompletionServiceClient.common_organization_path) - parse_common_organization_path = staticmethod(CompletionServiceClient.parse_common_organization_path) - common_project_path = staticmethod(CompletionServiceClient.common_project_path) - parse_common_project_path = staticmethod(CompletionServiceClient.parse_common_project_path) - common_location_path = staticmethod(CompletionServiceClient.common_location_path) - parse_common_location_path = staticmethod(CompletionServiceClient.parse_common_location_path) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CompletionServiceAsyncClient: The constructed client. - """ - return CompletionServiceClient.from_service_account_info.__func__(CompletionServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CompletionServiceAsyncClient: The constructed client. - """ - return CompletionServiceClient.from_service_account_file.__func__(CompletionServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[ClientOptions] = None): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variabel is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CompletionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CompletionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CompletionServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - get_transport_class = functools.partial(type(CompletionServiceClient).get_transport_class, type(CompletionServiceClient)) - - def __init__(self, *, - credentials: ga_credentials.Credentials = None, - transport: Union[str, CompletionServiceTransport] = "grpc_asyncio", - client_options: ClientOptions = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the completion service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Union[str, ~.CompletionServiceTransport]): The - transport to use. If set to None, a transport is chosen - automatically. - client_options (ClientOptions): Custom options for the client. It - won't take effect if a ``transport`` instance is provided. - (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT - environment variable can also be used to override the endpoint: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CompletionServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - - ) - - async def complete_query(self, - request: Union[completion_service.CompleteQueryRequest, dict] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - 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. - - Args: - request (Union[google.cloud.retail_v2.types.CompleteQueryRequest, dict]): - The request object. Auto-complete parameters. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.types.CompleteQueryResponse: - Response of the auto-complete query. - """ - # Create or coerce a protobuf request object. - request = completion_service.CompleteQueryRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.complete_query, - 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(( - ("catalog", request.catalog), - )), - ) - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def import_completion_data(self, - request: Union[import_config.ImportCompletionDataRequest, dict] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - 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. - - Args: - request (Union[google.cloud.retail_v2.types.ImportCompletionDataRequest, dict]): - The request object. Request message for - ImportCompletionData methods. - 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.ImportCompletionDataResponse` Response of the - [ImportCompletionDataRequest][google.cloud.retail.v2.ImportCompletionDataRequest]. - If the long running operation is done, this message - is returned by the - google.longrunning.Operations.response field if the - operation is successful. - - """ - # Create or coerce a protobuf request object. - request = import_config.ImportCompletionDataRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.import_completion_data, - default_timeout=None, - client_info=DEFAULT_CLIENT_INFO, - ) - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("parent", request.parent), - )), - ) - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation_async.from_gapic( - response, - self._client._transport.operations_client, - import_config.ImportCompletionDataResponse, - metadata_type=import_config.ImportMetadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self): - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - -try: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution( - "google-cloud-retail", - ).version, - ) -except pkg_resources.DistributionNotFound: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() - - -__all__ = ( - "CompletionServiceAsyncClient", -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/client.py deleted file mode 100644 index 65cb8884..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/client.py +++ /dev/null @@ -1,544 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -import os -import re -from typing import Dict, Optional, Sequence, Tuple, Type, Union -import pkg_resources - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object] # type: ignore - -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore -from google.cloud.retail_v2.types import completion_service -from google.cloud.retail_v2.types import import_config -from .transports.base import CompletionServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import CompletionServiceGrpcTransport -from .transports.grpc_asyncio import CompletionServiceGrpcAsyncIOTransport - - -class CompletionServiceClientMeta(type): - """Metaclass for the CompletionService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - _transport_registry = OrderedDict() # type: Dict[str, Type[CompletionServiceTransport]] - _transport_registry["grpc"] = CompletionServiceGrpcTransport - _transport_registry["grpc_asyncio"] = CompletionServiceGrpcAsyncIOTransport - - def get_transport_class(cls, - label: str = None, - ) -> Type[CompletionServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class 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. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - DEFAULT_ENDPOINT = "retail.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CompletionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info(info) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CompletionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CompletionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CompletionServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def catalog_path(project: str,location: str,catalog: str,) -> str: - """Returns a fully-qualified catalog string.""" - return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) - - @staticmethod - def parse_catalog_path(path: str) -> Dict[str,str]: - """Parses a catalog path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path(billing_account: str, ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str,str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path(folder: str, ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format(folder=folder, ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str,str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path(organization: str, ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format(organization=organization, ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str,str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path(project: str, ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format(project=project, ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str,str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path(project: str, location: str, ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format(project=project, location=location, ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str,str]: - """Parse a location path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variabel is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError("Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`") - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError("Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`") - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - def __init__(self, *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Union[str, CompletionServiceTransport, None] = None, - client_options: Optional[client_options_lib.ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the completion service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Union[str, CompletionServiceTransport]): The - transport to use. If set to None, a transport is chosen - automatically. - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. It won't take effect if a ``transport`` instance is provided. - (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT - environment variable can also be used to override the endpoint: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - if isinstance(client_options, dict): - client_options = client_options_lib.from_dict(client_options) - if client_options is None: - client_options = client_options_lib.ClientOptions() - - api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options) - - api_key_value = getattr(client_options, "api_key", None) - if api_key_value and credentials: - raise ValueError("client_options.api_key and credentials are mutually exclusive") - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - if isinstance(transport, CompletionServiceTransport): - # transport is a CompletionServiceTransport instance. - if credentials or client_options.credentials_file or api_key_value: - raise ValueError("When providing a transport instance, " - "provide its credentials directly.") - if client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = transport - else: - import google.auth._default # type: ignore - - if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"): - credentials = google.auth._default.get_api_key_credentials(api_key_value) - - Transport = type(self).get_transport_class(transport) - self._transport = Transport( - credentials=credentials, - credentials_file=client_options.credentials_file, - host=api_endpoint, - scopes=client_options.scopes, - client_cert_source_for_mtls=client_cert_source_func, - quota_project_id=client_options.quota_project_id, - client_info=client_info, - always_use_jwt_access=True, - ) - - def complete_query(self, - request: Union[completion_service.CompleteQueryRequest, dict] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - 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. - - Args: - request (Union[google.cloud.retail_v2.types.CompleteQueryRequest, dict]): - The request object. Auto-complete parameters. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.types.CompleteQueryResponse: - Response of the auto-complete query. - """ - # Create or coerce a protobuf request object. - # Minor optimization to avoid making a copy if the user passes - # in a completion_service.CompleteQueryRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, completion_service.CompleteQueryRequest): - request = completion_service.CompleteQueryRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.complete_query] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("catalog", request.catalog), - )), - ) - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def import_completion_data(self, - request: Union[import_config.ImportCompletionDataRequest, dict] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - 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. - - Args: - request (Union[google.cloud.retail_v2.types.ImportCompletionDataRequest, dict]): - The request object. Request message for - ImportCompletionData methods. - 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.ImportCompletionDataResponse` Response of the - [ImportCompletionDataRequest][google.cloud.retail.v2.ImportCompletionDataRequest]. - If the long running operation is done, this message - is returned by the - google.longrunning.Operations.response field if the - operation is successful. - - """ - # Create or coerce a protobuf request object. - # Minor optimization to avoid making a copy if the user passes - # in a import_config.ImportCompletionDataRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, import_config.ImportCompletionDataRequest): - request = import_config.ImportCompletionDataRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.import_completion_data] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("parent", request.parent), - )), - ) - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation.from_gapic( - response, - self._transport.operations_client, - import_config.ImportCompletionDataResponse, - metadata_type=import_config.ImportMetadata, - ) - - # Done; return the response. - return response - - def __enter__(self): - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - - -try: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution( - "google-cloud-retail", - ).version, - ) -except pkg_resources.DistributionNotFound: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() - - -__all__ = ( - "CompletionServiceClient", -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/__init__.py deleted file mode 100644 index afb1afd2..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from typing import Dict, Type - -from .base import CompletionServiceTransport -from .grpc import CompletionServiceGrpcTransport -from .grpc_asyncio import CompletionServiceGrpcAsyncIOTransport - - -# Compile a registry of transports. -_transport_registry = OrderedDict() # type: Dict[str, Type[CompletionServiceTransport]] -_transport_registry['grpc'] = CompletionServiceGrpcTransport -_transport_registry['grpc_asyncio'] = CompletionServiceGrpcAsyncIOTransport - -__all__ = ( - 'CompletionServiceTransport', - 'CompletionServiceGrpcTransport', - 'CompletionServiceGrpcAsyncIOTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/base.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/base.py deleted file mode 100644 index 5edbc6a1..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/base.py +++ /dev/null @@ -1,167 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Dict, Optional, Sequence, Union -import pkg_resources - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.api_core import operations_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore - -from google.cloud.retail_v2.types import completion_service -from google.cloud.retail_v2.types import import_config -from google.longrunning import operations_pb2 # type: ignore - -try: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution( - 'google-cloud-retail', - ).version, - ) -except pkg_resources.DistributionNotFound: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() - - -class CompletionServiceTransport(abc.ABC): - """Abstract transport class for CompletionService.""" - - AUTH_SCOPES = ( - 'https://www.googleapis.com/auth/cloud-platform', - ) - - DEFAULT_HOST: str = 'retail.googleapis.com' - def __init__( - self, *, - host: str = DEFAULT_HOST, - credentials: ga_credentials.Credentials = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to. - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ':' not in host: - host += ':443' - self._host = host - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs("'credentials_file' and 'credentials' are mutually exclusive") - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id - ) - elif credentials is None: - credentials, _ = google.auth.default(**scopes_kwargs, quota_project_id=quota_project_id) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if always_use_jwt_access and isinstance(credentials, service_account.Credentials) and hasattr(service_account.Credentials, "with_always_use_jwt_access"): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - 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.import_completion_data: gapic_v1.method.wrap_method( - self.import_completion_data, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def operations_client(self): - """Return the client designed to process long-running operations.""" - raise NotImplementedError() - - @property - def complete_query(self) -> Callable[ - [completion_service.CompleteQueryRequest], - Union[ - completion_service.CompleteQueryResponse, - Awaitable[completion_service.CompleteQueryResponse] - ]]: - raise NotImplementedError() - - @property - def import_completion_data(self) -> Callable[ - [import_config.ImportCompletionDataRequest], - Union[ - operations_pb2.Operation, - Awaitable[operations_pb2.Operation] - ]]: - raise NotImplementedError() - - -__all__ = ( - 'CompletionServiceTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc.py deleted file mode 100644 index 321cbca8..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc.py +++ /dev/null @@ -1,318 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import operations_v1 -from google.api_core import gapic_v1 -import google.auth # type: ignore -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore - -import grpc # type: ignore - -from google.cloud.retail_v2.types import completion_service -from google.cloud.retail_v2.types import import_config -from google.longrunning import operations_pb2 # type: ignore -from .base import CompletionServiceTransport, DEFAULT_CLIENT_INFO - - -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. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - _stubs: Dict[str, Callable] - - def __init__(self, *, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: str = None, - scopes: Sequence[str] = None, - channel: grpc.Channel = None, - api_mtls_endpoint: str = None, - client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, - client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to. - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if ``channel`` is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if ``channel`` is provided. - channel (Optional[grpc.Channel]): A ``Channel`` instance through - which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if ``channel`` is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if ``channel`` or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - self._operations_client: Optional[operations_v1.OperationsClient] = None - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn("client_cert_source is deprecated", DeprecationWarning) - - if channel: - # Ignore credentials if a channel was passed. - credentials = False - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - else: - self._ssl_channel_credentials = SslCredentials().ssl_credentials - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - ) - - if not self._grpc_channel: - self._grpc_channel = type(self).create_channel( - self._host, - credentials=self._credentials, - credentials_file=credentials_file, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Wrap messages. This must be done after self._grpc_channel exists - self._prep_wrapped_messages(client_info) - - @classmethod - def create_channel(cls, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: str = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service. - """ - return self._grpc_channel - - @property - def operations_client(self) -> operations_v1.OperationsClient: - """Create the client designed to process long-running operations. - - This property caches on the instance; repeated calls return the same - client. - """ - # Sanity check: Only create a new client if we do not already have one. - if self._operations_client is None: - self._operations_client = operations_v1.OperationsClient( - self.grpc_channel - ) - - # Return the client from cache. - return self._operations_client - - @property - def complete_query(self) -> Callable[ - [completion_service.CompleteQueryRequest], - completion_service.CompleteQueryResponse]: - 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. - - Returns: - Callable[[~.CompleteQueryRequest], - ~.CompleteQueryResponse]: - 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 'complete_query' not in self._stubs: - self._stubs['complete_query'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.CompletionService/CompleteQuery', - request_serializer=completion_service.CompleteQueryRequest.serialize, - response_deserializer=completion_service.CompleteQueryResponse.deserialize, - ) - return self._stubs['complete_query'] - - @property - def import_completion_data(self) -> Callable[ - [import_config.ImportCompletionDataRequest], - operations_pb2.Operation]: - 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. - - Returns: - Callable[[~.ImportCompletionDataRequest], - ~.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 'import_completion_data' not in self._stubs: - self._stubs['import_completion_data'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.CompletionService/ImportCompletionData', - request_serializer=import_config.ImportCompletionDataRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs['import_completion_data'] - - def close(self): - self.grpc_channel.close() - -__all__ = ( - 'CompletionServiceGrpcTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc_asyncio.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc_asyncio.py deleted file mode 100644 index 0731a483..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,322 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.api_core import operations_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore - -import grpc # type: ignore -from grpc.experimental import aio # type: ignore - -from google.cloud.retail_v2.types import completion_service -from google.cloud.retail_v2.types import import_config -from google.longrunning import operations_pb2 # type: ignore -from .base import CompletionServiceTransport, DEFAULT_CLIENT_INFO -from .grpc import CompletionServiceGrpcTransport - - -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. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel(cls, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs - ) - - def __init__(self, *, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: aio.Channel = None, - api_mtls_endpoint: str = None, - client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, - client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, - quota_project_id=None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to. - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if ``channel`` is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[aio.Channel]): A ``Channel`` instance through - which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if ``channel`` is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if ``channel`` or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn("client_cert_source is deprecated", DeprecationWarning) - - if channel: - # Ignore credentials if a channel was passed. - credentials = False - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - else: - self._ssl_channel_credentials = SslCredentials().ssl_credentials - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - ) - - if not self._grpc_channel: - self._grpc_channel = type(self).create_channel( - self._host, - credentials=self._credentials, - credentials_file=credentials_file, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Wrap messages. This must be done after self._grpc_channel exists - self._prep_wrapped_messages(client_info) - - @property - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def operations_client(self) -> operations_v1.OperationsAsyncClient: - """Create the client designed to process long-running operations. - - This property caches on the instance; repeated calls return the same - client. - """ - # Sanity check: Only create a new client if we do not already have one. - if self._operations_client is None: - self._operations_client = operations_v1.OperationsAsyncClient( - self.grpc_channel - ) - - # Return the client from cache. - return self._operations_client - - @property - def complete_query(self) -> Callable[ - [completion_service.CompleteQueryRequest], - Awaitable[completion_service.CompleteQueryResponse]]: - 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. - - Returns: - Callable[[~.CompleteQueryRequest], - Awaitable[~.CompleteQueryResponse]]: - 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 'complete_query' not in self._stubs: - self._stubs['complete_query'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.CompletionService/CompleteQuery', - request_serializer=completion_service.CompleteQueryRequest.serialize, - response_deserializer=completion_service.CompleteQueryResponse.deserialize, - ) - return self._stubs['complete_query'] - - @property - def import_completion_data(self) -> Callable[ - [import_config.ImportCompletionDataRequest], - Awaitable[operations_pb2.Operation]]: - 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. - - Returns: - Callable[[~.ImportCompletionDataRequest], - 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 'import_completion_data' not in self._stubs: - self._stubs['import_completion_data'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.CompletionService/ImportCompletionData', - request_serializer=import_config.ImportCompletionDataRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs['import_completion_data'] - - def close(self): - return self.grpc_channel.close() - - -__all__ = ( - 'CompletionServiceGrpcAsyncIOTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/__init__.py deleted file mode 100644 index 13c5d11c..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .client import PredictionServiceClient -from .async_client import PredictionServiceAsyncClient - -__all__ = ( - 'PredictionServiceClient', - 'PredictionServiceAsyncClient', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/async_client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/async_client.py deleted file mode 100644 index 9593b0ea..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/async_client.py +++ /dev/null @@ -1,255 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -import functools -import re -from typing import Dict, Optional, Sequence, Tuple, Type, Union -import pkg_resources - -from google.api_core.client_options import ClientOptions -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object] # type: ignore - -from google.cloud.retail_v2.types import prediction_service -from .transports.base import PredictionServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc_asyncio import PredictionServiceGrpcAsyncIOTransport -from .client import PredictionServiceClient - - -class PredictionServiceAsyncClient: - """Service for making recommendation prediction.""" - - _client: PredictionServiceClient - - DEFAULT_ENDPOINT = PredictionServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = PredictionServiceClient.DEFAULT_MTLS_ENDPOINT - - product_path = staticmethod(PredictionServiceClient.product_path) - parse_product_path = staticmethod(PredictionServiceClient.parse_product_path) - common_billing_account_path = staticmethod(PredictionServiceClient.common_billing_account_path) - parse_common_billing_account_path = staticmethod(PredictionServiceClient.parse_common_billing_account_path) - common_folder_path = staticmethod(PredictionServiceClient.common_folder_path) - parse_common_folder_path = staticmethod(PredictionServiceClient.parse_common_folder_path) - common_organization_path = staticmethod(PredictionServiceClient.common_organization_path) - parse_common_organization_path = staticmethod(PredictionServiceClient.parse_common_organization_path) - common_project_path = staticmethod(PredictionServiceClient.common_project_path) - parse_common_project_path = staticmethod(PredictionServiceClient.parse_common_project_path) - common_location_path = staticmethod(PredictionServiceClient.common_location_path) - parse_common_location_path = staticmethod(PredictionServiceClient.parse_common_location_path) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - PredictionServiceAsyncClient: The constructed client. - """ - return PredictionServiceClient.from_service_account_info.__func__(PredictionServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - PredictionServiceAsyncClient: The constructed client. - """ - return PredictionServiceClient.from_service_account_file.__func__(PredictionServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[ClientOptions] = None): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variabel is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return PredictionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> PredictionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - PredictionServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - get_transport_class = functools.partial(type(PredictionServiceClient).get_transport_class, type(PredictionServiceClient)) - - def __init__(self, *, - credentials: ga_credentials.Credentials = None, - transport: Union[str, PredictionServiceTransport] = "grpc_asyncio", - client_options: ClientOptions = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the prediction service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Union[str, ~.PredictionServiceTransport]): The - transport to use. If set to None, a transport is chosen - automatically. - client_options (ClientOptions): Custom options for the client. It - won't take effect if a ``transport`` instance is provided. - (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT - environment variable can also be used to override the endpoint: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = PredictionServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - - ) - - async def predict(self, - request: Union[prediction_service.PredictRequest, dict] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> prediction_service.PredictResponse: - r"""Makes a recommendation prediction. - - Args: - request (Union[google.cloud.retail_v2.types.PredictRequest, dict]): - The request object. Request message for Predict method. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.types.PredictResponse: - Response message for predict method. - """ - # Create or coerce a protobuf request object. - request = prediction_service.PredictRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.predict, - 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(( - ("placement", request.placement), - )), - ) - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self): - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - -try: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution( - "google-cloud-retail", - ).version, - ) -except pkg_resources.DistributionNotFound: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() - - -__all__ = ( - "PredictionServiceAsyncClient", -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/client.py deleted file mode 100644 index b0217ea8..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/client.py +++ /dev/null @@ -1,452 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -import os -import re -from typing import Dict, Optional, Sequence, Tuple, Type, Union -import pkg_resources - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object] # type: ignore - -from google.cloud.retail_v2.types import prediction_service -from .transports.base import PredictionServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import PredictionServiceGrpcTransport -from .transports.grpc_asyncio import PredictionServiceGrpcAsyncIOTransport - - -class PredictionServiceClientMeta(type): - """Metaclass for the PredictionService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - _transport_registry = OrderedDict() # type: Dict[str, Type[PredictionServiceTransport]] - _transport_registry["grpc"] = PredictionServiceGrpcTransport - _transport_registry["grpc_asyncio"] = PredictionServiceGrpcAsyncIOTransport - - def get_transport_class(cls, - label: str = None, - ) -> Type[PredictionServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class PredictionServiceClient(metaclass=PredictionServiceClientMeta): - """Service for making recommendation prediction.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - DEFAULT_ENDPOINT = "retail.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - PredictionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info(info) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - PredictionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> PredictionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - PredictionServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def product_path(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(project=project, location=location, catalog=catalog, branch=branch, product=product, ) - - @staticmethod - def parse_product_path(path: str) -> Dict[str,str]: - """Parses a product path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)/products/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path(billing_account: str, ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str,str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path(folder: str, ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format(folder=folder, ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str,str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path(organization: str, ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format(organization=organization, ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str,str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path(project: str, ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format(project=project, ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str,str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path(project: str, location: str, ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format(project=project, location=location, ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str,str]: - """Parse a location path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variabel is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError("Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`") - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError("Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`") - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - def __init__(self, *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Union[str, PredictionServiceTransport, None] = None, - client_options: Optional[client_options_lib.ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the prediction service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Union[str, PredictionServiceTransport]): The - transport to use. If set to None, a transport is chosen - automatically. - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. It won't take effect if a ``transport`` instance is provided. - (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT - environment variable can also be used to override the endpoint: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - if isinstance(client_options, dict): - client_options = client_options_lib.from_dict(client_options) - if client_options is None: - client_options = client_options_lib.ClientOptions() - - api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options) - - api_key_value = getattr(client_options, "api_key", None) - if api_key_value and credentials: - raise ValueError("client_options.api_key and credentials are mutually exclusive") - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - if isinstance(transport, PredictionServiceTransport): - # transport is a PredictionServiceTransport instance. - if credentials or client_options.credentials_file or api_key_value: - raise ValueError("When providing a transport instance, " - "provide its credentials directly.") - if client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = transport - else: - import google.auth._default # type: ignore - - if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"): - credentials = google.auth._default.get_api_key_credentials(api_key_value) - - Transport = type(self).get_transport_class(transport) - self._transport = Transport( - credentials=credentials, - credentials_file=client_options.credentials_file, - host=api_endpoint, - scopes=client_options.scopes, - client_cert_source_for_mtls=client_cert_source_func, - quota_project_id=client_options.quota_project_id, - client_info=client_info, - always_use_jwt_access=True, - ) - - def predict(self, - request: Union[prediction_service.PredictRequest, dict] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> prediction_service.PredictResponse: - r"""Makes a recommendation prediction. - - Args: - request (Union[google.cloud.retail_v2.types.PredictRequest, dict]): - The request object. Request message for Predict method. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.types.PredictResponse: - Response message for predict method. - """ - # Create or coerce a protobuf request object. - # Minor optimization to avoid making a copy if the user passes - # in a prediction_service.PredictRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, prediction_service.PredictRequest): - request = prediction_service.PredictRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.predict] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("placement", request.placement), - )), - ) - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self): - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - - -try: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution( - "google-cloud-retail", - ).version, - ) -except pkg_resources.DistributionNotFound: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() - - -__all__ = ( - "PredictionServiceClient", -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/__init__.py deleted file mode 100644 index d747de2c..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from typing import Dict, Type - -from .base import PredictionServiceTransport -from .grpc import PredictionServiceGrpcTransport -from .grpc_asyncio import PredictionServiceGrpcAsyncIOTransport - - -# Compile a registry of transports. -_transport_registry = OrderedDict() # type: Dict[str, Type[PredictionServiceTransport]] -_transport_registry['grpc'] = PredictionServiceGrpcTransport -_transport_registry['grpc_asyncio'] = PredictionServiceGrpcAsyncIOTransport - -__all__ = ( - 'PredictionServiceTransport', - 'PredictionServiceGrpcTransport', - 'PredictionServiceGrpcAsyncIOTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/base.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/base.py deleted file mode 100644 index b0debf1c..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/base.py +++ /dev/null @@ -1,145 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Dict, Optional, Sequence, Union -import pkg_resources - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore - -from google.cloud.retail_v2.types import prediction_service - -try: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution( - 'google-cloud-retail', - ).version, - ) -except pkg_resources.DistributionNotFound: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() - - -class PredictionServiceTransport(abc.ABC): - """Abstract transport class for PredictionService.""" - - AUTH_SCOPES = ( - 'https://www.googleapis.com/auth/cloud-platform', - ) - - DEFAULT_HOST: str = 'retail.googleapis.com' - def __init__( - self, *, - host: str = DEFAULT_HOST, - credentials: ga_credentials.Credentials = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to. - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ':' not in host: - host += ':443' - self._host = host - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs("'credentials_file' and 'credentials' are mutually exclusive") - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id - ) - elif credentials is None: - credentials, _ = google.auth.default(**scopes_kwargs, quota_project_id=quota_project_id) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if always_use_jwt_access and isinstance(credentials, service_account.Credentials) and hasattr(service_account.Credentials, "with_always_use_jwt_access"): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - 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, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def predict(self) -> Callable[ - [prediction_service.PredictRequest], - Union[ - prediction_service.PredictResponse, - Awaitable[prediction_service.PredictResponse] - ]]: - raise NotImplementedError() - - -__all__ = ( - 'PredictionServiceTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc.py deleted file mode 100644 index 90ae3faa..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc.py +++ /dev/null @@ -1,254 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -import google.auth # type: ignore -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore - -import grpc # type: ignore - -from google.cloud.retail_v2.types import prediction_service -from .base import PredictionServiceTransport, DEFAULT_CLIENT_INFO - - -class PredictionServiceGrpcTransport(PredictionServiceTransport): - """gRPC backend transport for PredictionService. - - Service for making recommendation prediction. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - _stubs: Dict[str, Callable] - - def __init__(self, *, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: str = None, - scopes: Sequence[str] = None, - channel: grpc.Channel = None, - api_mtls_endpoint: str = None, - client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, - client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to. - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if ``channel`` is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if ``channel`` is provided. - channel (Optional[grpc.Channel]): A ``Channel`` instance through - which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if ``channel`` is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if ``channel`` or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn("client_cert_source is deprecated", DeprecationWarning) - - if channel: - # Ignore credentials if a channel was passed. - credentials = False - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - else: - self._ssl_channel_credentials = SslCredentials().ssl_credentials - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - ) - - if not self._grpc_channel: - self._grpc_channel = type(self).create_channel( - self._host, - credentials=self._credentials, - credentials_file=credentials_file, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Wrap messages. This must be done after self._grpc_channel exists - self._prep_wrapped_messages(client_info) - - @classmethod - def create_channel(cls, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: str = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service. - """ - return self._grpc_channel - - @property - def predict(self) -> Callable[ - [prediction_service.PredictRequest], - prediction_service.PredictResponse]: - r"""Return a callable for the predict method over gRPC. - - Makes a recommendation prediction. - - Returns: - Callable[[~.PredictRequest], - ~.PredictResponse]: - 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 'predict' not in self._stubs: - self._stubs['predict'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.PredictionService/Predict', - request_serializer=prediction_service.PredictRequest.serialize, - response_deserializer=prediction_service.PredictResponse.deserialize, - ) - return self._stubs['predict'] - - def close(self): - self.grpc_channel.close() - -__all__ = ( - 'PredictionServiceGrpcTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc_asyncio.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc_asyncio.py deleted file mode 100644 index 5aafb5f8..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,258 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore - -import grpc # type: ignore -from grpc.experimental import aio # type: ignore - -from google.cloud.retail_v2.types import prediction_service -from .base import PredictionServiceTransport, DEFAULT_CLIENT_INFO -from .grpc import PredictionServiceGrpcTransport - - -class PredictionServiceGrpcAsyncIOTransport(PredictionServiceTransport): - """gRPC AsyncIO backend transport for PredictionService. - - Service for making recommendation prediction. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel(cls, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs - ) - - def __init__(self, *, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: aio.Channel = None, - api_mtls_endpoint: str = None, - client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, - client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, - quota_project_id=None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to. - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if ``channel`` is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[aio.Channel]): A ``Channel`` instance through - which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if ``channel`` is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if ``channel`` or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn("client_cert_source is deprecated", DeprecationWarning) - - if channel: - # Ignore credentials if a channel was passed. - credentials = False - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - else: - self._ssl_channel_credentials = SslCredentials().ssl_credentials - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - ) - - if not self._grpc_channel: - self._grpc_channel = type(self).create_channel( - self._host, - credentials=self._credentials, - credentials_file=credentials_file, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Wrap messages. This must be done after self._grpc_channel exists - self._prep_wrapped_messages(client_info) - - @property - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def predict(self) -> Callable[ - [prediction_service.PredictRequest], - Awaitable[prediction_service.PredictResponse]]: - r"""Return a callable for the predict method over gRPC. - - Makes a recommendation prediction. - - Returns: - Callable[[~.PredictRequest], - Awaitable[~.PredictResponse]]: - 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 'predict' not in self._stubs: - self._stubs['predict'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.PredictionService/Predict', - request_serializer=prediction_service.PredictRequest.serialize, - response_deserializer=prediction_service.PredictResponse.deserialize, - ) - return self._stubs['predict'] - - def close(self): - return self.grpc_channel.close() - - -__all__ = ( - 'PredictionServiceGrpcAsyncIOTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/__init__.py deleted file mode 100644 index 0cea8c87..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .client import ProductServiceClient -from .async_client import ProductServiceAsyncClient - -__all__ = ( - 'ProductServiceClient', - 'ProductServiceAsyncClient', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/async_client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/async_client.py deleted file mode 100644 index e1cc0b41..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/async_client.py +++ /dev/null @@ -1,1190 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -import functools -import re -from typing import Dict, Optional, Sequence, Tuple, Type, Union -import pkg_resources - -from google.api_core.client_options import ClientOptions -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object] # type: ignore - -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore -from google.cloud.retail_v2.services.product_service import pagers -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 product as gcr_product -from google.cloud.retail_v2.types import product_service -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 -from .transports.base import ProductServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc_asyncio import ProductServiceGrpcAsyncIOTransport -from .client import ProductServiceClient - - -class ProductServiceAsyncClient: - """Service for ingesting [Product][google.cloud.retail.v2.Product] - information of the customer's website. - """ - - _client: ProductServiceClient - - DEFAULT_ENDPOINT = ProductServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ProductServiceClient.DEFAULT_MTLS_ENDPOINT - - branch_path = staticmethod(ProductServiceClient.branch_path) - parse_branch_path = staticmethod(ProductServiceClient.parse_branch_path) - product_path = staticmethod(ProductServiceClient.product_path) - parse_product_path = staticmethod(ProductServiceClient.parse_product_path) - common_billing_account_path = staticmethod(ProductServiceClient.common_billing_account_path) - parse_common_billing_account_path = staticmethod(ProductServiceClient.parse_common_billing_account_path) - common_folder_path = staticmethod(ProductServiceClient.common_folder_path) - parse_common_folder_path = staticmethod(ProductServiceClient.parse_common_folder_path) - common_organization_path = staticmethod(ProductServiceClient.common_organization_path) - parse_common_organization_path = staticmethod(ProductServiceClient.parse_common_organization_path) - common_project_path = staticmethod(ProductServiceClient.common_project_path) - parse_common_project_path = staticmethod(ProductServiceClient.parse_common_project_path) - common_location_path = staticmethod(ProductServiceClient.common_location_path) - parse_common_location_path = staticmethod(ProductServiceClient.parse_common_location_path) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ProductServiceAsyncClient: The constructed client. - """ - return ProductServiceClient.from_service_account_info.__func__(ProductServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ProductServiceAsyncClient: The constructed client. - """ - return ProductServiceClient.from_service_account_file.__func__(ProductServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[ClientOptions] = None): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variabel is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return ProductServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> ProductServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ProductServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - get_transport_class = functools.partial(type(ProductServiceClient).get_transport_class, type(ProductServiceClient)) - - def __init__(self, *, - credentials: ga_credentials.Credentials = None, - transport: Union[str, ProductServiceTransport] = "grpc_asyncio", - client_options: ClientOptions = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the product service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Union[str, ~.ProductServiceTransport]): The - transport to use. If set to None, a transport is chosen - automatically. - client_options (ClientOptions): Custom options for the client. It - won't take effect if a ``transport`` instance is provided. - (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT - environment variable can also be used to override the endpoint: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = ProductServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - - ) - - async def create_product(self, - request: Union[product_service.CreateProductRequest, dict] = None, - *, - parent: str = None, - product: gcr_product.Product = None, - product_id: str = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> gcr_product.Product: - r"""Creates a [Product][google.cloud.retail.v2.Product]. - - Args: - request (Union[google.cloud.retail_v2.types.CreateProductRequest, dict]): - The request object. Request message for - [CreateProduct][] method. - parent (:class:`str`): - Required. The parent catalog resource name, such as - ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch``. - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - product (:class:`google.cloud.retail_v2.types.Product`): - Required. The [Product][google.cloud.retail.v2.Product] - to create. - - This corresponds to the ``product`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - product_id (:class:`str`): - Required. The ID to use for the - [Product][google.cloud.retail.v2.Product], which will - become the final component of the - [Product.name][google.cloud.retail.v2.Product.name]. - - If the caller does not have permission to create the - [Product][google.cloud.retail.v2.Product], regardless of - whether or not it exists, a PERMISSION_DENIED error is - returned. - - This field must be unique among all - [Product][google.cloud.retail.v2.Product]s with the same - [parent][google.cloud.retail.v2.CreateProductRequest.parent]. - Otherwise, an ALREADY_EXISTS error is returned. - - This field must be a UTF-8 encoded string with a length - limit of 128 characters. Otherwise, an INVALID_ARGUMENT - error is returned. - - This corresponds to the ``product_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.types.Product: - Product captures all metadata - information of items to be recommended - or searched. - - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, product, product_id]) - 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.CreateProductRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if parent is not None: - request.parent = parent - if product is not None: - request.product = product - if product_id is not None: - request.product_id = product_id - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.create_product, - default_timeout=None, - client_info=DEFAULT_CLIENT_INFO, - ) - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("parent", request.parent), - )), - ) - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def get_product(self, - request: Union[product_service.GetProductRequest, dict] = None, - *, - name: str = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> product.Product: - r"""Gets a [Product][google.cloud.retail.v2.Product]. - - Args: - request (Union[google.cloud.retail_v2.types.GetProductRequest, dict]): - The request object. Request message for [GetProduct][] - method. - name (: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. - - If the requested - [Product][google.cloud.retail.v2.Product] does not - exist, a NOT_FOUND error is returned. - - This corresponds to the ``name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.types.Product: - Product captures all metadata - information of items to be recommended - or searched. - - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: - raise ValueError("If the `request` argument is set, then none of " - "the individual field arguments should be set.") - - request = product_service.GetProductRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if name is not None: - request.name = name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.get_product, - default_timeout=None, - client_info=DEFAULT_CLIENT_INFO, - ) - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("name", request.name), - )), - ) - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def list_products(self, - request: Union[product_service.ListProductsRequest, dict] = None, - *, - parent: str = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> pagers.ListProductsAsyncPager: - r"""Gets a list of [Product][google.cloud.retail.v2.Product]s. - - Args: - request (Union[google.cloud.retail_v2.types.ListProductsRequest, dict]): - The request object. Request message for - [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] - method. - parent (:class:`str`): - Required. The parent branch resource name, such as - ``projects/*/locations/global/catalogs/default_catalog/branches/0``. - Use ``default_branch`` as the branch ID, to list - products under the default branch. - - If the caller does not have permission to list - [Product][google.cloud.retail.v2.Product]s under this - branch, regardless of whether or not this branch exists, - a PERMISSION_DENIED error is returned. - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.services.product_service.pagers.ListProductsAsyncPager: - Response message for - [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] - method. - - Iterating over this object will yield results and - resolve additional pages automatically. - - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent]) - if request is not None and has_flattened_params: - raise ValueError("If the `request` argument is set, then none of " - "the individual field arguments should be set.") - - request = product_service.ListProductsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if parent is not None: - request.parent = parent - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.list_products, - default_timeout=None, - client_info=DEFAULT_CLIENT_INFO, - ) - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("parent", request.parent), - )), - ) - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__aiter__` convenience method. - response = pagers.ListProductsAsyncPager( - method=rpc, - request=request, - response=response, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def update_product(self, - request: Union[product_service.UpdateProductRequest, dict] = None, - *, - product: gcr_product.Product = None, - update_mask: field_mask_pb2.FieldMask = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> gcr_product.Product: - r"""Updates a [Product][google.cloud.retail.v2.Product]. - - Args: - request (Union[google.cloud.retail_v2.types.UpdateProductRequest, dict]): - The request object. Request message for - [UpdateProduct][] method. - product (:class:`google.cloud.retail_v2.types.Product`): - Required. The product to update/create. - - If the caller does not have permission to update the - [Product][google.cloud.retail.v2.Product], regardless of - whether or not it exists, a PERMISSION_DENIED error is - returned. - - If the [Product][google.cloud.retail.v2.Product] to - update does not exist and - [allow_missing][google.cloud.retail.v2.UpdateProductRequest.allow_missing] - is not set, a NOT_FOUND error is returned. - - This corresponds to the ``product`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): - Indicates which fields in the provided - [Product][google.cloud.retail.v2.Product] to update. The - immutable and output only fields are NOT supported. If - not set, all supported fields (the fields that are - neither immutable nor output only) are updated. - - If an unsupported or unknown field is provided, an - INVALID_ARGUMENT error is returned. - - This corresponds to the ``update_mask`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.types.Product: - Product captures all metadata - information of items to be recommended - or searched. - - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([product, update_mask]) - if request is not None and has_flattened_params: - raise ValueError("If the `request` argument is set, then none of " - "the individual field arguments should be set.") - - request = product_service.UpdateProductRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if product is not None: - request.product = product - if update_mask is not None: - request.update_mask = update_mask - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.update_product, - 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.name", request.product.name), - )), - ) - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def delete_product(self, - request: Union[product_service.DeleteProductRequest, dict] = None, - *, - name: str = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> None: - r"""Deletes a [Product][google.cloud.retail.v2.Product]. - - Args: - request (Union[google.cloud.retail_v2.types.DeleteProductRequest, dict]): - The request object. Request message for - [DeleteProduct][] method. - name (: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 delete the - [Product][google.cloud.retail.v2.Product], regardless of - whether or not it exists, a PERMISSION_DENIED error is - returned. - - If the [Product][google.cloud.retail.v2.Product] to - delete does not exist, a NOT_FOUND error is returned. - - The [Product][google.cloud.retail.v2.Product] to delete - can neither be a - [Product.Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION] - [Product][google.cloud.retail.v2.Product] member nor a - [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] - [Product][google.cloud.retail.v2.Product] with more than - one - [variants][google.cloud.retail.v2.Product.Type.VARIANT]. - Otherwise, an INVALID_ARGUMENT error is returned. - - All inventory information for the named - [Product][google.cloud.retail.v2.Product] will be - deleted. - - This corresponds to the ``name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: - raise ValueError("If the `request` argument is set, then none of " - "the individual field arguments should be set.") - - request = product_service.DeleteProductRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if name is not None: - request.name = name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.delete_product, - default_timeout=None, - client_info=DEFAULT_CLIENT_INFO, - ) - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("name", request.name), - )), - ) - - # Send the request. - await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - async def import_products(self, - request: Union[import_config.ImportProductsRequest, dict] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation_async.AsyncOperation: - r"""Bulk import of multiple - [Product][google.cloud.retail.v2.Product]s. - - Request processing may be synchronous. No partial updating is - supported. Non-existing items are created. - - Note that it is possible for a subset of the - [Product][google.cloud.retail.v2.Product]s to be successfully - updated. - - Args: - request (Union[google.cloud.retail_v2.types.ImportProductsRequest, dict]): - The request object. Request message for Import methods. - 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.ImportProductsResponse` Response of the - [ImportProductsRequest][google.cloud.retail.v2.ImportProductsRequest]. - If the long running operation is done, then this - message is returned by the - google.longrunning.Operations.response field if the - operation was successful. - - """ - # Create or coerce a protobuf request object. - request = import_config.ImportProductsRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.import_products, - default_retry=retries.Retry( -initial=0.1,maximum=300.0,multiplier=1.3, predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=300.0, - ), - default_timeout=300.0, - client_info=DEFAULT_CLIENT_INFO, - ) - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("parent", request.parent), - )), - ) - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation_async.from_gapic( - response, - self._client._transport.operations_client, - import_config.ImportProductsResponse, - metadata_type=import_config.ImportMetadata, - ) - - # Done; return the response. - return response - - async def set_inventory(self, - request: Union[product_service.SetInventoryRequest, dict] = None, - *, - inventory: product.Product = None, - set_mask: field_mask_pb2.FieldMask = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation_async.AsyncOperation: - r"""Updates inventory information for a - [Product][google.cloud.retail.v2.Product] 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 fulfillment information. If the request is valid, the - update will be enqueued and processed downstream. As a - consequence, when a response is returned, updates are not - immediately manifested in the - [Product][google.cloud.retail.v2.Product] queried by - [GetProduct][google.cloud.retail.v2.ProductService.GetProduct] - or - [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. - - When inventory is updated with - [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] - and - [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct], - the specified inventory field value(s) will overwrite any - existing value(s) while ignoring the last update time for this - field. Furthermore, the last update time for the specified - inventory fields will be overwritten to the time of the - [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] - or - [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] - request. - - If no inventory fields are set in - [CreateProductRequest.product][google.cloud.retail.v2.CreateProductRequest.product], - then any pre-existing inventory information for this product - will be used. - - If no inventory fields are set in - [UpdateProductRequest.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], - [AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces], - and - [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. - - Args: - request (Union[google.cloud.retail_v2.types.SetInventoryRequest, dict]): - The request object. Request message for [SetInventory][] - method. - inventory (:class:`google.cloud.retail_v2.types.Product`): - Required. The inventory information to update. The - allowable fields to update are: - - - [Product.price_info][google.cloud.retail.v2.Product.price_info] - - [Product.availability][google.cloud.retail.v2.Product.availability] - - [Product.available_quantity][google.cloud.retail.v2.Product.available_quantity] - - [Product.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] - The updated inventory fields must be specified in - [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask]. - - If [SetInventoryRequest.inventory.name][] is empty or - invalid, an INVALID_ARGUMENT error is returned. - - If the caller does not have permission to update the - [Product][google.cloud.retail.v2.Product] named in - [Product.name][google.cloud.retail.v2.Product.name], - regardless of whether or not it exists, a - PERMISSION_DENIED error is returned. - - If the [Product][google.cloud.retail.v2.Product] to - update does not have existing inventory information, the - provided inventory information will be inserted. - - If the [Product][google.cloud.retail.v2.Product] to - update has existing inventory information, the provided - inventory information will be merged while respecting - the last update time for each inventory field, using the - provided or default value for - [SetInventoryRequest.set_time][google.cloud.retail.v2.SetInventoryRequest.set_time]. - - The last update time is recorded for the following - inventory fields: - - - [Product.price_info][google.cloud.retail.v2.Product.price_info] - - [Product.availability][google.cloud.retail.v2.Product.availability] - - [Product.available_quantity][google.cloud.retail.v2.Product.available_quantity] - - [Product.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] - - If a full overwrite of inventory information while - ignoring timestamps is needed, [UpdateProduct][] should - be invoked instead. - - This corresponds to the ``inventory`` field - on the ``request`` instance; if ``request`` is provided, this - 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. - - If an unsupported or unknown field is provided, an - INVALID_ARGUMENT error is returned and the entire update - will be ignored. - - This corresponds to the ``set_mask`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.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.SetInventoryResponse` Response of the SetInventoryRequest. Currently empty because - there is no meaningful response populated from the - [SetInventory][] method. - - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([inventory, set_mask]) - if request is not None and has_flattened_params: - raise ValueError("If the `request` argument is set, then none of " - "the individual field arguments should be set.") - - request = product_service.SetInventoryRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if inventory is not None: - request.inventory = inventory - if set_mask is not None: - request.set_mask = set_mask - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.set_inventory, - 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(( - ("inventory.name", request.inventory.name), - )), - ) - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation_async.from_gapic( - response, - self._client._transport.operations_client, - product_service.SetInventoryResponse, - metadata_type=product_service.SetInventoryMetadata, - ) - - # Done; return the response. - return response - - async def add_fulfillment_places(self, - request: Union[product_service.AddFulfillmentPlacesRequest, dict] = None, - *, - product: str = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation_async.AsyncOperation: - r"""Incrementally adds place IDs to - [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. - - This process is asynchronous and does not require the - [Product][google.cloud.retail.v2.Product] to exist before - updating fulfillment information. If the request is valid, the - update will be enqueued and processed downstream. As a - consequence, when a response is returned, the added place IDs - 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]. - - 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. - - Args: - request (Union[google.cloud.retail_v2.types.AddFulfillmentPlacesRequest, dict]): - The request object. Request message for - [AddFulfillmentPlaces][] 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.AddFulfillmentPlacesResponse` Response of the AddFulfillmentPlacesRequest. Currently empty because - there is no meaningful response populated from the - [AddFulfillmentPlaces][] method. - - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - 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.AddFulfillmentPlacesRequest(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_fulfillment_places, - 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.AddFulfillmentPlacesResponse, - metadata_type=product_service.AddFulfillmentPlacesMetadata, - ) - - # Done; return the response. - return response - - async def remove_fulfillment_places(self, - request: Union[product_service.RemoveFulfillmentPlacesRequest, dict] = None, - *, - product: str = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation_async.AsyncOperation: - r"""Incrementally removes place IDs from a - [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. - - This process is asynchronous and does not require the - [Product][google.cloud.retail.v2.Product] to exist before - updating fulfillment information. If the request is valid, the - update will be enqueued and processed downstream. As a - consequence, when a response is returned, the removed place IDs - 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]. - - 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. - - Args: - request (Union[google.cloud.retail_v2.types.RemoveFulfillmentPlacesRequest, dict]): - The request object. Request message for - [RemoveFulfillmentPlaces][] 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.RemoveFulfillmentPlacesResponse` Response of the RemoveFulfillmentPlacesRequest. Currently empty because there - is no meaningful response populated from the - [RemoveFulfillmentPlaces][] method. - - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - 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.RemoveFulfillmentPlacesRequest(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_fulfillment_places, - 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.RemoveFulfillmentPlacesResponse, - metadata_type=product_service.RemoveFulfillmentPlacesMetadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self): - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - -try: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution( - "google-cloud-retail", - ).version, - ) -except pkg_resources.DistributionNotFound: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() - - -__all__ = ( - "ProductServiceAsyncClient", -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/client.py deleted file mode 100644 index a6908eed..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/client.py +++ /dev/null @@ -1,1389 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -import os -import re -from typing import Dict, Optional, Sequence, Tuple, Type, Union -import pkg_resources - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object] # type: ignore - -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore -from google.cloud.retail_v2.services.product_service import pagers -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 product as gcr_product -from google.cloud.retail_v2.types import product_service -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 -from .transports.base import ProductServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import ProductServiceGrpcTransport -from .transports.grpc_asyncio import ProductServiceGrpcAsyncIOTransport - - -class ProductServiceClientMeta(type): - """Metaclass for the ProductService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - _transport_registry = OrderedDict() # type: Dict[str, Type[ProductServiceTransport]] - _transport_registry["grpc"] = ProductServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ProductServiceGrpcAsyncIOTransport - - def get_transport_class(cls, - label: str = None, - ) -> Type[ProductServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class ProductServiceClient(metaclass=ProductServiceClientMeta): - """Service for ingesting [Product][google.cloud.retail.v2.Product] - information of the customer's website. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - DEFAULT_ENDPOINT = "retail.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ProductServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info(info) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ProductServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> ProductServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ProductServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - 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, ) - - @staticmethod - def parse_branch_path(path: str) -> Dict[str,str]: - """Parses a branch path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def product_path(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(project=project, location=location, catalog=catalog, branch=branch, product=product, ) - - @staticmethod - def parse_product_path(path: str) -> Dict[str,str]: - """Parses a product path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)/products/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path(billing_account: str, ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str,str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path(folder: str, ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format(folder=folder, ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str,str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path(organization: str, ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format(organization=organization, ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str,str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path(project: str, ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format(project=project, ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str,str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path(project: str, location: str, ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format(project=project, location=location, ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str,str]: - """Parse a location path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variabel is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError("Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`") - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError("Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`") - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - def __init__(self, *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Union[str, ProductServiceTransport, None] = None, - client_options: Optional[client_options_lib.ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the product service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Union[str, ProductServiceTransport]): The - transport to use. If set to None, a transport is chosen - automatically. - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. It won't take effect if a ``transport`` instance is provided. - (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT - environment variable can also be used to override the endpoint: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - if isinstance(client_options, dict): - client_options = client_options_lib.from_dict(client_options) - if client_options is None: - client_options = client_options_lib.ClientOptions() - - api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options) - - api_key_value = getattr(client_options, "api_key", None) - if api_key_value and credentials: - raise ValueError("client_options.api_key and credentials are mutually exclusive") - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - if isinstance(transport, ProductServiceTransport): - # transport is a ProductServiceTransport instance. - if credentials or client_options.credentials_file or api_key_value: - raise ValueError("When providing a transport instance, " - "provide its credentials directly.") - if client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = transport - else: - import google.auth._default # type: ignore - - if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"): - credentials = google.auth._default.get_api_key_credentials(api_key_value) - - Transport = type(self).get_transport_class(transport) - self._transport = Transport( - credentials=credentials, - credentials_file=client_options.credentials_file, - host=api_endpoint, - scopes=client_options.scopes, - client_cert_source_for_mtls=client_cert_source_func, - quota_project_id=client_options.quota_project_id, - client_info=client_info, - always_use_jwt_access=True, - ) - - def create_product(self, - request: Union[product_service.CreateProductRequest, dict] = None, - *, - parent: str = None, - product: gcr_product.Product = None, - product_id: str = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> gcr_product.Product: - r"""Creates a [Product][google.cloud.retail.v2.Product]. - - Args: - request (Union[google.cloud.retail_v2.types.CreateProductRequest, dict]): - The request object. Request message for - [CreateProduct][] method. - parent (str): - Required. The parent catalog resource name, such as - ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch``. - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - product (google.cloud.retail_v2.types.Product): - Required. The [Product][google.cloud.retail.v2.Product] - to create. - - This corresponds to the ``product`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - product_id (str): - Required. The ID to use for the - [Product][google.cloud.retail.v2.Product], which will - become the final component of the - [Product.name][google.cloud.retail.v2.Product.name]. - - If the caller does not have permission to create the - [Product][google.cloud.retail.v2.Product], regardless of - whether or not it exists, a PERMISSION_DENIED error is - returned. - - This field must be unique among all - [Product][google.cloud.retail.v2.Product]s with the same - [parent][google.cloud.retail.v2.CreateProductRequest.parent]. - Otherwise, an ALREADY_EXISTS error is returned. - - This field must be a UTF-8 encoded string with a length - limit of 128 characters. Otherwise, an INVALID_ARGUMENT - error is returned. - - This corresponds to the ``product_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.types.Product: - Product captures all metadata - information of items to be recommended - or searched. - - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, product, product_id]) - 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.CreateProductRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, product_service.CreateProductRequest): - request = product_service.CreateProductRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if parent is not None: - request.parent = parent - if product is not None: - request.product = product - if product_id is not None: - request.product_id = product_id - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.create_product] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("parent", request.parent), - )), - ) - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def get_product(self, - request: Union[product_service.GetProductRequest, dict] = None, - *, - name: str = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> product.Product: - r"""Gets a [Product][google.cloud.retail.v2.Product]. - - Args: - request (Union[google.cloud.retail_v2.types.GetProductRequest, dict]): - The request object. Request message for [GetProduct][] - method. - name (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. - - If the requested - [Product][google.cloud.retail.v2.Product] does not - exist, a NOT_FOUND error is returned. - - This corresponds to the ``name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.types.Product: - Product captures all metadata - information of items to be recommended - or searched. - - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: - raise ValueError('If the `request` argument is set, then none of ' - 'the individual field arguments should be set.') - - # Minor optimization to avoid making a copy if the user passes - # in a product_service.GetProductRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, product_service.GetProductRequest): - request = product_service.GetProductRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if name is not None: - request.name = name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.get_product] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("name", request.name), - )), - ) - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def list_products(self, - request: Union[product_service.ListProductsRequest, dict] = None, - *, - parent: str = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> pagers.ListProductsPager: - r"""Gets a list of [Product][google.cloud.retail.v2.Product]s. - - Args: - request (Union[google.cloud.retail_v2.types.ListProductsRequest, dict]): - The request object. Request message for - [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] - method. - parent (str): - Required. The parent branch resource name, such as - ``projects/*/locations/global/catalogs/default_catalog/branches/0``. - Use ``default_branch`` as the branch ID, to list - products under the default branch. - - If the caller does not have permission to list - [Product][google.cloud.retail.v2.Product]s under this - branch, regardless of whether or not this branch exists, - a PERMISSION_DENIED error is returned. - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.services.product_service.pagers.ListProductsPager: - Response message for - [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] - method. - - Iterating over this object will yield results and - resolve additional pages automatically. - - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent]) - if request is not None and has_flattened_params: - raise ValueError('If the `request` argument is set, then none of ' - 'the individual field arguments should be set.') - - # Minor optimization to avoid making a copy if the user passes - # in a product_service.ListProductsRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, product_service.ListProductsRequest): - request = product_service.ListProductsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if parent is not None: - request.parent = parent - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.list_products] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("parent", request.parent), - )), - ) - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__iter__` convenience method. - response = pagers.ListProductsPager( - method=rpc, - request=request, - response=response, - metadata=metadata, - ) - - # Done; return the response. - return response - - def update_product(self, - request: Union[product_service.UpdateProductRequest, dict] = None, - *, - product: gcr_product.Product = None, - update_mask: field_mask_pb2.FieldMask = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> gcr_product.Product: - r"""Updates a [Product][google.cloud.retail.v2.Product]. - - Args: - request (Union[google.cloud.retail_v2.types.UpdateProductRequest, dict]): - The request object. Request message for - [UpdateProduct][] method. - product (google.cloud.retail_v2.types.Product): - Required. The product to update/create. - - If the caller does not have permission to update the - [Product][google.cloud.retail.v2.Product], regardless of - whether or not it exists, a PERMISSION_DENIED error is - returned. - - If the [Product][google.cloud.retail.v2.Product] to - update does not exist and - [allow_missing][google.cloud.retail.v2.UpdateProductRequest.allow_missing] - is not set, a NOT_FOUND error is returned. - - This corresponds to the ``product`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - update_mask (google.protobuf.field_mask_pb2.FieldMask): - Indicates which fields in the provided - [Product][google.cloud.retail.v2.Product] to update. The - immutable and output only fields are NOT supported. If - not set, all supported fields (the fields that are - neither immutable nor output only) are updated. - - If an unsupported or unknown field is provided, an - INVALID_ARGUMENT error is returned. - - This corresponds to the ``update_mask`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.types.Product: - Product captures all metadata - information of items to be recommended - or searched. - - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([product, update_mask]) - if request is not None and has_flattened_params: - raise ValueError('If the `request` argument is set, then none of ' - 'the individual field arguments should be set.') - - # Minor optimization to avoid making a copy if the user passes - # in a product_service.UpdateProductRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, product_service.UpdateProductRequest): - request = product_service.UpdateProductRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if product is not None: - request.product = product - if update_mask is not None: - request.update_mask = update_mask - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.update_product] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("product.name", request.product.name), - )), - ) - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def delete_product(self, - request: Union[product_service.DeleteProductRequest, dict] = None, - *, - name: str = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> None: - r"""Deletes a [Product][google.cloud.retail.v2.Product]. - - Args: - request (Union[google.cloud.retail_v2.types.DeleteProductRequest, dict]): - The request object. Request message for - [DeleteProduct][] method. - name (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 delete the - [Product][google.cloud.retail.v2.Product], regardless of - whether or not it exists, a PERMISSION_DENIED error is - returned. - - If the [Product][google.cloud.retail.v2.Product] to - delete does not exist, a NOT_FOUND error is returned. - - The [Product][google.cloud.retail.v2.Product] to delete - can neither be a - [Product.Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION] - [Product][google.cloud.retail.v2.Product] member nor a - [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] - [Product][google.cloud.retail.v2.Product] with more than - one - [variants][google.cloud.retail.v2.Product.Type.VARIANT]. - Otherwise, an INVALID_ARGUMENT error is returned. - - All inventory information for the named - [Product][google.cloud.retail.v2.Product] will be - deleted. - - This corresponds to the ``name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: - raise ValueError('If the `request` argument is set, then none of ' - 'the individual field arguments should be set.') - - # Minor optimization to avoid making a copy if the user passes - # in a product_service.DeleteProductRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, product_service.DeleteProductRequest): - request = product_service.DeleteProductRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if name is not None: - request.name = name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.delete_product] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("name", request.name), - )), - ) - - # Send the request. - rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - def import_products(self, - request: Union[import_config.ImportProductsRequest, dict] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation.Operation: - r"""Bulk import of multiple - [Product][google.cloud.retail.v2.Product]s. - - Request processing may be synchronous. No partial updating is - supported. Non-existing items are created. - - Note that it is possible for a subset of the - [Product][google.cloud.retail.v2.Product]s to be successfully - updated. - - Args: - request (Union[google.cloud.retail_v2.types.ImportProductsRequest, dict]): - The request object. Request message for Import methods. - 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.ImportProductsResponse` Response of the - [ImportProductsRequest][google.cloud.retail.v2.ImportProductsRequest]. - If the long running operation is done, then this - message is returned by the - google.longrunning.Operations.response field if the - operation was successful. - - """ - # Create or coerce a protobuf request object. - # Minor optimization to avoid making a copy if the user passes - # in a import_config.ImportProductsRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, import_config.ImportProductsRequest): - request = import_config.ImportProductsRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.import_products] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("parent", request.parent), - )), - ) - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation.from_gapic( - response, - self._transport.operations_client, - import_config.ImportProductsResponse, - metadata_type=import_config.ImportMetadata, - ) - - # Done; return the response. - return response - - def set_inventory(self, - request: Union[product_service.SetInventoryRequest, dict] = None, - *, - inventory: product.Product = None, - set_mask: field_mask_pb2.FieldMask = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation.Operation: - r"""Updates inventory information for a - [Product][google.cloud.retail.v2.Product] 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 fulfillment information. If the request is valid, the - update will be enqueued and processed downstream. As a - consequence, when a response is returned, updates are not - immediately manifested in the - [Product][google.cloud.retail.v2.Product] queried by - [GetProduct][google.cloud.retail.v2.ProductService.GetProduct] - or - [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. - - When inventory is updated with - [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] - and - [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct], - the specified inventory field value(s) will overwrite any - existing value(s) while ignoring the last update time for this - field. Furthermore, the last update time for the specified - inventory fields will be overwritten to the time of the - [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] - or - [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] - request. - - If no inventory fields are set in - [CreateProductRequest.product][google.cloud.retail.v2.CreateProductRequest.product], - then any pre-existing inventory information for this product - will be used. - - If no inventory fields are set in - [UpdateProductRequest.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], - [AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces], - and - [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. - - Args: - request (Union[google.cloud.retail_v2.types.SetInventoryRequest, dict]): - The request object. Request message for [SetInventory][] - method. - inventory (google.cloud.retail_v2.types.Product): - Required. The inventory information to update. The - allowable fields to update are: - - - [Product.price_info][google.cloud.retail.v2.Product.price_info] - - [Product.availability][google.cloud.retail.v2.Product.availability] - - [Product.available_quantity][google.cloud.retail.v2.Product.available_quantity] - - [Product.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] - The updated inventory fields must be specified in - [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask]. - - If [SetInventoryRequest.inventory.name][] is empty or - invalid, an INVALID_ARGUMENT error is returned. - - If the caller does not have permission to update the - [Product][google.cloud.retail.v2.Product] named in - [Product.name][google.cloud.retail.v2.Product.name], - regardless of whether or not it exists, a - PERMISSION_DENIED error is returned. - - If the [Product][google.cloud.retail.v2.Product] to - update does not have existing inventory information, the - provided inventory information will be inserted. - - If the [Product][google.cloud.retail.v2.Product] to - update has existing inventory information, the provided - inventory information will be merged while respecting - the last update time for each inventory field, using the - provided or default value for - [SetInventoryRequest.set_time][google.cloud.retail.v2.SetInventoryRequest.set_time]. - - The last update time is recorded for the following - inventory fields: - - - [Product.price_info][google.cloud.retail.v2.Product.price_info] - - [Product.availability][google.cloud.retail.v2.Product.availability] - - [Product.available_quantity][google.cloud.retail.v2.Product.available_quantity] - - [Product.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] - - If a full overwrite of inventory information while - ignoring timestamps is needed, [UpdateProduct][] should - be invoked instead. - - This corresponds to the ``inventory`` field - on the ``request`` instance; if ``request`` is provided, this - 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. - - If an unsupported or unknown field is provided, an - INVALID_ARGUMENT error is returned and the entire update - will be ignored. - - This corresponds to the ``set_mask`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.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.SetInventoryResponse` Response of the SetInventoryRequest. Currently empty because - there is no meaningful response populated from the - [SetInventory][] method. - - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([inventory, set_mask]) - if request is not None and has_flattened_params: - raise ValueError('If the `request` argument is set, then none of ' - 'the individual field arguments should be set.') - - # Minor optimization to avoid making a copy if the user passes - # in a product_service.SetInventoryRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, product_service.SetInventoryRequest): - request = product_service.SetInventoryRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if inventory is not None: - request.inventory = inventory - if set_mask is not None: - request.set_mask = set_mask - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.set_inventory] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("inventory.name", request.inventory.name), - )), - ) - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation.from_gapic( - response, - self._transport.operations_client, - product_service.SetInventoryResponse, - metadata_type=product_service.SetInventoryMetadata, - ) - - # Done; return the response. - return response - - def add_fulfillment_places(self, - request: Union[product_service.AddFulfillmentPlacesRequest, dict] = None, - *, - product: str = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation.Operation: - r"""Incrementally adds place IDs to - [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. - - This process is asynchronous and does not require the - [Product][google.cloud.retail.v2.Product] to exist before - updating fulfillment information. If the request is valid, the - update will be enqueued and processed downstream. As a - consequence, when a response is returned, the added place IDs - 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]. - - 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. - - Args: - request (Union[google.cloud.retail_v2.types.AddFulfillmentPlacesRequest, dict]): - The request object. Request message for - [AddFulfillmentPlaces][] 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.AddFulfillmentPlacesResponse` Response of the AddFulfillmentPlacesRequest. Currently empty because - there is no meaningful response populated from the - [AddFulfillmentPlaces][] method. - - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - 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.AddFulfillmentPlacesRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, product_service.AddFulfillmentPlacesRequest): - request = product_service.AddFulfillmentPlacesRequest(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_fulfillment_places] - - # 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.AddFulfillmentPlacesResponse, - metadata_type=product_service.AddFulfillmentPlacesMetadata, - ) - - # Done; return the response. - return response - - def remove_fulfillment_places(self, - request: Union[product_service.RemoveFulfillmentPlacesRequest, dict] = None, - *, - product: str = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation.Operation: - r"""Incrementally removes place IDs from a - [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. - - This process is asynchronous and does not require the - [Product][google.cloud.retail.v2.Product] to exist before - updating fulfillment information. If the request is valid, the - update will be enqueued and processed downstream. As a - consequence, when a response is returned, the removed place IDs - 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]. - - 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. - - Args: - request (Union[google.cloud.retail_v2.types.RemoveFulfillmentPlacesRequest, dict]): - The request object. Request message for - [RemoveFulfillmentPlaces][] 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.RemoveFulfillmentPlacesResponse` Response of the RemoveFulfillmentPlacesRequest. Currently empty because there - is no meaningful response populated from the - [RemoveFulfillmentPlaces][] method. - - """ - # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - 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.RemoveFulfillmentPlacesRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, product_service.RemoveFulfillmentPlacesRequest): - request = product_service.RemoveFulfillmentPlacesRequest(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_fulfillment_places] - - # 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.RemoveFulfillmentPlacesResponse, - metadata_type=product_service.RemoveFulfillmentPlacesMetadata, - ) - - # Done; return the response. - return response - - def __enter__(self): - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - - -try: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution( - "google-cloud-retail", - ).version, - ) -except pkg_resources.DistributionNotFound: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() - - -__all__ = ( - "ProductServiceClient", -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/pagers.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/pagers.py deleted file mode 100644 index d1addca2..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/pagers.py +++ /dev/null @@ -1,140 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from typing import Any, AsyncIterator, Awaitable, Callable, Sequence, Tuple, Optional, Iterator - -from google.cloud.retail_v2.types import product -from google.cloud.retail_v2.types import product_service - - -class ListProductsPager: - """A pager for iterating through ``list_products`` requests. - - This class thinly wraps an initial - :class:`google.cloud.retail_v2.types.ListProductsResponse` object, and - provides an ``__iter__`` method to iterate through its - ``products`` field. - - If there are more pages, the ``__iter__`` method will make additional - ``ListProducts`` requests and continue to iterate - through the ``products`` field on the - corresponding responses. - - All the usual :class:`google.cloud.retail_v2.types.ListProductsResponse` - attributes are available on the pager. If multiple requests are made, only - the most recent response is retained, and thus used for attribute lookup. - """ - def __init__(self, - method: Callable[..., product_service.ListProductsResponse], - request: product_service.ListProductsRequest, - response: product_service.ListProductsResponse, - *, - metadata: Sequence[Tuple[str, str]] = ()): - """Instantiate the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.cloud.retail_v2.types.ListProductsRequest): - The initial request object. - response (google.cloud.retail_v2.types.ListProductsResponse): - The initial response object. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - self._method = method - self._request = product_service.ListProductsRequest(request) - self._response = response - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - def pages(self) -> Iterator[product_service.ListProductsResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = self._method(self._request, metadata=self._metadata) - yield self._response - - def __iter__(self) -> Iterator[product.Product]: - for page in self.pages: - yield from page.products - - def __repr__(self) -> str: - return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) - - -class ListProductsAsyncPager: - """A pager for iterating through ``list_products`` requests. - - This class thinly wraps an initial - :class:`google.cloud.retail_v2.types.ListProductsResponse` object, and - provides an ``__aiter__`` method to iterate through its - ``products`` field. - - If there are more pages, the ``__aiter__`` method will make additional - ``ListProducts`` requests and continue to iterate - through the ``products`` field on the - corresponding responses. - - All the usual :class:`google.cloud.retail_v2.types.ListProductsResponse` - attributes are available on the pager. If multiple requests are made, only - the most recent response is retained, and thus used for attribute lookup. - """ - def __init__(self, - method: Callable[..., Awaitable[product_service.ListProductsResponse]], - request: product_service.ListProductsRequest, - response: product_service.ListProductsResponse, - *, - metadata: Sequence[Tuple[str, str]] = ()): - """Instantiates the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.cloud.retail_v2.types.ListProductsRequest): - The initial request object. - response (google.cloud.retail_v2.types.ListProductsResponse): - The initial response object. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - self._method = method - self._request = product_service.ListProductsRequest(request) - self._response = response - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - async def pages(self) -> AsyncIterator[product_service.ListProductsResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = await self._method(self._request, metadata=self._metadata) - yield self._response - def __aiter__(self) -> AsyncIterator[product.Product]: - async def async_generator(): - async for page in self.pages: - for response in page.products: - yield response - - return async_generator() - - def __repr__(self) -> str: - return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/__init__.py deleted file mode 100644 index 2f27ad58..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from typing import Dict, Type - -from .base import ProductServiceTransport -from .grpc import ProductServiceGrpcTransport -from .grpc_asyncio import ProductServiceGrpcAsyncIOTransport - - -# Compile a registry of transports. -_transport_registry = OrderedDict() # type: Dict[str, Type[ProductServiceTransport]] -_transport_registry['grpc'] = ProductServiceGrpcTransport -_transport_registry['grpc_asyncio'] = ProductServiceGrpcAsyncIOTransport - -__all__ = ( - 'ProductServiceTransport', - 'ProductServiceGrpcTransport', - 'ProductServiceGrpcAsyncIOTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/base.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/base.py deleted file mode 100644 index 7e475a6c..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/base.py +++ /dev/null @@ -1,275 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Dict, Optional, Sequence, Union -import pkg_resources - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.api_core import operations_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore - -from google.cloud.retail_v2.types import import_config -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.longrunning import operations_pb2 # type: ignore -from google.protobuf import empty_pb2 # type: ignore - -try: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution( - 'google-cloud-retail', - ).version, - ) -except pkg_resources.DistributionNotFound: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() - - -class ProductServiceTransport(abc.ABC): - """Abstract transport class for ProductService.""" - - AUTH_SCOPES = ( - 'https://www.googleapis.com/auth/cloud-platform', - ) - - DEFAULT_HOST: str = 'retail.googleapis.com' - def __init__( - self, *, - host: str = DEFAULT_HOST, - credentials: ga_credentials.Credentials = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to. - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ':' not in host: - host += ':443' - self._host = host - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs("'credentials_file' and 'credentials' are mutually exclusive") - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id - ) - elif credentials is None: - credentials, _ = google.auth.default(**scopes_kwargs, quota_project_id=quota_project_id) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if always_use_jwt_access and isinstance(credentials, service_account.Credentials) and hasattr(service_account.Credentials, "with_always_use_jwt_access"): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - 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.get_product: gapic_v1.method.wrap_method( - 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.update_product: gapic_v1.method.wrap_method( - 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.import_products: gapic_v1.method.wrap_method( - self.import_products, - default_retry=retries.Retry( -initial=0.1,maximum=300.0,multiplier=1.3, predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=300.0, - ), - default_timeout=300.0, - client_info=client_info, - ), - self.set_inventory: gapic_v1.method.wrap_method( - self.set_inventory, - default_timeout=None, - client_info=client_info, - ), - self.add_fulfillment_places: gapic_v1.method.wrap_method( - self.add_fulfillment_places, - default_timeout=None, - client_info=client_info, - ), - self.remove_fulfillment_places: gapic_v1.method.wrap_method( - self.remove_fulfillment_places, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def operations_client(self): - """Return the client designed to process long-running operations.""" - raise NotImplementedError() - - @property - def create_product(self) -> Callable[ - [product_service.CreateProductRequest], - Union[ - gcr_product.Product, - Awaitable[gcr_product.Product] - ]]: - raise NotImplementedError() - - @property - def get_product(self) -> Callable[ - [product_service.GetProductRequest], - Union[ - product.Product, - Awaitable[product.Product] - ]]: - raise NotImplementedError() - - @property - def list_products(self) -> Callable[ - [product_service.ListProductsRequest], - Union[ - product_service.ListProductsResponse, - Awaitable[product_service.ListProductsResponse] - ]]: - raise NotImplementedError() - - @property - def update_product(self) -> Callable[ - [product_service.UpdateProductRequest], - Union[ - gcr_product.Product, - Awaitable[gcr_product.Product] - ]]: - raise NotImplementedError() - - @property - def delete_product(self) -> Callable[ - [product_service.DeleteProductRequest], - Union[ - empty_pb2.Empty, - Awaitable[empty_pb2.Empty] - ]]: - raise NotImplementedError() - - @property - def import_products(self) -> Callable[ - [import_config.ImportProductsRequest], - Union[ - operations_pb2.Operation, - Awaitable[operations_pb2.Operation] - ]]: - raise NotImplementedError() - - @property - def set_inventory(self) -> Callable[ - [product_service.SetInventoryRequest], - Union[ - operations_pb2.Operation, - Awaitable[operations_pb2.Operation] - ]]: - raise NotImplementedError() - - @property - def add_fulfillment_places(self) -> Callable[ - [product_service.AddFulfillmentPlacesRequest], - Union[ - operations_pb2.Operation, - Awaitable[operations_pb2.Operation] - ]]: - raise NotImplementedError() - - @property - def remove_fulfillment_places(self) -> Callable[ - [product_service.RemoveFulfillmentPlacesRequest], - Union[ - operations_pb2.Operation, - Awaitable[operations_pb2.Operation] - ]]: - raise NotImplementedError() - - -__all__ = ( - 'ProductServiceTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc.py deleted file mode 100644 index 14db14bd..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc.py +++ /dev/null @@ -1,574 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import operations_v1 -from google.api_core import gapic_v1 -import google.auth # type: ignore -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore - -import grpc # type: ignore - -from google.cloud.retail_v2.types import import_config -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.longrunning import operations_pb2 # type: ignore -from google.protobuf import empty_pb2 # type: ignore -from .base import ProductServiceTransport, DEFAULT_CLIENT_INFO - - -class ProductServiceGrpcTransport(ProductServiceTransport): - """gRPC backend transport for ProductService. - - Service for ingesting [Product][google.cloud.retail.v2.Product] - information of the customer's website. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - _stubs: Dict[str, Callable] - - def __init__(self, *, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: str = None, - scopes: Sequence[str] = None, - channel: grpc.Channel = None, - api_mtls_endpoint: str = None, - client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, - client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to. - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if ``channel`` is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if ``channel`` is provided. - channel (Optional[grpc.Channel]): A ``Channel`` instance through - which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if ``channel`` is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if ``channel`` or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - self._operations_client: Optional[operations_v1.OperationsClient] = None - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn("client_cert_source is deprecated", DeprecationWarning) - - if channel: - # Ignore credentials if a channel was passed. - credentials = False - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - else: - self._ssl_channel_credentials = SslCredentials().ssl_credentials - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - ) - - if not self._grpc_channel: - self._grpc_channel = type(self).create_channel( - self._host, - credentials=self._credentials, - credentials_file=credentials_file, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Wrap messages. This must be done after self._grpc_channel exists - self._prep_wrapped_messages(client_info) - - @classmethod - def create_channel(cls, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: str = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service. - """ - return self._grpc_channel - - @property - def operations_client(self) -> operations_v1.OperationsClient: - """Create the client designed to process long-running operations. - - This property caches on the instance; repeated calls return the same - client. - """ - # Sanity check: Only create a new client if we do not already have one. - if self._operations_client is None: - self._operations_client = operations_v1.OperationsClient( - self.grpc_channel - ) - - # Return the client from cache. - return self._operations_client - - @property - def create_product(self) -> Callable[ - [product_service.CreateProductRequest], - gcr_product.Product]: - r"""Return a callable for the create product method over gRPC. - - Creates a [Product][google.cloud.retail.v2.Product]. - - Returns: - Callable[[~.CreateProductRequest], - ~.Product]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if 'create_product' not in self._stubs: - self._stubs['create_product'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.ProductService/CreateProduct', - request_serializer=product_service.CreateProductRequest.serialize, - response_deserializer=gcr_product.Product.deserialize, - ) - return self._stubs['create_product'] - - @property - def get_product(self) -> Callable[ - [product_service.GetProductRequest], - product.Product]: - r"""Return a callable for the get product method over gRPC. - - Gets a [Product][google.cloud.retail.v2.Product]. - - Returns: - Callable[[~.GetProductRequest], - ~.Product]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if 'get_product' not in self._stubs: - self._stubs['get_product'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.ProductService/GetProduct', - request_serializer=product_service.GetProductRequest.serialize, - response_deserializer=product.Product.deserialize, - ) - return self._stubs['get_product'] - - @property - def list_products(self) -> Callable[ - [product_service.ListProductsRequest], - product_service.ListProductsResponse]: - r"""Return a callable for the list products method over gRPC. - - Gets a list of [Product][google.cloud.retail.v2.Product]s. - - Returns: - Callable[[~.ListProductsRequest], - ~.ListProductsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if 'list_products' not in self._stubs: - self._stubs['list_products'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.ProductService/ListProducts', - request_serializer=product_service.ListProductsRequest.serialize, - response_deserializer=product_service.ListProductsResponse.deserialize, - ) - return self._stubs['list_products'] - - @property - def update_product(self) -> Callable[ - [product_service.UpdateProductRequest], - gcr_product.Product]: - r"""Return a callable for the update product method over gRPC. - - Updates a [Product][google.cloud.retail.v2.Product]. - - Returns: - Callable[[~.UpdateProductRequest], - ~.Product]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if 'update_product' not in self._stubs: - self._stubs['update_product'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.ProductService/UpdateProduct', - request_serializer=product_service.UpdateProductRequest.serialize, - response_deserializer=gcr_product.Product.deserialize, - ) - return self._stubs['update_product'] - - @property - def delete_product(self) -> Callable[ - [product_service.DeleteProductRequest], - empty_pb2.Empty]: - r"""Return a callable for the delete product method over gRPC. - - Deletes a [Product][google.cloud.retail.v2.Product]. - - Returns: - Callable[[~.DeleteProductRequest], - ~.Empty]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if 'delete_product' not in self._stubs: - self._stubs['delete_product'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.ProductService/DeleteProduct', - request_serializer=product_service.DeleteProductRequest.serialize, - response_deserializer=empty_pb2.Empty.FromString, - ) - return self._stubs['delete_product'] - - @property - def import_products(self) -> Callable[ - [import_config.ImportProductsRequest], - operations_pb2.Operation]: - r"""Return a callable for the import products method over gRPC. - - Bulk import of multiple - [Product][google.cloud.retail.v2.Product]s. - - Request processing may be synchronous. No partial updating is - supported. Non-existing items are created. - - Note that it is possible for a subset of the - [Product][google.cloud.retail.v2.Product]s to be successfully - updated. - - Returns: - Callable[[~.ImportProductsRequest], - ~.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 'import_products' not in self._stubs: - self._stubs['import_products'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.ProductService/ImportProducts', - request_serializer=import_config.ImportProductsRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs['import_products'] - - @property - def set_inventory(self) -> Callable[ - [product_service.SetInventoryRequest], - operations_pb2.Operation]: - r"""Return a callable for the set inventory method over gRPC. - - Updates inventory information for a - [Product][google.cloud.retail.v2.Product] 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 fulfillment information. If the request is valid, the - update will be enqueued and processed downstream. As a - consequence, when a response is returned, updates are not - immediately manifested in the - [Product][google.cloud.retail.v2.Product] queried by - [GetProduct][google.cloud.retail.v2.ProductService.GetProduct] - or - [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. - - When inventory is updated with - [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] - and - [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct], - the specified inventory field value(s) will overwrite any - existing value(s) while ignoring the last update time for this - field. Furthermore, the last update time for the specified - inventory fields will be overwritten to the time of the - [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] - or - [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] - request. - - If no inventory fields are set in - [CreateProductRequest.product][google.cloud.retail.v2.CreateProductRequest.product], - then any pre-existing inventory information for this product - will be used. - - If no inventory fields are set in - [UpdateProductRequest.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], - [AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces], - and - [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. - - Returns: - Callable[[~.SetInventoryRequest], - ~.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 'set_inventory' not in self._stubs: - self._stubs['set_inventory'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.ProductService/SetInventory', - request_serializer=product_service.SetInventoryRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs['set_inventory'] - - @property - def add_fulfillment_places(self) -> Callable[ - [product_service.AddFulfillmentPlacesRequest], - operations_pb2.Operation]: - r"""Return a callable for the add fulfillment places method over gRPC. - - Incrementally adds place IDs to - [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. - - This process is asynchronous and does not require the - [Product][google.cloud.retail.v2.Product] to exist before - updating fulfillment information. If the request is valid, the - update will be enqueued and processed downstream. As a - consequence, when a response is returned, the added place IDs - 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]. - - 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[[~.AddFulfillmentPlacesRequest], - ~.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_fulfillment_places' not in self._stubs: - self._stubs['add_fulfillment_places'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.ProductService/AddFulfillmentPlaces', - request_serializer=product_service.AddFulfillmentPlacesRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs['add_fulfillment_places'] - - @property - def remove_fulfillment_places(self) -> Callable[ - [product_service.RemoveFulfillmentPlacesRequest], - operations_pb2.Operation]: - r"""Return a callable for the remove fulfillment places method over gRPC. - - Incrementally removes place IDs from a - [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. - - This process is asynchronous and does not require the - [Product][google.cloud.retail.v2.Product] to exist before - updating fulfillment information. If the request is valid, the - update will be enqueued and processed downstream. As a - consequence, when a response is returned, the removed place IDs - 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]. - - 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[[~.RemoveFulfillmentPlacesRequest], - ~.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_fulfillment_places' not in self._stubs: - self._stubs['remove_fulfillment_places'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.ProductService/RemoveFulfillmentPlaces', - request_serializer=product_service.RemoveFulfillmentPlacesRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs['remove_fulfillment_places'] - - def close(self): - self.grpc_channel.close() - -__all__ = ( - 'ProductServiceGrpcTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc_asyncio.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc_asyncio.py deleted file mode 100644 index 811e1ff4..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,578 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.api_core import operations_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore - -import grpc # type: ignore -from grpc.experimental import aio # type: ignore - -from google.cloud.retail_v2.types import import_config -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.longrunning import operations_pb2 # type: ignore -from google.protobuf import empty_pb2 # type: ignore -from .base import ProductServiceTransport, DEFAULT_CLIENT_INFO -from .grpc import ProductServiceGrpcTransport - - -class ProductServiceGrpcAsyncIOTransport(ProductServiceTransport): - """gRPC AsyncIO backend transport for ProductService. - - Service for ingesting [Product][google.cloud.retail.v2.Product] - information of the customer's website. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel(cls, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs - ) - - def __init__(self, *, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: aio.Channel = None, - api_mtls_endpoint: str = None, - client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, - client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, - quota_project_id=None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to. - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if ``channel`` is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[aio.Channel]): A ``Channel`` instance through - which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if ``channel`` is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if ``channel`` or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn("client_cert_source is deprecated", DeprecationWarning) - - if channel: - # Ignore credentials if a channel was passed. - credentials = False - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - else: - self._ssl_channel_credentials = SslCredentials().ssl_credentials - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - ) - - if not self._grpc_channel: - self._grpc_channel = type(self).create_channel( - self._host, - credentials=self._credentials, - credentials_file=credentials_file, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Wrap messages. This must be done after self._grpc_channel exists - self._prep_wrapped_messages(client_info) - - @property - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def operations_client(self) -> operations_v1.OperationsAsyncClient: - """Create the client designed to process long-running operations. - - This property caches on the instance; repeated calls return the same - client. - """ - # Sanity check: Only create a new client if we do not already have one. - if self._operations_client is None: - self._operations_client = operations_v1.OperationsAsyncClient( - self.grpc_channel - ) - - # Return the client from cache. - return self._operations_client - - @property - def create_product(self) -> Callable[ - [product_service.CreateProductRequest], - Awaitable[gcr_product.Product]]: - r"""Return a callable for the create product method over gRPC. - - Creates a [Product][google.cloud.retail.v2.Product]. - - Returns: - Callable[[~.CreateProductRequest], - Awaitable[~.Product]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if 'create_product' not in self._stubs: - self._stubs['create_product'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.ProductService/CreateProduct', - request_serializer=product_service.CreateProductRequest.serialize, - response_deserializer=gcr_product.Product.deserialize, - ) - return self._stubs['create_product'] - - @property - def get_product(self) -> Callable[ - [product_service.GetProductRequest], - Awaitable[product.Product]]: - r"""Return a callable for the get product method over gRPC. - - Gets a [Product][google.cloud.retail.v2.Product]. - - Returns: - Callable[[~.GetProductRequest], - Awaitable[~.Product]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if 'get_product' not in self._stubs: - self._stubs['get_product'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.ProductService/GetProduct', - request_serializer=product_service.GetProductRequest.serialize, - response_deserializer=product.Product.deserialize, - ) - return self._stubs['get_product'] - - @property - def list_products(self) -> Callable[ - [product_service.ListProductsRequest], - Awaitable[product_service.ListProductsResponse]]: - r"""Return a callable for the list products method over gRPC. - - Gets a list of [Product][google.cloud.retail.v2.Product]s. - - Returns: - Callable[[~.ListProductsRequest], - Awaitable[~.ListProductsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if 'list_products' not in self._stubs: - self._stubs['list_products'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.ProductService/ListProducts', - request_serializer=product_service.ListProductsRequest.serialize, - response_deserializer=product_service.ListProductsResponse.deserialize, - ) - return self._stubs['list_products'] - - @property - def update_product(self) -> Callable[ - [product_service.UpdateProductRequest], - Awaitable[gcr_product.Product]]: - r"""Return a callable for the update product method over gRPC. - - Updates a [Product][google.cloud.retail.v2.Product]. - - Returns: - Callable[[~.UpdateProductRequest], - Awaitable[~.Product]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if 'update_product' not in self._stubs: - self._stubs['update_product'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.ProductService/UpdateProduct', - request_serializer=product_service.UpdateProductRequest.serialize, - response_deserializer=gcr_product.Product.deserialize, - ) - return self._stubs['update_product'] - - @property - def delete_product(self) -> Callable[ - [product_service.DeleteProductRequest], - Awaitable[empty_pb2.Empty]]: - r"""Return a callable for the delete product method over gRPC. - - Deletes a [Product][google.cloud.retail.v2.Product]. - - Returns: - Callable[[~.DeleteProductRequest], - Awaitable[~.Empty]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if 'delete_product' not in self._stubs: - self._stubs['delete_product'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.ProductService/DeleteProduct', - request_serializer=product_service.DeleteProductRequest.serialize, - response_deserializer=empty_pb2.Empty.FromString, - ) - return self._stubs['delete_product'] - - @property - def import_products(self) -> Callable[ - [import_config.ImportProductsRequest], - Awaitable[operations_pb2.Operation]]: - r"""Return a callable for the import products method over gRPC. - - Bulk import of multiple - [Product][google.cloud.retail.v2.Product]s. - - Request processing may be synchronous. No partial updating is - supported. Non-existing items are created. - - Note that it is possible for a subset of the - [Product][google.cloud.retail.v2.Product]s to be successfully - updated. - - Returns: - Callable[[~.ImportProductsRequest], - 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 'import_products' not in self._stubs: - self._stubs['import_products'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.ProductService/ImportProducts', - request_serializer=import_config.ImportProductsRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs['import_products'] - - @property - def set_inventory(self) -> Callable[ - [product_service.SetInventoryRequest], - Awaitable[operations_pb2.Operation]]: - r"""Return a callable for the set inventory method over gRPC. - - Updates inventory information for a - [Product][google.cloud.retail.v2.Product] 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 fulfillment information. If the request is valid, the - update will be enqueued and processed downstream. As a - consequence, when a response is returned, updates are not - immediately manifested in the - [Product][google.cloud.retail.v2.Product] queried by - [GetProduct][google.cloud.retail.v2.ProductService.GetProduct] - or - [ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. - - When inventory is updated with - [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] - and - [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct], - the specified inventory field value(s) will overwrite any - existing value(s) while ignoring the last update time for this - field. Furthermore, the last update time for the specified - inventory fields will be overwritten to the time of the - [CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] - or - [UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] - request. - - If no inventory fields are set in - [CreateProductRequest.product][google.cloud.retail.v2.CreateProductRequest.product], - then any pre-existing inventory information for this product - will be used. - - If no inventory fields are set in - [UpdateProductRequest.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], - [AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces], - and - [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. - - Returns: - Callable[[~.SetInventoryRequest], - 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 'set_inventory' not in self._stubs: - self._stubs['set_inventory'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.ProductService/SetInventory', - request_serializer=product_service.SetInventoryRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs['set_inventory'] - - @property - def add_fulfillment_places(self) -> Callable[ - [product_service.AddFulfillmentPlacesRequest], - Awaitable[operations_pb2.Operation]]: - r"""Return a callable for the add fulfillment places method over gRPC. - - Incrementally adds place IDs to - [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. - - This process is asynchronous and does not require the - [Product][google.cloud.retail.v2.Product] to exist before - updating fulfillment information. If the request is valid, the - update will be enqueued and processed downstream. As a - consequence, when a response is returned, the added place IDs - 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]. - - 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[[~.AddFulfillmentPlacesRequest], - 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_fulfillment_places' not in self._stubs: - self._stubs['add_fulfillment_places'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.ProductService/AddFulfillmentPlaces', - request_serializer=product_service.AddFulfillmentPlacesRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs['add_fulfillment_places'] - - @property - def remove_fulfillment_places(self) -> Callable[ - [product_service.RemoveFulfillmentPlacesRequest], - Awaitable[operations_pb2.Operation]]: - r"""Return a callable for the remove fulfillment places method over gRPC. - - Incrementally removes place IDs from a - [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. - - This process is asynchronous and does not require the - [Product][google.cloud.retail.v2.Product] to exist before - updating fulfillment information. If the request is valid, the - update will be enqueued and processed downstream. As a - consequence, when a response is returned, the removed place IDs - 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]. - - 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[[~.RemoveFulfillmentPlacesRequest], - 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_fulfillment_places' not in self._stubs: - self._stubs['remove_fulfillment_places'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.ProductService/RemoveFulfillmentPlaces', - request_serializer=product_service.RemoveFulfillmentPlacesRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs['remove_fulfillment_places'] - - def close(self): - return self.grpc_channel.close() - - -__all__ = ( - 'ProductServiceGrpcAsyncIOTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/__init__.py deleted file mode 100644 index 2fa43cc2..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .client import SearchServiceClient -from .async_client import SearchServiceAsyncClient - -__all__ = ( - 'SearchServiceClient', - 'SearchServiceAsyncClient', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/async_client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/async_client.py deleted file mode 100644 index 3169b7da..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/async_client.py +++ /dev/null @@ -1,286 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -import functools -import re -from typing import Dict, Optional, Sequence, Tuple, Type, Union -import pkg_resources - -from google.api_core.client_options import ClientOptions -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object] # type: ignore - -from google.cloud.retail_v2.services.search_service import pagers -from google.cloud.retail_v2.types import search_service -from .transports.base import SearchServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc_asyncio import SearchServiceGrpcAsyncIOTransport -from .client import SearchServiceClient - - -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. - """ - - _client: SearchServiceClient - - DEFAULT_ENDPOINT = SearchServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = SearchServiceClient.DEFAULT_MTLS_ENDPOINT - - branch_path = staticmethod(SearchServiceClient.branch_path) - parse_branch_path = staticmethod(SearchServiceClient.parse_branch_path) - product_path = staticmethod(SearchServiceClient.product_path) - parse_product_path = staticmethod(SearchServiceClient.parse_product_path) - common_billing_account_path = staticmethod(SearchServiceClient.common_billing_account_path) - parse_common_billing_account_path = staticmethod(SearchServiceClient.parse_common_billing_account_path) - common_folder_path = staticmethod(SearchServiceClient.common_folder_path) - parse_common_folder_path = staticmethod(SearchServiceClient.parse_common_folder_path) - common_organization_path = staticmethod(SearchServiceClient.common_organization_path) - parse_common_organization_path = staticmethod(SearchServiceClient.parse_common_organization_path) - common_project_path = staticmethod(SearchServiceClient.common_project_path) - parse_common_project_path = staticmethod(SearchServiceClient.parse_common_project_path) - common_location_path = staticmethod(SearchServiceClient.common_location_path) - parse_common_location_path = staticmethod(SearchServiceClient.parse_common_location_path) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - SearchServiceAsyncClient: The constructed client. - """ - return SearchServiceClient.from_service_account_info.__func__(SearchServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - SearchServiceAsyncClient: The constructed client. - """ - return SearchServiceClient.from_service_account_file.__func__(SearchServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[ClientOptions] = None): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variabel is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return SearchServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> SearchServiceTransport: - """Returns the transport used by the client instance. - - Returns: - SearchServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - get_transport_class = functools.partial(type(SearchServiceClient).get_transport_class, type(SearchServiceClient)) - - def __init__(self, *, - credentials: ga_credentials.Credentials = None, - transport: Union[str, SearchServiceTransport] = "grpc_asyncio", - client_options: ClientOptions = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the search service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Union[str, ~.SearchServiceTransport]): The - transport to use. If set to None, a transport is chosen - automatically. - client_options (ClientOptions): Custom options for the client. It - won't take effect if a ``transport`` instance is provided. - (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT - environment variable can also be used to override the endpoint: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = SearchServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - - ) - - async def search(self, - request: Union[search_service.SearchRequest, dict] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - 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. - - Args: - request (Union[google.cloud.retail_v2.types.SearchRequest, dict]): - The request object. Request message for - [SearchService.Search][google.cloud.retail.v2.SearchService.Search] - method. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.services.search_service.pagers.SearchAsyncPager: - Response message for - [SearchService.Search][google.cloud.retail.v2.SearchService.Search] - method. - - Iterating over this object will yield results and - resolve additional pages automatically. - - """ - # Create or coerce a protobuf request object. - request = search_service.SearchRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.search, - 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(( - ("placement", request.placement), - )), - ) - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__aiter__` convenience method. - response = pagers.SearchAsyncPager( - method=rpc, - request=request, - response=response, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self): - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - -try: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution( - "google-cloud-retail", - ).version, - ) -except pkg_resources.DistributionNotFound: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() - - -__all__ = ( - "SearchServiceAsyncClient", -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/client.py deleted file mode 100644 index 838fba23..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/client.py +++ /dev/null @@ -1,492 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -import os -import re -from typing import Dict, Optional, Sequence, Tuple, Type, Union -import pkg_resources - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object] # type: ignore - -from google.cloud.retail_v2.services.search_service import pagers -from google.cloud.retail_v2.types import search_service -from .transports.base import SearchServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import SearchServiceGrpcTransport -from .transports.grpc_asyncio import SearchServiceGrpcAsyncIOTransport - - -class SearchServiceClientMeta(type): - """Metaclass for the SearchService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - _transport_registry = OrderedDict() # type: Dict[str, Type[SearchServiceTransport]] - _transport_registry["grpc"] = SearchServiceGrpcTransport - _transport_registry["grpc_asyncio"] = SearchServiceGrpcAsyncIOTransport - - def get_transport_class(cls, - label: str = None, - ) -> Type[SearchServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class 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. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - DEFAULT_ENDPOINT = "retail.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - SearchServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info(info) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - SearchServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> SearchServiceTransport: - """Returns the transport used by the client instance. - - Returns: - SearchServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - 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, ) - - @staticmethod - def parse_branch_path(path: str) -> Dict[str,str]: - """Parses a branch path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def product_path(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(project=project, location=location, catalog=catalog, branch=branch, product=product, ) - - @staticmethod - def parse_product_path(path: str) -> Dict[str,str]: - """Parses a product path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)/products/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path(billing_account: str, ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str,str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path(folder: str, ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format(folder=folder, ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str,str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path(organization: str, ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format(organization=organization, ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str,str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path(project: str, ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format(project=project, ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str,str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path(project: str, location: str, ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format(project=project, location=location, ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str,str]: - """Parse a location path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variabel is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError("Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`") - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError("Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`") - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - def __init__(self, *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Union[str, SearchServiceTransport, None] = None, - client_options: Optional[client_options_lib.ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the search service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Union[str, SearchServiceTransport]): The - transport to use. If set to None, a transport is chosen - automatically. - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. It won't take effect if a ``transport`` instance is provided. - (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT - environment variable can also be used to override the endpoint: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - if isinstance(client_options, dict): - client_options = client_options_lib.from_dict(client_options) - if client_options is None: - client_options = client_options_lib.ClientOptions() - - api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options) - - api_key_value = getattr(client_options, "api_key", None) - if api_key_value and credentials: - raise ValueError("client_options.api_key and credentials are mutually exclusive") - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - if isinstance(transport, SearchServiceTransport): - # transport is a SearchServiceTransport instance. - if credentials or client_options.credentials_file or api_key_value: - raise ValueError("When providing a transport instance, " - "provide its credentials directly.") - if client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = transport - else: - import google.auth._default # type: ignore - - if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"): - credentials = google.auth._default.get_api_key_credentials(api_key_value) - - Transport = type(self).get_transport_class(transport) - self._transport = Transport( - credentials=credentials, - credentials_file=client_options.credentials_file, - host=api_endpoint, - scopes=client_options.scopes, - client_cert_source_for_mtls=client_cert_source_func, - quota_project_id=client_options.quota_project_id, - client_info=client_info, - always_use_jwt_access=True, - ) - - def search(self, - request: Union[search_service.SearchRequest, dict] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - 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. - - Args: - request (Union[google.cloud.retail_v2.types.SearchRequest, dict]): - The request object. Request message for - [SearchService.Search][google.cloud.retail.v2.SearchService.Search] - method. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.services.search_service.pagers.SearchPager: - Response message for - [SearchService.Search][google.cloud.retail.v2.SearchService.Search] - method. - - Iterating over this object will yield results and - resolve additional pages automatically. - - """ - # Create or coerce a protobuf request object. - # Minor optimization to avoid making a copy if the user passes - # in a search_service.SearchRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, search_service.SearchRequest): - request = search_service.SearchRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.search] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("placement", request.placement), - )), - ) - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__iter__` convenience method. - response = pagers.SearchPager( - method=rpc, - request=request, - response=response, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self): - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - - -try: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution( - "google-cloud-retail", - ).version, - ) -except pkg_resources.DistributionNotFound: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() - - -__all__ = ( - "SearchServiceClient", -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/pagers.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/pagers.py deleted file mode 100644 index bd901167..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/pagers.py +++ /dev/null @@ -1,139 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from typing import Any, AsyncIterator, Awaitable, Callable, Sequence, Tuple, Optional, Iterator - -from google.cloud.retail_v2.types import search_service - - -class SearchPager: - """A pager for iterating through ``search`` requests. - - This class thinly wraps an initial - :class:`google.cloud.retail_v2.types.SearchResponse` object, and - provides an ``__iter__`` method to iterate through its - ``results`` field. - - If there are more pages, the ``__iter__`` method will make additional - ``Search`` requests and continue to iterate - through the ``results`` field on the - corresponding responses. - - All the usual :class:`google.cloud.retail_v2.types.SearchResponse` - attributes are available on the pager. If multiple requests are made, only - the most recent response is retained, and thus used for attribute lookup. - """ - def __init__(self, - method: Callable[..., search_service.SearchResponse], - request: search_service.SearchRequest, - response: search_service.SearchResponse, - *, - metadata: Sequence[Tuple[str, str]] = ()): - """Instantiate the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.cloud.retail_v2.types.SearchRequest): - The initial request object. - response (google.cloud.retail_v2.types.SearchResponse): - The initial response object. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - self._method = method - self._request = search_service.SearchRequest(request) - self._response = response - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - def pages(self) -> Iterator[search_service.SearchResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = self._method(self._request, metadata=self._metadata) - yield self._response - - def __iter__(self) -> Iterator[search_service.SearchResponse.SearchResult]: - for page in self.pages: - yield from page.results - - def __repr__(self) -> str: - return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) - - -class SearchAsyncPager: - """A pager for iterating through ``search`` requests. - - This class thinly wraps an initial - :class:`google.cloud.retail_v2.types.SearchResponse` object, and - provides an ``__aiter__`` method to iterate through its - ``results`` field. - - If there are more pages, the ``__aiter__`` method will make additional - ``Search`` requests and continue to iterate - through the ``results`` field on the - corresponding responses. - - All the usual :class:`google.cloud.retail_v2.types.SearchResponse` - attributes are available on the pager. If multiple requests are made, only - the most recent response is retained, and thus used for attribute lookup. - """ - def __init__(self, - method: Callable[..., Awaitable[search_service.SearchResponse]], - request: search_service.SearchRequest, - response: search_service.SearchResponse, - *, - metadata: Sequence[Tuple[str, str]] = ()): - """Instantiates the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.cloud.retail_v2.types.SearchRequest): - The initial request object. - response (google.cloud.retail_v2.types.SearchResponse): - The initial response object. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - self._method = method - self._request = search_service.SearchRequest(request) - self._response = response - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - async def pages(self) -> AsyncIterator[search_service.SearchResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = await self._method(self._request, metadata=self._metadata) - yield self._response - def __aiter__(self) -> AsyncIterator[search_service.SearchResponse.SearchResult]: - async def async_generator(): - async for page in self.pages: - for response in page.results: - yield response - - return async_generator() - - def __repr__(self) -> str: - return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/__init__.py deleted file mode 100644 index d7acf5fa..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from typing import Dict, Type - -from .base import SearchServiceTransport -from .grpc import SearchServiceGrpcTransport -from .grpc_asyncio import SearchServiceGrpcAsyncIOTransport - - -# Compile a registry of transports. -_transport_registry = OrderedDict() # type: Dict[str, Type[SearchServiceTransport]] -_transport_registry['grpc'] = SearchServiceGrpcTransport -_transport_registry['grpc_asyncio'] = SearchServiceGrpcAsyncIOTransport - -__all__ = ( - 'SearchServiceTransport', - 'SearchServiceGrpcTransport', - 'SearchServiceGrpcAsyncIOTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/base.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/base.py deleted file mode 100644 index 03235dd3..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/base.py +++ /dev/null @@ -1,145 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Dict, Optional, Sequence, Union -import pkg_resources - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore - -from google.cloud.retail_v2.types import search_service - -try: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution( - 'google-cloud-retail', - ).version, - ) -except pkg_resources.DistributionNotFound: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() - - -class SearchServiceTransport(abc.ABC): - """Abstract transport class for SearchService.""" - - AUTH_SCOPES = ( - 'https://www.googleapis.com/auth/cloud-platform', - ) - - DEFAULT_HOST: str = 'retail.googleapis.com' - def __init__( - self, *, - host: str = DEFAULT_HOST, - credentials: ga_credentials.Credentials = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to. - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ':' not in host: - host += ':443' - self._host = host - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs("'credentials_file' and 'credentials' are mutually exclusive") - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id - ) - elif credentials is None: - credentials, _ = google.auth.default(**scopes_kwargs, quota_project_id=quota_project_id) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if always_use_jwt_access and isinstance(credentials, service_account.Credentials) and hasattr(service_account.Credentials, "with_always_use_jwt_access"): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - 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, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def search(self) -> Callable[ - [search_service.SearchRequest], - Union[ - search_service.SearchResponse, - Awaitable[search_service.SearchResponse] - ]]: - raise NotImplementedError() - - -__all__ = ( - 'SearchServiceTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc.py deleted file mode 100644 index 5b082d93..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc.py +++ /dev/null @@ -1,264 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -import google.auth # type: ignore -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore - -import grpc # type: ignore - -from google.cloud.retail_v2.types import search_service -from .base import SearchServiceTransport, DEFAULT_CLIENT_INFO - - -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. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - _stubs: Dict[str, Callable] - - def __init__(self, *, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: str = None, - scopes: Sequence[str] = None, - channel: grpc.Channel = None, - api_mtls_endpoint: str = None, - client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, - client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to. - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if ``channel`` is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if ``channel`` is provided. - channel (Optional[grpc.Channel]): A ``Channel`` instance through - which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if ``channel`` is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if ``channel`` or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn("client_cert_source is deprecated", DeprecationWarning) - - if channel: - # Ignore credentials if a channel was passed. - credentials = False - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - else: - self._ssl_channel_credentials = SslCredentials().ssl_credentials - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - ) - - if not self._grpc_channel: - self._grpc_channel = type(self).create_channel( - self._host, - credentials=self._credentials, - credentials_file=credentials_file, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Wrap messages. This must be done after self._grpc_channel exists - self._prep_wrapped_messages(client_info) - - @classmethod - def create_channel(cls, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: str = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service. - """ - return self._grpc_channel - - @property - def search(self) -> Callable[ - [search_service.SearchRequest], - search_service.SearchResponse]: - 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. - - Returns: - Callable[[~.SearchRequest], - ~.SearchResponse]: - 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 'search' not in self._stubs: - self._stubs['search'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.SearchService/Search', - request_serializer=search_service.SearchRequest.serialize, - response_deserializer=search_service.SearchResponse.deserialize, - ) - return self._stubs['search'] - - def close(self): - self.grpc_channel.close() - -__all__ = ( - 'SearchServiceGrpcTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc_asyncio.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc_asyncio.py deleted file mode 100644 index ee3c956c..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,268 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore - -import grpc # type: ignore -from grpc.experimental import aio # type: ignore - -from google.cloud.retail_v2.types import search_service -from .base import SearchServiceTransport, DEFAULT_CLIENT_INFO -from .grpc import SearchServiceGrpcTransport - - -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. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel(cls, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs - ) - - def __init__(self, *, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: aio.Channel = None, - api_mtls_endpoint: str = None, - client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, - client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, - quota_project_id=None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to. - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if ``channel`` is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[aio.Channel]): A ``Channel`` instance through - which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if ``channel`` is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if ``channel`` or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn("client_cert_source is deprecated", DeprecationWarning) - - if channel: - # Ignore credentials if a channel was passed. - credentials = False - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - else: - self._ssl_channel_credentials = SslCredentials().ssl_credentials - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - ) - - if not self._grpc_channel: - self._grpc_channel = type(self).create_channel( - self._host, - credentials=self._credentials, - credentials_file=credentials_file, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Wrap messages. This must be done after self._grpc_channel exists - self._prep_wrapped_messages(client_info) - - @property - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def search(self) -> Callable[ - [search_service.SearchRequest], - Awaitable[search_service.SearchResponse]]: - 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. - - Returns: - Callable[[~.SearchRequest], - Awaitable[~.SearchResponse]]: - 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 'search' not in self._stubs: - self._stubs['search'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.SearchService/Search', - request_serializer=search_service.SearchRequest.serialize, - response_deserializer=search_service.SearchResponse.deserialize, - ) - return self._stubs['search'] - - def close(self): - return self.grpc_channel.close() - - -__all__ = ( - 'SearchServiceGrpcAsyncIOTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/__init__.py deleted file mode 100644 index 808f8208..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .client import UserEventServiceClient -from .async_client import UserEventServiceAsyncClient - -__all__ = ( - 'UserEventServiceClient', - 'UserEventServiceAsyncClient', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/async_client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/async_client.py deleted file mode 100644 index bff9a954..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/async_client.py +++ /dev/null @@ -1,610 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -import functools -import re -from typing import Dict, Optional, Sequence, Tuple, Type, Union -import pkg_resources - -from google.api_core.client_options import ClientOptions -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object] # type: ignore - -from google.api import httpbody_pb2 # type: ignore -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore -from google.cloud.retail_v2.types import common -from google.cloud.retail_v2.types import import_config -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 -from google.protobuf import any_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore -from .transports.base import UserEventServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc_asyncio import UserEventServiceGrpcAsyncIOTransport -from .client import UserEventServiceClient - - -class UserEventServiceAsyncClient: - """Service for ingesting end user actions on the customer - website. - """ - - _client: UserEventServiceClient - - DEFAULT_ENDPOINT = UserEventServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = UserEventServiceClient.DEFAULT_MTLS_ENDPOINT - - catalog_path = staticmethod(UserEventServiceClient.catalog_path) - parse_catalog_path = staticmethod(UserEventServiceClient.parse_catalog_path) - product_path = staticmethod(UserEventServiceClient.product_path) - parse_product_path = staticmethod(UserEventServiceClient.parse_product_path) - common_billing_account_path = staticmethod(UserEventServiceClient.common_billing_account_path) - parse_common_billing_account_path = staticmethod(UserEventServiceClient.parse_common_billing_account_path) - common_folder_path = staticmethod(UserEventServiceClient.common_folder_path) - parse_common_folder_path = staticmethod(UserEventServiceClient.parse_common_folder_path) - common_organization_path = staticmethod(UserEventServiceClient.common_organization_path) - parse_common_organization_path = staticmethod(UserEventServiceClient.parse_common_organization_path) - common_project_path = staticmethod(UserEventServiceClient.common_project_path) - parse_common_project_path = staticmethod(UserEventServiceClient.parse_common_project_path) - common_location_path = staticmethod(UserEventServiceClient.common_location_path) - parse_common_location_path = staticmethod(UserEventServiceClient.parse_common_location_path) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - UserEventServiceAsyncClient: The constructed client. - """ - return UserEventServiceClient.from_service_account_info.__func__(UserEventServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - UserEventServiceAsyncClient: The constructed client. - """ - return UserEventServiceClient.from_service_account_file.__func__(UserEventServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[ClientOptions] = None): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variabel is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return UserEventServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> UserEventServiceTransport: - """Returns the transport used by the client instance. - - Returns: - UserEventServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - get_transport_class = functools.partial(type(UserEventServiceClient).get_transport_class, type(UserEventServiceClient)) - - def __init__(self, *, - credentials: ga_credentials.Credentials = None, - transport: Union[str, UserEventServiceTransport] = "grpc_asyncio", - client_options: ClientOptions = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the user event service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Union[str, ~.UserEventServiceTransport]): The - transport to use. If set to None, a transport is chosen - automatically. - client_options (ClientOptions): Custom options for the client. It - won't take effect if a ``transport`` instance is provided. - (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT - environment variable can also be used to override the endpoint: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = UserEventServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - - ) - - async def write_user_event(self, - request: Union[user_event_service.WriteUserEventRequest, dict] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> user_event.UserEvent: - r"""Writes a single user event. - - Args: - request (Union[google.cloud.retail_v2.types.WriteUserEventRequest, dict]): - The request object. Request message for WriteUserEvent - method. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.types.UserEvent: - UserEvent captures all metadata - information Retail API needs to know - about how end users interact with - customers' website. - - """ - # Create or coerce a protobuf request object. - request = user_event_service.WriteUserEventRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.write_user_event, - default_timeout=None, - client_info=DEFAULT_CLIENT_INFO, - ) - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("parent", request.parent), - )), - ) - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def collect_user_event(self, - request: Union[user_event_service.CollectUserEventRequest, dict] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> httpbody_pb2.HttpBody: - r"""Writes a single user event from the browser. This - uses a GET request to due to browser restriction of - POST-ing to a 3rd party domain. - This method is used only by the Retail API JavaScript - pixel and Google Tag Manager. Users should not call this - method directly. - - Args: - request (Union[google.cloud.retail_v2.types.CollectUserEventRequest, dict]): - The request object. Request message for CollectUserEvent - method. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.api.httpbody_pb2.HttpBody: - Message that represents an arbitrary HTTP body. It should only be used for - payload formats that can't be represented as JSON, - such as raw binary or an HTML page. - - This message can be used both in streaming and - non-streaming API methods in the request as well as - the response. - - It can be used as a top-level request field, which is - convenient if one wants to extract parameters from - either the URL or HTTP template into the request - fields and also want access to the raw HTTP body. - - Example: - - message GetResourceRequest { - // A unique request id. string request_id = 1; - - // The raw HTTP body is bound to this field. - google.api.HttpBody http_body = 2; - - } - - service ResourceService { - rpc GetResource(GetResourceRequest) - returns (google.api.HttpBody); - - rpc UpdateResource(google.api.HttpBody) - returns (google.protobuf.Empty); - - } - - Example with streaming methods: - - service CaldavService { - rpc GetCalendar(stream google.api.HttpBody) - returns (stream google.api.HttpBody); - - rpc UpdateCalendar(stream google.api.HttpBody) - returns (stream google.api.HttpBody); - - } - - Use of this type only changes how the request and - response bodies are handled, all other features will - continue to work unchanged. - - """ - # Create or coerce a protobuf request object. - request = user_event_service.CollectUserEventRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.collect_user_event, - default_timeout=None, - client_info=DEFAULT_CLIENT_INFO, - ) - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("parent", request.parent), - )), - ) - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def purge_user_events(self, - request: Union[purge_config.PurgeUserEventsRequest, dict] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation_async.AsyncOperation: - r"""Deletes permanently all user events specified by the - filter provided. Depending on the number of events - specified by the filter, this operation could take hours - or days to complete. To test a filter, use the list - command first. - - Args: - request (Union[google.cloud.retail_v2.types.PurgeUserEventsRequest, dict]): - The request object. Request message for PurgeUserEvents - method. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.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.PurgeUserEventsResponse` Response of the PurgeUserEventsRequest. If the long running operation is - successfully done, then this message is returned by - the google.longrunning.Operations.response field. - - """ - # Create or coerce a protobuf request object. - request = purge_config.PurgeUserEventsRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.purge_user_events, - default_retry=retries.Retry( -initial=0.1,maximum=30.0,multiplier=1.3, predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=30.0, - ), - default_timeout=30.0, - client_info=DEFAULT_CLIENT_INFO, - ) - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("parent", request.parent), - )), - ) - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation_async.from_gapic( - response, - self._client._transport.operations_client, - purge_config.PurgeUserEventsResponse, - metadata_type=purge_config.PurgeMetadata, - ) - - # Done; return the response. - return response - - async def import_user_events(self, - request: Union[import_config.ImportUserEventsRequest, dict] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation_async.AsyncOperation: - r"""Bulk import of User events. Request processing might - be synchronous. Events that already exist are skipped. - Use this method for backfilling historical user events. - Operation.response is of type ImportResponse. Note that - it is possible for a subset of the items to be - successfully inserted. Operation.metadata is of type - ImportMetadata. - - Args: - request (Union[google.cloud.retail_v2.types.ImportUserEventsRequest, dict]): - The request object. Request message for the - ImportUserEvents request. - 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.ImportUserEventsResponse` Response of the ImportUserEventsRequest. If the long running - operation was successful, then this message is - returned by the - google.longrunning.Operations.response field if the - operation was successful. - - """ - # Create or coerce a protobuf request object. - request = import_config.ImportUserEventsRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.import_user_events, - default_retry=retries.Retry( -initial=0.1,maximum=300.0,multiplier=1.3, predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=600.0, - ), - default_timeout=600.0, - client_info=DEFAULT_CLIENT_INFO, - ) - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("parent", request.parent), - )), - ) - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation_async.from_gapic( - response, - self._client._transport.operations_client, - import_config.ImportUserEventsResponse, - metadata_type=import_config.ImportMetadata, - ) - - # Done; return the response. - return response - - async def rejoin_user_events(self, - request: Union[user_event_service.RejoinUserEventsRequest, dict] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation_async.AsyncOperation: - r"""Triggers 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 - with latest version of product catalog. It can also be - used to correct events joined with wrong product - catalog. - - Args: - request (Union[google.cloud.retail_v2.types.RejoinUserEventsRequest, dict]): - The request object. Request message for RejoinUserEvents - method. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.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.RejoinUserEventsResponse` - Response message for RejoinUserEvents method. - - """ - # Create or coerce a protobuf request object. - request = user_event_service.RejoinUserEventsRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.rejoin_user_events, - default_timeout=None, - client_info=DEFAULT_CLIENT_INFO, - ) - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("parent", request.parent), - )), - ) - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation_async.from_gapic( - response, - self._client._transport.operations_client, - user_event_service.RejoinUserEventsResponse, - metadata_type=user_event_service.RejoinUserEventsMetadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self): - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - -try: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution( - "google-cloud-retail", - ).version, - ) -except pkg_resources.DistributionNotFound: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() - - -__all__ = ( - "UserEventServiceAsyncClient", -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/client.py deleted file mode 100644 index efa6d0b3..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/client.py +++ /dev/null @@ -1,806 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -import os -import re -from typing import Dict, Optional, Sequence, Tuple, Type, Union -import pkg_resources - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object] # type: ignore - -from google.api import httpbody_pb2 # type: ignore -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore -from google.cloud.retail_v2.types import common -from google.cloud.retail_v2.types import import_config -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 -from google.protobuf import any_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore -from .transports.base import UserEventServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import UserEventServiceGrpcTransport -from .transports.grpc_asyncio import UserEventServiceGrpcAsyncIOTransport - - -class UserEventServiceClientMeta(type): - """Metaclass for the UserEventService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - _transport_registry = OrderedDict() # type: Dict[str, Type[UserEventServiceTransport]] - _transport_registry["grpc"] = UserEventServiceGrpcTransport - _transport_registry["grpc_asyncio"] = UserEventServiceGrpcAsyncIOTransport - - def get_transport_class(cls, - label: str = None, - ) -> Type[UserEventServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class UserEventServiceClient(metaclass=UserEventServiceClientMeta): - """Service for ingesting end user actions on the customer - website. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - DEFAULT_ENDPOINT = "retail.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - UserEventServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info(info) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - UserEventServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> UserEventServiceTransport: - """Returns the transport used by the client instance. - - Returns: - UserEventServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def catalog_path(project: str,location: str,catalog: str,) -> str: - """Returns a fully-qualified catalog string.""" - return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) - - @staticmethod - def parse_catalog_path(path: str) -> Dict[str,str]: - """Parses a catalog path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def product_path(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(project=project, location=location, catalog=catalog, branch=branch, product=product, ) - - @staticmethod - def parse_product_path(path: str) -> Dict[str,str]: - """Parses a product path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)/products/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path(billing_account: str, ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str,str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path(folder: str, ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format(folder=folder, ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str,str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path(organization: str, ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format(organization=organization, ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str,str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path(project: str, ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format(project=project, ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str,str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path(project: str, location: str, ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format(project=project, location=location, ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str,str]: - """Parse a location path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variabel is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError("Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`") - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError("Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`") - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - def __init__(self, *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Union[str, UserEventServiceTransport, None] = None, - client_options: Optional[client_options_lib.ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the user event service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Union[str, UserEventServiceTransport]): The - transport to use. If set to None, a transport is chosen - automatically. - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. It won't take effect if a ``transport`` instance is provided. - (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT - environment variable can also be used to override the endpoint: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - if isinstance(client_options, dict): - client_options = client_options_lib.from_dict(client_options) - if client_options is None: - client_options = client_options_lib.ClientOptions() - - api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options) - - api_key_value = getattr(client_options, "api_key", None) - if api_key_value and credentials: - raise ValueError("client_options.api_key and credentials are mutually exclusive") - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - if isinstance(transport, UserEventServiceTransport): - # transport is a UserEventServiceTransport instance. - if credentials or client_options.credentials_file or api_key_value: - raise ValueError("When providing a transport instance, " - "provide its credentials directly.") - if client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = transport - else: - import google.auth._default # type: ignore - - if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"): - credentials = google.auth._default.get_api_key_credentials(api_key_value) - - Transport = type(self).get_transport_class(transport) - self._transport = Transport( - credentials=credentials, - credentials_file=client_options.credentials_file, - host=api_endpoint, - scopes=client_options.scopes, - client_cert_source_for_mtls=client_cert_source_func, - quota_project_id=client_options.quota_project_id, - client_info=client_info, - always_use_jwt_access=True, - ) - - def write_user_event(self, - request: Union[user_event_service.WriteUserEventRequest, dict] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> user_event.UserEvent: - r"""Writes a single user event. - - Args: - request (Union[google.cloud.retail_v2.types.WriteUserEventRequest, dict]): - The request object. Request message for WriteUserEvent - method. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.cloud.retail_v2.types.UserEvent: - UserEvent captures all metadata - information Retail API needs to know - about how end users interact with - customers' website. - - """ - # Create or coerce a protobuf request object. - # Minor optimization to avoid making a copy if the user passes - # in a user_event_service.WriteUserEventRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, user_event_service.WriteUserEventRequest): - request = user_event_service.WriteUserEventRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.write_user_event] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("parent", request.parent), - )), - ) - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def collect_user_event(self, - request: Union[user_event_service.CollectUserEventRequest, dict] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> httpbody_pb2.HttpBody: - r"""Writes a single user event from the browser. This - uses a GET request to due to browser restriction of - POST-ing to a 3rd party domain. - This method is used only by the Retail API JavaScript - pixel and Google Tag Manager. Users should not call this - method directly. - - Args: - request (Union[google.cloud.retail_v2.types.CollectUserEventRequest, dict]): - The request object. Request message for CollectUserEvent - method. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.api.httpbody_pb2.HttpBody: - Message that represents an arbitrary HTTP body. It should only be used for - payload formats that can't be represented as JSON, - such as raw binary or an HTML page. - - This message can be used both in streaming and - non-streaming API methods in the request as well as - the response. - - It can be used as a top-level request field, which is - convenient if one wants to extract parameters from - either the URL or HTTP template into the request - fields and also want access to the raw HTTP body. - - Example: - - message GetResourceRequest { - // A unique request id. string request_id = 1; - - // The raw HTTP body is bound to this field. - google.api.HttpBody http_body = 2; - - } - - service ResourceService { - rpc GetResource(GetResourceRequest) - returns (google.api.HttpBody); - - rpc UpdateResource(google.api.HttpBody) - returns (google.protobuf.Empty); - - } - - Example with streaming methods: - - service CaldavService { - rpc GetCalendar(stream google.api.HttpBody) - returns (stream google.api.HttpBody); - - rpc UpdateCalendar(stream google.api.HttpBody) - returns (stream google.api.HttpBody); - - } - - Use of this type only changes how the request and - response bodies are handled, all other features will - continue to work unchanged. - - """ - # Create or coerce a protobuf request object. - # Minor optimization to avoid making a copy if the user passes - # in a user_event_service.CollectUserEventRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, user_event_service.CollectUserEventRequest): - request = user_event_service.CollectUserEventRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.collect_user_event] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("parent", request.parent), - )), - ) - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def purge_user_events(self, - request: Union[purge_config.PurgeUserEventsRequest, dict] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation.Operation: - r"""Deletes permanently all user events specified by the - filter provided. Depending on the number of events - specified by the filter, this operation could take hours - or days to complete. To test a filter, use the list - command first. - - Args: - request (Union[google.cloud.retail_v2.types.PurgeUserEventsRequest, dict]): - The request object. Request message for PurgeUserEvents - method. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.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.PurgeUserEventsResponse` Response of the PurgeUserEventsRequest. If the long running operation is - successfully done, then this message is returned by - the google.longrunning.Operations.response field. - - """ - # Create or coerce a protobuf request object. - # Minor optimization to avoid making a copy if the user passes - # in a purge_config.PurgeUserEventsRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, purge_config.PurgeUserEventsRequest): - request = purge_config.PurgeUserEventsRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.purge_user_events] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("parent", request.parent), - )), - ) - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation.from_gapic( - response, - self._transport.operations_client, - purge_config.PurgeUserEventsResponse, - metadata_type=purge_config.PurgeMetadata, - ) - - # Done; return the response. - return response - - def import_user_events(self, - request: Union[import_config.ImportUserEventsRequest, dict] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation.Operation: - r"""Bulk import of User events. Request processing might - be synchronous. Events that already exist are skipped. - Use this method for backfilling historical user events. - Operation.response is of type ImportResponse. Note that - it is possible for a subset of the items to be - successfully inserted. Operation.metadata is of type - ImportMetadata. - - Args: - request (Union[google.cloud.retail_v2.types.ImportUserEventsRequest, dict]): - The request object. Request message for the - ImportUserEvents request. - 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.ImportUserEventsResponse` Response of the ImportUserEventsRequest. If the long running - operation was successful, then this message is - returned by the - google.longrunning.Operations.response field if the - operation was successful. - - """ - # Create or coerce a protobuf request object. - # Minor optimization to avoid making a copy if the user passes - # in a import_config.ImportUserEventsRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, import_config.ImportUserEventsRequest): - request = import_config.ImportUserEventsRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.import_user_events] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("parent", request.parent), - )), - ) - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation.from_gapic( - response, - self._transport.operations_client, - import_config.ImportUserEventsResponse, - metadata_type=import_config.ImportMetadata, - ) - - # Done; return the response. - return response - - def rejoin_user_events(self, - request: Union[user_event_service.RejoinUserEventsRequest, dict] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation.Operation: - r"""Triggers 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 - with latest version of product catalog. It can also be - used to correct events joined with wrong product - catalog. - - Args: - request (Union[google.cloud.retail_v2.types.RejoinUserEventsRequest, dict]): - The request object. Request message for RejoinUserEvents - method. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.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.RejoinUserEventsResponse` - Response message for RejoinUserEvents method. - - """ - # Create or coerce a protobuf request object. - # Minor optimization to avoid making a copy if the user passes - # in a user_event_service.RejoinUserEventsRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, user_event_service.RejoinUserEventsRequest): - request = user_event_service.RejoinUserEventsRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.rejoin_user_events] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ("parent", request.parent), - )), - ) - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation.from_gapic( - response, - self._transport.operations_client, - user_event_service.RejoinUserEventsResponse, - metadata_type=user_event_service.RejoinUserEventsMetadata, - ) - - # Done; return the response. - return response - - def __enter__(self): - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - - -try: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution( - "google-cloud-retail", - ).version, - ) -except pkg_resources.DistributionNotFound: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() - - -__all__ = ( - "UserEventServiceClient", -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/__init__.py deleted file mode 100644 index 7cff2187..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from typing import Dict, Type - -from .base import UserEventServiceTransport -from .grpc import UserEventServiceGrpcTransport -from .grpc_asyncio import UserEventServiceGrpcAsyncIOTransport - - -# Compile a registry of transports. -_transport_registry = OrderedDict() # type: Dict[str, Type[UserEventServiceTransport]] -_transport_registry['grpc'] = UserEventServiceGrpcTransport -_transport_registry['grpc_asyncio'] = UserEventServiceGrpcAsyncIOTransport - -__all__ = ( - 'UserEventServiceTransport', - 'UserEventServiceGrpcTransport', - 'UserEventServiceGrpcAsyncIOTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/base.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/base.py deleted file mode 100644 index 0a28e430..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/base.py +++ /dev/null @@ -1,226 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Dict, Optional, Sequence, Union -import pkg_resources - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.api_core import operations_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore - -from google.api import httpbody_pb2 # type: ignore -from google.cloud.retail_v2.types import import_config -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 -from google.longrunning import operations_pb2 # type: ignore - -try: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=pkg_resources.get_distribution( - 'google-cloud-retail', - ).version, - ) -except pkg_resources.DistributionNotFound: - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() - - -class UserEventServiceTransport(abc.ABC): - """Abstract transport class for UserEventService.""" - - AUTH_SCOPES = ( - 'https://www.googleapis.com/auth/cloud-platform', - ) - - DEFAULT_HOST: str = 'retail.googleapis.com' - def __init__( - self, *, - host: str = DEFAULT_HOST, - credentials: ga_credentials.Credentials = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to. - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ':' not in host: - host += ':443' - self._host = host - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs("'credentials_file' and 'credentials' are mutually exclusive") - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id - ) - elif credentials is None: - credentials, _ = google.auth.default(**scopes_kwargs, quota_project_id=quota_project_id) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if always_use_jwt_access and isinstance(credentials, service_account.Credentials) and hasattr(service_account.Credentials, "with_always_use_jwt_access"): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - 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.collect_user_event: gapic_v1.method.wrap_method( - self.collect_user_event, - default_timeout=None, - client_info=client_info, - ), - self.purge_user_events: gapic_v1.method.wrap_method( - self.purge_user_events, - default_retry=retries.Retry( -initial=0.1,maximum=30.0,multiplier=1.3, predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=30.0, - ), - default_timeout=30.0, - client_info=client_info, - ), - self.import_user_events: gapic_v1.method.wrap_method( - self.import_user_events, - default_retry=retries.Retry( -initial=0.1,maximum=300.0,multiplier=1.3, predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=600.0, - ), - default_timeout=600.0, - client_info=client_info, - ), - self.rejoin_user_events: gapic_v1.method.wrap_method( - 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! - """ - raise NotImplementedError() - - @property - def operations_client(self): - """Return the client designed to process long-running operations.""" - raise NotImplementedError() - - @property - def write_user_event(self) -> Callable[ - [user_event_service.WriteUserEventRequest], - Union[ - user_event.UserEvent, - Awaitable[user_event.UserEvent] - ]]: - raise NotImplementedError() - - @property - def collect_user_event(self) -> Callable[ - [user_event_service.CollectUserEventRequest], - Union[ - httpbody_pb2.HttpBody, - Awaitable[httpbody_pb2.HttpBody] - ]]: - raise NotImplementedError() - - @property - def purge_user_events(self) -> Callable[ - [purge_config.PurgeUserEventsRequest], - Union[ - operations_pb2.Operation, - Awaitable[operations_pb2.Operation] - ]]: - raise NotImplementedError() - - @property - def import_user_events(self) -> Callable[ - [import_config.ImportUserEventsRequest], - Union[ - operations_pb2.Operation, - Awaitable[operations_pb2.Operation] - ]]: - raise NotImplementedError() - - @property - def rejoin_user_events(self) -> Callable[ - [user_event_service.RejoinUserEventsRequest], - Union[ - operations_pb2.Operation, - Awaitable[operations_pb2.Operation] - ]]: - raise NotImplementedError() - - -__all__ = ( - 'UserEventServiceTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc.py deleted file mode 100644 index efda9abb..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc.py +++ /dev/null @@ -1,406 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import operations_v1 -from google.api_core import gapic_v1 -import google.auth # type: ignore -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore - -import grpc # type: ignore - -from google.api import httpbody_pb2 # type: ignore -from google.cloud.retail_v2.types import import_config -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 -from google.longrunning import operations_pb2 # type: ignore -from .base import UserEventServiceTransport, DEFAULT_CLIENT_INFO - - -class UserEventServiceGrpcTransport(UserEventServiceTransport): - """gRPC backend transport for UserEventService. - - Service for ingesting end user actions on the customer - website. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - _stubs: Dict[str, Callable] - - def __init__(self, *, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: str = None, - scopes: Sequence[str] = None, - channel: grpc.Channel = None, - api_mtls_endpoint: str = None, - client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, - client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to. - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if ``channel`` is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if ``channel`` is provided. - channel (Optional[grpc.Channel]): A ``Channel`` instance through - which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if ``channel`` is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if ``channel`` or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - self._operations_client: Optional[operations_v1.OperationsClient] = None - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn("client_cert_source is deprecated", DeprecationWarning) - - if channel: - # Ignore credentials if a channel was passed. - credentials = False - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - else: - self._ssl_channel_credentials = SslCredentials().ssl_credentials - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - ) - - if not self._grpc_channel: - self._grpc_channel = type(self).create_channel( - self._host, - credentials=self._credentials, - credentials_file=credentials_file, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Wrap messages. This must be done after self._grpc_channel exists - self._prep_wrapped_messages(client_info) - - @classmethod - def create_channel(cls, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: str = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service. - """ - return self._grpc_channel - - @property - def operations_client(self) -> operations_v1.OperationsClient: - """Create the client designed to process long-running operations. - - This property caches on the instance; repeated calls return the same - client. - """ - # Sanity check: Only create a new client if we do not already have one. - if self._operations_client is None: - self._operations_client = operations_v1.OperationsClient( - self.grpc_channel - ) - - # Return the client from cache. - return self._operations_client - - @property - def write_user_event(self) -> Callable[ - [user_event_service.WriteUserEventRequest], - user_event.UserEvent]: - r"""Return a callable for the write user event method over gRPC. - - Writes a single user event. - - Returns: - Callable[[~.WriteUserEventRequest], - ~.UserEvent]: - 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 'write_user_event' not in self._stubs: - self._stubs['write_user_event'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.UserEventService/WriteUserEvent', - request_serializer=user_event_service.WriteUserEventRequest.serialize, - response_deserializer=user_event.UserEvent.deserialize, - ) - return self._stubs['write_user_event'] - - @property - def collect_user_event(self) -> Callable[ - [user_event_service.CollectUserEventRequest], - httpbody_pb2.HttpBody]: - r"""Return a callable for the collect user event method over gRPC. - - Writes a single user event from the browser. This - uses a GET request to due to browser restriction of - POST-ing to a 3rd party domain. - This method is used only by the Retail API JavaScript - pixel and Google Tag Manager. Users should not call this - method directly. - - Returns: - Callable[[~.CollectUserEventRequest], - ~.HttpBody]: - 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 'collect_user_event' not in self._stubs: - self._stubs['collect_user_event'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.UserEventService/CollectUserEvent', - request_serializer=user_event_service.CollectUserEventRequest.serialize, - response_deserializer=httpbody_pb2.HttpBody.FromString, - ) - return self._stubs['collect_user_event'] - - @property - def purge_user_events(self) -> Callable[ - [purge_config.PurgeUserEventsRequest], - operations_pb2.Operation]: - r"""Return a callable for the purge user events method over gRPC. - - Deletes permanently all user events specified by the - filter provided. Depending on the number of events - specified by the filter, this operation could take hours - or days to complete. To test a filter, use the list - command first. - - Returns: - Callable[[~.PurgeUserEventsRequest], - ~.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 'purge_user_events' not in self._stubs: - self._stubs['purge_user_events'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.UserEventService/PurgeUserEvents', - request_serializer=purge_config.PurgeUserEventsRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs['purge_user_events'] - - @property - def import_user_events(self) -> Callable[ - [import_config.ImportUserEventsRequest], - operations_pb2.Operation]: - r"""Return a callable for the import user events method over gRPC. - - Bulk import of User events. Request processing might - be synchronous. Events that already exist are skipped. - Use this method for backfilling historical user events. - Operation.response is of type ImportResponse. Note that - it is possible for a subset of the items to be - successfully inserted. Operation.metadata is of type - ImportMetadata. - - Returns: - Callable[[~.ImportUserEventsRequest], - ~.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 'import_user_events' not in self._stubs: - self._stubs['import_user_events'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.UserEventService/ImportUserEvents', - request_serializer=import_config.ImportUserEventsRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs['import_user_events'] - - @property - def rejoin_user_events(self) -> Callable[ - [user_event_service.RejoinUserEventsRequest], - operations_pb2.Operation]: - r"""Return a callable for the rejoin user events method over gRPC. - - Triggers 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 - with latest version of product catalog. It can also be - used to correct events joined with wrong product - catalog. - - Returns: - Callable[[~.RejoinUserEventsRequest], - ~.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 'rejoin_user_events' not in self._stubs: - self._stubs['rejoin_user_events'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.UserEventService/RejoinUserEvents', - request_serializer=user_event_service.RejoinUserEventsRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs['rejoin_user_events'] - - def close(self): - self.grpc_channel.close() - -__all__ = ( - 'UserEventServiceGrpcTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc_asyncio.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc_asyncio.py deleted file mode 100644 index a0e4c061..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,410 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.api_core import operations_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore - -import grpc # type: ignore -from grpc.experimental import aio # type: ignore - -from google.api import httpbody_pb2 # type: ignore -from google.cloud.retail_v2.types import import_config -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 -from google.longrunning import operations_pb2 # type: ignore -from .base import UserEventServiceTransport, DEFAULT_CLIENT_INFO -from .grpc import UserEventServiceGrpcTransport - - -class UserEventServiceGrpcAsyncIOTransport(UserEventServiceTransport): - """gRPC AsyncIO backend transport for UserEventService. - - Service for ingesting end user actions on the customer - website. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel(cls, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs - ) - - def __init__(self, *, - host: str = 'retail.googleapis.com', - credentials: ga_credentials.Credentials = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: aio.Channel = None, - api_mtls_endpoint: str = None, - client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, - client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, - quota_project_id=None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to. - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if ``channel`` is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[aio.Channel]): A ``Channel`` instance through - which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if ``channel`` is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if ``channel`` or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn("client_cert_source is deprecated", DeprecationWarning) - - if channel: - # Ignore credentials if a channel was passed. - credentials = False - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - else: - self._ssl_channel_credentials = SslCredentials().ssl_credentials - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - ) - - if not self._grpc_channel: - self._grpc_channel = type(self).create_channel( - self._host, - credentials=self._credentials, - credentials_file=credentials_file, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Wrap messages. This must be done after self._grpc_channel exists - self._prep_wrapped_messages(client_info) - - @property - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def operations_client(self) -> operations_v1.OperationsAsyncClient: - """Create the client designed to process long-running operations. - - This property caches on the instance; repeated calls return the same - client. - """ - # Sanity check: Only create a new client if we do not already have one. - if self._operations_client is None: - self._operations_client = operations_v1.OperationsAsyncClient( - self.grpc_channel - ) - - # Return the client from cache. - return self._operations_client - - @property - def write_user_event(self) -> Callable[ - [user_event_service.WriteUserEventRequest], - Awaitable[user_event.UserEvent]]: - r"""Return a callable for the write user event method over gRPC. - - Writes a single user event. - - Returns: - Callable[[~.WriteUserEventRequest], - Awaitable[~.UserEvent]]: - 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 'write_user_event' not in self._stubs: - self._stubs['write_user_event'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.UserEventService/WriteUserEvent', - request_serializer=user_event_service.WriteUserEventRequest.serialize, - response_deserializer=user_event.UserEvent.deserialize, - ) - return self._stubs['write_user_event'] - - @property - def collect_user_event(self) -> Callable[ - [user_event_service.CollectUserEventRequest], - Awaitable[httpbody_pb2.HttpBody]]: - r"""Return a callable for the collect user event method over gRPC. - - Writes a single user event from the browser. This - uses a GET request to due to browser restriction of - POST-ing to a 3rd party domain. - This method is used only by the Retail API JavaScript - pixel and Google Tag Manager. Users should not call this - method directly. - - Returns: - Callable[[~.CollectUserEventRequest], - Awaitable[~.HttpBody]]: - 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 'collect_user_event' not in self._stubs: - self._stubs['collect_user_event'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.UserEventService/CollectUserEvent', - request_serializer=user_event_service.CollectUserEventRequest.serialize, - response_deserializer=httpbody_pb2.HttpBody.FromString, - ) - return self._stubs['collect_user_event'] - - @property - def purge_user_events(self) -> Callable[ - [purge_config.PurgeUserEventsRequest], - Awaitable[operations_pb2.Operation]]: - r"""Return a callable for the purge user events method over gRPC. - - Deletes permanently all user events specified by the - filter provided. Depending on the number of events - specified by the filter, this operation could take hours - or days to complete. To test a filter, use the list - command first. - - Returns: - Callable[[~.PurgeUserEventsRequest], - 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 'purge_user_events' not in self._stubs: - self._stubs['purge_user_events'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.UserEventService/PurgeUserEvents', - request_serializer=purge_config.PurgeUserEventsRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs['purge_user_events'] - - @property - def import_user_events(self) -> Callable[ - [import_config.ImportUserEventsRequest], - Awaitable[operations_pb2.Operation]]: - r"""Return a callable for the import user events method over gRPC. - - Bulk import of User events. Request processing might - be synchronous. Events that already exist are skipped. - Use this method for backfilling historical user events. - Operation.response is of type ImportResponse. Note that - it is possible for a subset of the items to be - successfully inserted. Operation.metadata is of type - ImportMetadata. - - Returns: - Callable[[~.ImportUserEventsRequest], - 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 'import_user_events' not in self._stubs: - self._stubs['import_user_events'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.UserEventService/ImportUserEvents', - request_serializer=import_config.ImportUserEventsRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs['import_user_events'] - - @property - def rejoin_user_events(self) -> Callable[ - [user_event_service.RejoinUserEventsRequest], - Awaitable[operations_pb2.Operation]]: - r"""Return a callable for the rejoin user events method over gRPC. - - Triggers 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 - with latest version of product catalog. It can also be - used to correct events joined with wrong product - catalog. - - Returns: - Callable[[~.RejoinUserEventsRequest], - 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 'rejoin_user_events' not in self._stubs: - self._stubs['rejoin_user_events'] = self.grpc_channel.unary_unary( - '/google.cloud.retail.v2.UserEventService/RejoinUserEvents', - request_serializer=user_event_service.RejoinUserEventsRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs['rejoin_user_events'] - - def close(self): - return self.grpc_channel.close() - - -__all__ = ( - 'UserEventServiceGrpcAsyncIOTransport', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/__init__.py deleted file mode 100644 index 686e8b61..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/types/__init__.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .catalog import ( - Catalog, - ProductLevelConfig, -) -from .catalog_service import ( - GetDefaultBranchRequest, - GetDefaultBranchResponse, - ListCatalogsRequest, - ListCatalogsResponse, - SetDefaultBranchRequest, - UpdateCatalogRequest, -) -from .common import ( - Audience, - ColorInfo, - CustomAttribute, - FulfillmentInfo, - Image, - Interval, - PriceInfo, - Promotion, - Rating, - UserInfo, -) -from .completion_service import ( - CompleteQueryRequest, - CompleteQueryResponse, -) -from .import_config import ( - BigQuerySource, - CompletionDataInputConfig, - GcsSource, - ImportCompletionDataRequest, - ImportCompletionDataResponse, - ImportErrorsConfig, - ImportMetadata, - ImportProductsRequest, - ImportProductsResponse, - ImportUserEventsRequest, - ImportUserEventsResponse, - ProductInlineSource, - ProductInputConfig, - UserEventImportSummary, - UserEventInlineSource, - UserEventInputConfig, -) -from .prediction_service import ( - PredictRequest, - PredictResponse, -) -from .product import ( - Product, -) -from .product_service import ( - AddFulfillmentPlacesMetadata, - AddFulfillmentPlacesRequest, - AddFulfillmentPlacesResponse, - CreateProductRequest, - DeleteProductRequest, - GetProductRequest, - ListProductsRequest, - ListProductsResponse, - RemoveFulfillmentPlacesMetadata, - RemoveFulfillmentPlacesRequest, - RemoveFulfillmentPlacesResponse, - SetInventoryMetadata, - SetInventoryRequest, - SetInventoryResponse, - UpdateProductRequest, -) -from .purge_config import ( - PurgeMetadata, - PurgeUserEventsRequest, - PurgeUserEventsResponse, -) -from .search_service import ( - SearchRequest, - SearchResponse, -) -from .user_event import ( - CompletionDetail, - ProductDetail, - PurchaseTransaction, - UserEvent, -) -from .user_event_service import ( - CollectUserEventRequest, - RejoinUserEventsMetadata, - RejoinUserEventsRequest, - RejoinUserEventsResponse, - WriteUserEventRequest, -) - -__all__ = ( - 'Catalog', - 'ProductLevelConfig', - 'GetDefaultBranchRequest', - 'GetDefaultBranchResponse', - 'ListCatalogsRequest', - 'ListCatalogsResponse', - 'SetDefaultBranchRequest', - 'UpdateCatalogRequest', - 'Audience', - 'ColorInfo', - 'CustomAttribute', - 'FulfillmentInfo', - 'Image', - 'Interval', - 'PriceInfo', - 'Promotion', - 'Rating', - 'UserInfo', - 'CompleteQueryRequest', - 'CompleteQueryResponse', - 'BigQuerySource', - 'CompletionDataInputConfig', - 'GcsSource', - 'ImportCompletionDataRequest', - 'ImportCompletionDataResponse', - 'ImportErrorsConfig', - 'ImportMetadata', - 'ImportProductsRequest', - 'ImportProductsResponse', - 'ImportUserEventsRequest', - 'ImportUserEventsResponse', - 'ProductInlineSource', - 'ProductInputConfig', - 'UserEventImportSummary', - 'UserEventInlineSource', - 'UserEventInputConfig', - 'PredictRequest', - 'PredictResponse', - 'Product', - 'AddFulfillmentPlacesMetadata', - 'AddFulfillmentPlacesRequest', - 'AddFulfillmentPlacesResponse', - 'CreateProductRequest', - 'DeleteProductRequest', - 'GetProductRequest', - 'ListProductsRequest', - 'ListProductsResponse', - 'RemoveFulfillmentPlacesMetadata', - 'RemoveFulfillmentPlacesRequest', - 'RemoveFulfillmentPlacesResponse', - 'SetInventoryMetadata', - 'SetInventoryRequest', - 'SetInventoryResponse', - 'UpdateProductRequest', - 'PurgeMetadata', - 'PurgeUserEventsRequest', - 'PurgeUserEventsResponse', - 'SearchRequest', - 'SearchResponse', - 'CompletionDetail', - 'ProductDetail', - 'PurchaseTransaction', - 'UserEvent', - 'CollectUserEventRequest', - 'RejoinUserEventsMetadata', - 'RejoinUserEventsRequest', - 'RejoinUserEventsResponse', - 'WriteUserEventRequest', -) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/catalog.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/catalog.py deleted file mode 100644 index 77327f5a..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/types/catalog.py +++ /dev/null @@ -1,130 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import proto # type: ignore - - -__protobuf__ = proto.module( - package='google.cloud.retail.v2', - manifest={ - 'ProductLevelConfig', - 'Catalog', - }, -) - - -class ProductLevelConfig(proto.Message): - r"""Configures what level the product should be uploaded with - regards to how users will be send events and how predictions - will be made. - - Attributes: - ingestion_product_type (str): - The type of [Product][google.cloud.retail.v2.Product]s - allowed to be ingested into the catalog. Acceptable values - are: - - - ``primary`` (default): You can ingest - [Product][google.cloud.retail.v2.Product]s of all types. - When ingesting a - [Product][google.cloud.retail.v2.Product], its type will - default to - [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] - if unset. - - ``variant``: You can only ingest - [Product.Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT] - [Product][google.cloud.retail.v2.Product]s. This means - [Product.primary_product_id][google.cloud.retail.v2.Product.primary_product_id] - cannot be empty. - - If this field is set to an invalid value other than these, - an INVALID_ARGUMENT error is returned. - - If this field is ``variant`` and - [merchant_center_product_id_field][google.cloud.retail.v2.ProductLevelConfig.merchant_center_product_id_field] - is ``itemGroupId``, an INVALID_ARGUMENT error is returned. - - See `Using product - levels `__ - for more details. - merchant_center_product_id_field (str): - Which field of `Merchant Center - Product `__ - should be imported as - [Product.id][google.cloud.retail.v2.Product.id]. Acceptable - values are: - - - ``offerId`` (default): Import ``offerId`` as the product - ID. - - ``itemGroupId``: Import ``itemGroupId`` as the product - ID. Notice that Retail API will choose one item from the - ones with the same ``itemGroupId``, and use it to - represent the item group. - - If this field is set to an invalid value other than these, - an INVALID_ARGUMENT error is returned. - - If this field is ``itemGroupId`` and - [ingestion_product_type][google.cloud.retail.v2.ProductLevelConfig.ingestion_product_type] - is ``variant``, an INVALID_ARGUMENT error is returned. - - See `Using product - levels `__ - for more details. - """ - - ingestion_product_type = proto.Field( - proto.STRING, - number=1, - ) - merchant_center_product_id_field = proto.Field( - proto.STRING, - number=2, - ) - - -class Catalog(proto.Message): - r"""The catalog configuration. - - Attributes: - name (str): - Required. Immutable. The fully qualified - resource name of the catalog. - display_name (str): - Required. Immutable. The catalog display name. - - This field must be a UTF-8 encoded string with a length - limit of 128 characters. Otherwise, an INVALID_ARGUMENT - error is returned. - product_level_config (google.cloud.retail_v2.types.ProductLevelConfig): - Required. The product level configuration. - """ - - 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', - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/catalog_service.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/catalog_service.py deleted file mode 100644 index 32e84a43..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/types/catalog_service.py +++ /dev/null @@ -1,235 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import proto # type: ignore - -from google.cloud.retail_v2.types import catalog as gcr_catalog -from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore - - -__protobuf__ = proto.module( - package='google.cloud.retail.v2', - manifest={ - 'ListCatalogsRequest', - 'ListCatalogsResponse', - 'UpdateCatalogRequest', - 'SetDefaultBranchRequest', - 'GetDefaultBranchRequest', - 'GetDefaultBranchResponse', - }, -) - - -class ListCatalogsRequest(proto.Message): - r"""Request for - [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] - method. - - Attributes: - parent (str): - Required. The account resource name with an associated - location. - - If the caller does not have permission to list - [Catalog][google.cloud.retail.v2.Catalog]s under this - location, regardless of whether or not this location exists, - a PERMISSION_DENIED error is returned. - page_size (int): - Maximum number of [Catalog][google.cloud.retail.v2.Catalog]s - to return. If unspecified, defaults to 50. The maximum - allowed value is 1000. Values above 1000 will be coerced to - 1000. - - If this field is negative, an INVALID_ARGUMENT is returned. - page_token (str): - A page token - [ListCatalogsResponse.next_page_token][google.cloud.retail.v2.ListCatalogsResponse.next_page_token], - received from a previous - [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] - call. Provide this to retrieve the subsequent page. - - When paginating, all other parameters provided to - [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] - must match the call that provided the page token. Otherwise, - 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, - ) - - -class ListCatalogsResponse(proto.Message): - r"""Response for - [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] - method. - - Attributes: - catalogs (Sequence[google.cloud.retail_v2.types.Catalog]): - All the customer's - [Catalog][google.cloud.retail.v2.Catalog]s. - next_page_token (str): - A token that can be sent as - [ListCatalogsRequest.page_token][google.cloud.retail.v2.ListCatalogsRequest.page_token] - to retrieve the next page. If this field is omitted, there - are no subsequent pages. - """ - - @property - def raw_page(self): - return self - - catalogs = proto.RepeatedField( - proto.MESSAGE, - number=1, - message=gcr_catalog.Catalog, - ) - next_page_token = proto.Field( - proto.STRING, - number=2, - ) - - -class UpdateCatalogRequest(proto.Message): - r"""Request for - [CatalogService.UpdateCatalog][google.cloud.retail.v2.CatalogService.UpdateCatalog] - method. - - Attributes: - catalog (google.cloud.retail_v2.types.Catalog): - Required. The [Catalog][google.cloud.retail.v2.Catalog] to - update. - - If the caller does not have permission to update the - [Catalog][google.cloud.retail.v2.Catalog], regardless of - whether or not it exists, a PERMISSION_DENIED error is - returned. - - If the [Catalog][google.cloud.retail.v2.Catalog] to update - does not exist, a NOT_FOUND error is returned. - update_mask (google.protobuf.field_mask_pb2.FieldMask): - Indicates which fields in the provided - [Catalog][google.cloud.retail.v2.Catalog] to update. - - If an unsupported or unknown field is provided, an - INVALID_ARGUMENT error is returned. - """ - - catalog = proto.Field( - proto.MESSAGE, - number=1, - message=gcr_catalog.Catalog, - ) - update_mask = proto.Field( - proto.MESSAGE, - number=2, - message=field_mask_pb2.FieldMask, - ) - - -class SetDefaultBranchRequest(proto.Message): - r"""Request message to set a specified branch as new default_branch. - - Attributes: - catalog (str): - Full resource name of the catalog, such as - ``projects/*/locations/global/catalogs/default_catalog``. - branch_id (str): - The final component of the resource name of a branch. - - This field must be one of "0", "1" or "2". Otherwise, an - INVALID_ARGUMENT error is returned. - note (str): - Some note on this request, this can be retrieved by - [CatalogService.GetDefaultBranch][google.cloud.retail.v2.CatalogService.GetDefaultBranch] - before next valid default branch set occurs. - - This field must be a UTF-8 encoded string with a length - limit of 1,000 characters. Otherwise, an INVALID_ARGUMENT - error is returned. - """ - - catalog = proto.Field( - proto.STRING, - number=1, - ) - branch_id = proto.Field( - proto.STRING, - number=2, - ) - note = proto.Field( - proto.STRING, - number=3, - ) - - -class GetDefaultBranchRequest(proto.Message): - r"""Request message to show which branch is currently the default - branch. - - Attributes: - catalog (str): - The parent catalog resource name, such as - ``projects/*/locations/global/catalogs/default_catalog``. - """ - - catalog = proto.Field( - proto.STRING, - number=1, - ) - - -class GetDefaultBranchResponse(proto.Message): - r"""Response message of - [CatalogService.GetDefaultBranch][google.cloud.retail.v2.CatalogService.GetDefaultBranch]. - - Attributes: - branch (str): - Full resource name of the branch id currently - set as default branch. - set_time (google.protobuf.timestamp_pb2.Timestamp): - The time when this branch is set to default. - note (str): - This corresponds to - [SetDefaultBranchRequest.note][google.cloud.retail.v2.SetDefaultBranchRequest.note] - 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, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/common.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/common.py deleted file mode 100644 index 9e3c3c58..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/types/common.py +++ /dev/null @@ -1,651 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import proto # type: ignore - -from google.protobuf import timestamp_pb2 # type: ignore - - -__protobuf__ = proto.module( - package='google.cloud.retail.v2', - manifest={ - 'Audience', - 'ColorInfo', - 'CustomAttribute', - 'FulfillmentInfo', - 'Image', - 'Interval', - 'PriceInfo', - 'Rating', - 'UserInfo', - 'Promotion', - }, -) - - -class Audience(proto.Message): - r"""An intended audience of the - [Product][google.cloud.retail.v2.Product] for whom it's sold. - - Attributes: - genders (Sequence[str]): - The genders of the audience. Strongly encouraged to use the - standard values: "male", "female", "unisex". - - At most 5 values are allowed. Each value must be a UTF-8 - encoded string with a length limit of 128 characters. - Otherwise, an INVALID_ARGUMENT error is returned. - - Google Merchant Center property - `gender `__. - Schema.org property - `Product.audience.suggestedGender `__. - age_groups (Sequence[str]): - The age groups of the audience. Strongly encouraged to use - the standard values: "newborn" (up to 3 months old), - "infant" (3–12 months old), "toddler" (1–5 years old), - "kids" (5–13 years old), "adult" (typically teens or older). - - At most 5 values are allowed. Each value must be a UTF-8 - encoded string with a length limit of 128 characters. - Otherwise, an INVALID_ARGUMENT error is returned. - - Google Merchant Center property - `age_group `__. - Schema.org property - `Product.audience.suggestedMinAge `__ - and - `Product.audience.suggestedMaxAge `__. - """ - - genders = proto.RepeatedField( - proto.STRING, - number=1, - ) - age_groups = proto.RepeatedField( - proto.STRING, - number=2, - ) - - -class ColorInfo(proto.Message): - r"""The color information of a - [Product][google.cloud.retail.v2.Product]. - - Attributes: - color_families (Sequence[str]): - The standard color families. Strongly recommended to use the - following standard color groups: "Red", "Pink", "Orange", - "Yellow", "Purple", "Green", "Cyan", "Blue", "Brown", - "White", "Gray", "Black" and "Mixed". Normally it is - expected to have only 1 color family. May consider using - single "Mixed" instead of multiple values. - - A maximum of 5 values are allowed. Each value must be a - UTF-8 encoded string with a length limit of 128 characters. - Otherwise, an INVALID_ARGUMENT error is returned. - - Google Merchant Center property - `color `__. - Schema.org property - `Product.color `__. - colors (Sequence[str]): - The color display names, which may be different from - standard color family names, such as the color aliases used - in the website frontend. Normally it is expected to have - only 1 color. May consider using single "Mixed" instead of - multiple values. - - A maximum of 25 colors are allowed. Each value must be a - UTF-8 encoded string with a length limit of 128 characters. - Otherwise, an INVALID_ARGUMENT error is returned. - - Google Merchant Center property - `color `__. - Schema.org property - `Product.color `__. - """ - - color_families = proto.RepeatedField( - proto.STRING, - number=1, - ) - colors = proto.RepeatedField( - proto.STRING, - number=2, - ) - - -class CustomAttribute(proto.Message): - r"""A custom attribute that is not explicitly modeled in - [Product][google.cloud.retail.v2.Product]. - - Attributes: - text (Sequence[str]): - 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. - - 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. - numbers (Sequence[float]): - 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 - [SearchService.Search][google.cloud.retail.v2.SearchService.Search]. - - This field is ignored in a - [UserEvent][google.cloud.retail.v2.UserEvent]. - - Only set if type - [text][google.cloud.retail.v2.CustomAttribute.text] is set. - Otherwise, a INVALID_ARGUMENT error is returned. - - 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 - [SearchService.Search][google.cloud.retail.v2.SearchService.Search]. - - This field is ignored in a - [UserEvent][google.cloud.retail.v2.UserEvent]. - - See - [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter], - [SearchRequest.facet_specs][google.cloud.retail.v2.SearchRequest.facet_specs] - and - [SearchRequest.boost_spec][google.cloud.retail.v2.SearchRequest.boost_spec] - for more details. - - 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, - ) - - -class FulfillmentInfo(proto.Message): - r"""Fulfillment information, such as the store IDs for in-store - pickup or region IDs for different shipping methods. - - Attributes: - type_ (str): - The fulfillment type, including 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. - place_ids (Sequence[str]): - The IDs for this - [type][google.cloud.retail.v2.FulfillmentInfo.type], such as - the store IDs for - [FulfillmentInfo.type.pickup-in-store][google.cloud.retail.v2.FulfillmentInfo.type] - or the region IDs for - [FulfillmentInfo.type.same-day-delivery][google.cloud.retail.v2.FulfillmentInfo.type]. - - A maximum of 3000 values are allowed. Each value must be a - string with a length limit of 30 characters, matching the - pattern ``[a-zA-Z0-9_-]+``, such as "store1" or "REGION-2". - Otherwise, an INVALID_ARGUMENT error is returned. - """ - - 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. - - Attributes: - uri (str): - Required. URI of the image. - - This field must be a valid UTF-8 encoded URI with a length - limit of 5,000 characters. Otherwise, an INVALID_ARGUMENT - error is returned. - - Google Merchant Center property - `image_link `__. - Schema.org property - `Product.image `__. - height (int): - Height of the image in number of pixels. - - This field must be nonnegative. Otherwise, an - INVALID_ARGUMENT error is returned. - width (int): - Width of the image in number of pixels. - - This field must be nonnegative. Otherwise, an - 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, - ) - - -class Interval(proto.Message): - r"""A floating point interval. - - This message has `oneof`_ fields (mutually exclusive fields). - For each oneof, at most one member field can be set at the same time. - Setting any member of the oneof automatically clears all other - members. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - minimum (float): - Inclusive lower bound. - - This field is a member of `oneof`_ ``min``. - exclusive_minimum (float): - Exclusive lower bound. - - This field is a member of `oneof`_ ``min``. - maximum (float): - Inclusive upper bound. - - This field is a member of `oneof`_ ``max``. - exclusive_maximum (float): - Exclusive upper bound. - - 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', - ) - - -class PriceInfo(proto.Message): - r"""The price information of a - [Product][google.cloud.retail.v2.Product]. - - Attributes: - currency_code (str): - The 3-letter currency code defined in `ISO - 4217 `__. - - If this field is an unrecognizable currency code, an - INVALID_ARGUMENT error is returned. - - The - [Product.Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT] - [Product][google.cloud.retail.v2.Product]s with the same - [Product.primary_product_id][google.cloud.retail.v2.Product.primary_product_id] - must share the same - [currency_code][google.cloud.retail.v2.PriceInfo.currency_code]. - Otherwise, a FAILED_PRECONDITION error is returned. - price (float): - Price of the product. - - Google Merchant Center property - `price `__. - Schema.org property - `Offer.priceSpecification `__. - original_price (float): - Price of the product without any discount. If zero, by - default set to be the - [price][google.cloud.retail.v2.PriceInfo.price]. - cost (float): - The costs associated with the sale of a particular product. - Used for gross profit reporting. - - - Profit = [price][google.cloud.retail.v2.PriceInfo.price] - - [cost][google.cloud.retail.v2.PriceInfo.cost] - - Google Merchant Center property - `cost_of_goods_sold `__. - price_effective_time (google.protobuf.timestamp_pb2.Timestamp): - The timestamp when the - [price][google.cloud.retail.v2.PriceInfo.price] starts to be - effective. This can be set as a future timestamp, and the - [price][google.cloud.retail.v2.PriceInfo.price] is only used - for search after - [price_effective_time][google.cloud.retail.v2.PriceInfo.price_effective_time]. - If so, the - [original_price][google.cloud.retail.v2.PriceInfo.original_price] - must be set and - [original_price][google.cloud.retail.v2.PriceInfo.original_price] - is used before - [price_effective_time][google.cloud.retail.v2.PriceInfo.price_effective_time]. - - Do not set if - [price][google.cloud.retail.v2.PriceInfo.price] is always - effective because it will cause additional latency during - search. - price_expire_time (google.protobuf.timestamp_pb2.Timestamp): - The timestamp when the - [price][google.cloud.retail.v2.PriceInfo.price] stops to be - effective. The - [price][google.cloud.retail.v2.PriceInfo.price] is used for - search before - [price_expire_time][google.cloud.retail.v2.PriceInfo.price_expire_time]. - If this field is set, the - [original_price][google.cloud.retail.v2.PriceInfo.original_price] - must be set and - [original_price][google.cloud.retail.v2.PriceInfo.original_price] - is used after - [price_expire_time][google.cloud.retail.v2.PriceInfo.price_expire_time]. - - Do not set if - [price][google.cloud.retail.v2.PriceInfo.price] is always - effective because it will cause additional latency during - search. - price_range (google.cloud.retail_v2.types.PriceInfo.PriceRange): - Output only. The price range of all the child - [Product.Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT] - [Product][google.cloud.retail.v2.Product]s grouped together - on the - [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] - [Product][google.cloud.retail.v2.Product]. Only populated - for - [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] - [Product][google.cloud.retail.v2.Product]s. - - Note: This field is OUTPUT_ONLY for - [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct]. - Do not set this field in API requests. - """ - - class PriceRange(proto.Message): - r"""The price range of all - [variant][google.cloud.retail.v2.Product.Type.VARIANT] - [Product][google.cloud.retail.v2.Product] having the same - [Product.primary_product_id][google.cloud.retail.v2.Product.primary_product_id]. - - Attributes: - price (google.cloud.retail_v2.types.Interval): - The inclusive - [Product.pricing_info.price][google.cloud.retail.v2.PriceInfo.price] - interval of all - [variant][google.cloud.retail.v2.Product.Type.VARIANT] - [Product][google.cloud.retail.v2.Product] having the same - [Product.primary_product_id][google.cloud.retail.v2.Product.primary_product_id]. - original_price (google.cloud.retail_v2.types.Interval): - The inclusive - [Product.pricing_info.original_price][google.cloud.retail.v2.PriceInfo.original_price] - internal of all - [variant][google.cloud.retail.v2.Product.Type.VARIANT] - [Product][google.cloud.retail.v2.Product] having the same - [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_effective_time = proto.Field( - proto.MESSAGE, - number=5, - message=timestamp_pb2.Timestamp, - ) - price_expire_time = proto.Field( - proto.MESSAGE, - number=6, - message=timestamp_pb2.Timestamp, - ) - price_range = proto.Field( - proto.MESSAGE, - number=7, - message=PriceRange, - ) - - -class Rating(proto.Message): - r"""The rating of a [Product][google.cloud.retail.v2.Product]. - - Attributes: - rating_count (int): - The total number of ratings. This value is independent of - the value of - [rating_histogram][google.cloud.retail.v2.Rating.rating_histogram]. - - This value must be nonnegative. Otherwise, an - INVALID_ARGUMENT error is returned. - average_rating (float): - The average rating of the - [Product][google.cloud.retail.v2.Product]. - - The rating is scaled at 1-5. Otherwise, an INVALID_ARGUMENT - error is returned. - rating_histogram (Sequence[int]): - List of rating counts per rating value (index = rating - 1). - The list is empty if there is no rating. If the list is - non-empty, its size is always 5. Otherwise, an - INVALID_ARGUMENT error is returned. - - For example, [41, 14, 13, 47, 303]. It means that the - [Product][google.cloud.retail.v2.Product] got 41 ratings - 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, - ) - - -class UserInfo(proto.Message): - r"""Information of an end user. - - Attributes: - user_id (str): - Highly recommended for logged-in users. Unique identifier - for logged-in user, such as a user name. - - 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. - - 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. - user_agent (str): - User agent as included in the HTTP header. Required for - getting - [SearchResponse.sponsored_results][google.cloud.retail.v2.SearchResponse.sponsored_results]. - - The field must be a UTF-8 encoded string with a length limit - of 1,000 characters. Otherwise, an INVALID_ARGUMENT error is - returned. - - This should not be set when using the client side event - reporting with GTM or 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. - direct_user_request (bool): - True if the request is made directly from the end user, in - which case the - [ip_address][google.cloud.retail.v2.UserInfo.ip_address] and - [user_agent][google.cloud.retail.v2.UserInfo.user_agent] can - be populated from the HTTP request. This flag should be set - only if the API request is made directly from the end user - such as a mobile app (and not if a gateway or a server is - processing and pushing the user events). - - This should not be set when using the JavaScript tag in - [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, - ) - - -class Promotion(proto.Message): - r"""Promotion information. - - 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. - - Google Merchant Center property - `promotion `__. - """ - - promotion_id = proto.Field( - proto.STRING, - number=1, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/completion_service.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/completion_service.py deleted file mode 100644 index dfa9bfb8..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/types/completion_service.py +++ /dev/null @@ -1,218 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import proto # type: ignore - -from google.cloud.retail_v2.types import common - - -__protobuf__ = proto.module( - package='google.cloud.retail.v2', - manifest={ - 'CompleteQueryRequest', - 'CompleteQueryResponse', - }, -) - - -class CompleteQueryRequest(proto.Message): - r"""Auto-complete parameters. - - Attributes: - catalog (str): - Required. Catalog for which the completion is performed. - - Full resource name of catalog, such as - ``projects/*/locations/global/catalogs/default_catalog``. - query (str): - Required. The query used to generate - 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. - - 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. - device_type (str): - The device type context for completion suggestions. It is - useful to apply different suggestions on different device - types, e.g. ``DESKTOP``, ``MOBILE``. If it is empty, the - suggestions are across all device types. - - Supported formats: - - - ``UNKNOWN_DEVICE_TYPE`` - - - ``DESKTOP`` - - - ``MOBILE`` - - - A customized string starts with ``OTHER_``, e.g. - ``OTHER_IPHONE``. - dataset (str): - Determines which dataset to use for fetching completion. - "user-data" will use the imported dataset through - [CompletionService.ImportCompletionData][google.cloud.retail.v2.CompletionService.ImportCompletionData]. - "cloud-retail" will use the dataset generated by cloud - retail based on user events. If leave empty, it will use the - "user-data". - - Current supported values: - - - user-data - - - cloud-retail This option requires additional - allowlisting. Before using cloud-retail, contact Cloud - Retail support team first. - max_suggestions (int): - Completion max suggestions. If left unset or set to 0, then - will fallback to the configured value - [CompletionConfig.max_suggestions][]. - - The maximum allowed max suggestions is 20. If it is set - 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, - ) - - -class CompleteQueryResponse(proto.Message): - r"""Response of the auto-complete query. - - Attributes: - completion_results (Sequence[google.cloud.retail_v2.types.CompleteQueryResponse.CompletionResult]): - Results of the matching suggestions. The - result list is ordered and the first result is - 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. - 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. - Contact Retail Search support team if you are interested in - enabling it. - - This feature is only available when - [CompleteQueryRequest.visitor_id][google.cloud.retail.v2.CompleteQueryRequest.visitor_id] - field is set and - [UserEvent][google.cloud.retail.v2.UserEvent] is imported. - The recent searches satisfy the follow rules: - - - They are ordered from latest to oldest. - - They are matched with - [CompleteQueryRequest.query][google.cloud.retail.v2.CompleteQueryRequest.query] - case insensitively. - - They are transformed to lower cases. - - They are UTF-8 safe. - - Recent searches are deduplicated. More recent searches will - be reserved when duplication happens. - """ - - class CompletionResult(proto.Message): - r"""Resource that represents completion results. - - Attributes: - suggestion (str): - The suggestion for the query. - attributes (Sequence[google.cloud.retail_v2.types.CompleteQueryResponse.CompletionResult.AttributesEntry]): - Additional custom attributes ingested through - BigQuery. - """ - - suggestion = proto.Field( - proto.STRING, - number=1, - ) - attributes = proto.MapField( - proto.STRING, - proto.MESSAGE, - number=2, - message=common.CustomAttribute, - ) - - class RecentSearchResult(proto.Message): - r"""Recent search of this user. - - Attributes: - recent_search (str): - The recent search query. - """ - - recent_search = proto.Field( - proto.STRING, - number=1, - ) - - completion_results = proto.RepeatedField( - proto.MESSAGE, - number=1, - message=CompletionResult, - ) - attribution_token = proto.Field( - proto.STRING, - number=2, - ) - recent_search_results = proto.RepeatedField( - proto.MESSAGE, - number=3, - message=RecentSearchResult, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/import_config.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/import_config.py deleted file mode 100644 index 8eed17f4..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/types/import_config.py +++ /dev/null @@ -1,677 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import proto # type: ignore - -from google.cloud.retail_v2.types import product -from google.cloud.retail_v2.types import user_event -from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore -from google.rpc import status_pb2 # type: ignore -from google.type import date_pb2 # type: ignore - - -__protobuf__ = proto.module( - package='google.cloud.retail.v2', - manifest={ - 'GcsSource', - 'BigQuerySource', - 'ProductInlineSource', - 'UserEventInlineSource', - 'ImportErrorsConfig', - 'ImportProductsRequest', - 'ImportUserEventsRequest', - 'ImportCompletionDataRequest', - 'ProductInputConfig', - 'UserEventInputConfig', - 'CompletionDataInputConfig', - 'ImportMetadata', - 'ImportProductsResponse', - 'ImportUserEventsResponse', - 'UserEventImportSummary', - 'ImportCompletionDataResponse', - }, -) - - -class GcsSource(proto.Message): - r"""Google Cloud Storage location for input content. - format. - - Attributes: - input_uris (Sequence[str]): - Required. Google Cloud Storage URIs to input files. URI can - be up to 2000 characters long. URIs can match the full - object path (for example, - ``gs://bucket/directory/object.json``) or a pattern matching - one or more files, such as ``gs://bucket/directory/*.json``. - A request can contain at most 100 files, and each file can - be up to 2 GB. See `Importing product - information `__ - for the expected file format and setup instructions. - data_schema (str): - The schema to use when parsing the data from the source. - - Supported values for product imports: - - - ``product`` (default): One JSON - [Product][google.cloud.retail.v2.Product] per line. Each - product must have a valid - [Product.id][google.cloud.retail.v2.Product.id]. - - ``product_merchant_center``: See `Importing catalog data - from Merchant - Center `__. - - Supported values for user events imports: - - - ``user_event`` (default): One JSON - [UserEvent][google.cloud.retail.v2.UserEvent] per line. - - ``user_event_ga360``: Using - https://support.google.com/analytics/answer/3437719. - """ - - input_uris = proto.RepeatedField( - proto.STRING, - number=1, - ) - data_schema = proto.Field( - proto.STRING, - number=2, - ) - - -class BigQuerySource(proto.Message): - r"""BigQuery source import data from. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - partition_date (google.type.date_pb2.Date): - BigQuery time partitioned table's \_PARTITIONDATE in - YYYY-MM-DD format. - - Only supported when - [ImportProductsRequest.reconciliation_mode][google.cloud.retail.v2.ImportProductsRequest.reconciliation_mode] - is set to ``FULL``. - - This field is a member of `oneof`_ ``partition``. - project_id (str): - The project ID (can be project # or ID) that - the BigQuery source is in with a length limit of - 128 characters. If not specified, inherits the - project ID from the parent request. - dataset_id (str): - Required. The BigQuery data set to copy the - data from with a length limit of 1,024 - characters. - table_id (str): - Required. The BigQuery table to copy the data - from with a length limit of 1,024 characters. - gcs_staging_dir (str): - Intermediate Cloud Storage directory used for - the import with a length limit of 2,000 - characters. Can be specified if one wants to - have the BigQuery export to a specific Cloud - Storage directory. - data_schema (str): - The schema to use when parsing the data from the source. - - Supported values for product imports: - - - ``product`` (default): One JSON - [Product][google.cloud.retail.v2.Product] per line. Each - product must have a valid - [Product.id][google.cloud.retail.v2.Product.id]. - - ``product_merchant_center``: See `Importing catalog data - from Merchant - Center `__. - - Supported values for user events imports: - - - ``user_event`` (default): One JSON - [UserEvent][google.cloud.retail.v2.UserEvent] per line. - - ``user_event_ga360``: Using - https://support.google.com/analytics/answer/3437719. - """ - - partition_date = proto.Field( - 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, - ) - - -class ProductInlineSource(proto.Message): - r"""The inline source for the input config for ImportProducts - method. - - Attributes: - products (Sequence[google.cloud.retail_v2.types.Product]): - Required. A list of products to update/create. Each product - must have a valid - [Product.id][google.cloud.retail.v2.Product.id]. Recommended - max of 100 items. - """ - - products = proto.RepeatedField( - proto.MESSAGE, - number=1, - message=product.Product, - ) - - -class UserEventInlineSource(proto.Message): - r"""The inline source for the input config for ImportUserEvents - method. - - Attributes: - user_events (Sequence[google.cloud.retail_v2.types.UserEvent]): - Required. A list of user events to import. - Recommended max of 10k items. - """ - - user_events = proto.RepeatedField( - proto.MESSAGE, - number=1, - message=user_event.UserEvent, - ) - - -class ImportErrorsConfig(proto.Message): - r"""Configuration of destination for Import related errors. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - 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. - - This field is a member of `oneof`_ ``destination``. - """ - - gcs_prefix = proto.Field( - proto.STRING, - number=1, - oneof='destination', - ) - - -class ImportProductsRequest(proto.Message): - r"""Request message for Import methods. - - Attributes: - parent (str): - Required. - ``projects/1234/locations/global/catalogs/default_catalog/branches/default_branch`` - - If no updateMask is specified, requires products.create - 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``. - input_config (google.cloud.retail_v2.types.ProductInputConfig): - Required. The desired input location of the - data. - errors_config (google.cloud.retail_v2.types.ImportErrorsConfig): - The desired location of errors incurred - during the Import. - update_mask (google.protobuf.field_mask_pb2.FieldMask): - Indicates which fields in the provided - imported 'products' to update. If not set, will - by default update all fields. - reconciliation_mode (google.cloud.retail_v2.types.ImportProductsRequest.ReconciliationMode): - The mode of reconciliation between existing products and the - products to be imported. Defaults to - [ReconciliationMode.INCREMENTAL][google.cloud.retail.v2.ImportProductsRequest.ReconciliationMode.INCREMENTAL]. - notification_pubsub_topic (str): - Pub/Sub topic for receiving notification. If this field is - set, when the import is finished, a notification will be - sent to specified Pub/Sub topic. The message data will be - JSON string of a [Operation][google.longrunning.Operation]. - Format of the Pub/Sub topic is - ``projects/{project}/topics/{topic}``. - - Only supported when - [ImportProductsRequest.reconciliation_mode][google.cloud.retail.v2.ImportProductsRequest.reconciliation_mode] - is set to ``FULL``. - """ - class ReconciliationMode(proto.Enum): - r"""Indicates how imported products are reconciled with the - existing products created or imported before. - """ - RECONCILIATION_MODE_UNSPECIFIED = 0 - 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', - ) - update_mask = proto.Field( - 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, - ) - - -class ImportUserEventsRequest(proto.Message): - r"""Request message for the ImportUserEvents request. - - Attributes: - parent (str): - Required. - ``projects/1234/locations/global/catalogs/default_catalog`` - input_config (google.cloud.retail_v2.types.UserEventInputConfig): - Required. The desired input location of the - data. - errors_config (google.cloud.retail_v2.types.ImportErrorsConfig): - The desired location of errors incurred - during the Import. Cannot be set for inline user - 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', - ) - - -class ImportCompletionDataRequest(proto.Message): - r"""Request message for ImportCompletionData methods. - - Attributes: - parent (str): - Required. The catalog which the suggestions dataset belongs - to. - - Format: - ``projects/1234/locations/global/catalogs/default_catalog``. - input_config (google.cloud.retail_v2.types.CompletionDataInputConfig): - Required. The desired input location of the - data. - notification_pubsub_topic (str): - Pub/Sub topic for receiving notification. If this field is - set, when the import is finished, a notification will be - sent to specified Pub/Sub topic. The message data will be - JSON string of a [Operation][google.longrunning.Operation]. - Format of the Pub/Sub topic is - ``projects/{project}/topics/{topic}``. - """ - - parent = proto.Field( - proto.STRING, - number=1, - ) - input_config = proto.Field( - proto.MESSAGE, - number=2, - message='CompletionDataInputConfig', - ) - notification_pubsub_topic = proto.Field( - proto.STRING, - number=3, - ) - - -class ProductInputConfig(proto.Message): - r"""The input config source for products. - - This message has `oneof`_ fields (mutually exclusive fields). - For each oneof, at most one member field can be set at the same time. - Setting any member of the oneof automatically clears all other - members. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - product_inline_source (google.cloud.retail_v2.types.ProductInlineSource): - The Inline source for the input content for - products. - - This field is a member of `oneof`_ ``source``. - gcs_source (google.cloud.retail_v2.types.GcsSource): - Google Cloud Storage location for the input - content. - - This field is a member of `oneof`_ ``source``. - big_query_source (google.cloud.retail_v2.types.BigQuerySource): - BigQuery input source. - - This field is a member of `oneof`_ ``source``. - """ - - product_inline_source = proto.Field( - proto.MESSAGE, - number=1, - oneof='source', - message='ProductInlineSource', - ) - gcs_source = proto.Field( - proto.MESSAGE, - number=2, - oneof='source', - message='GcsSource', - ) - big_query_source = proto.Field( - proto.MESSAGE, - number=3, - oneof='source', - message='BigQuerySource', - ) - - -class UserEventInputConfig(proto.Message): - r"""The input config source for user events. - - This message has `oneof`_ fields (mutually exclusive fields). - For each oneof, at most one member field can be set at the same time. - Setting any member of the oneof automatically clears all other - members. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - user_event_inline_source (google.cloud.retail_v2.types.UserEventInlineSource): - Required. The Inline source for the input - content for UserEvents. - - This field is a member of `oneof`_ ``source``. - gcs_source (google.cloud.retail_v2.types.GcsSource): - Required. Google Cloud Storage location for - the input content. - - This field is a member of `oneof`_ ``source``. - big_query_source (google.cloud.retail_v2.types.BigQuerySource): - Required. BigQuery input source. - - This field is a member of `oneof`_ ``source``. - """ - - user_event_inline_source = proto.Field( - proto.MESSAGE, - number=1, - oneof='source', - message='UserEventInlineSource', - ) - gcs_source = proto.Field( - proto.MESSAGE, - number=2, - oneof='source', - message='GcsSource', - ) - big_query_source = proto.Field( - proto.MESSAGE, - number=3, - oneof='source', - message='BigQuerySource', - ) - - -class CompletionDataInputConfig(proto.Message): - r"""The input config source for completion data. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - big_query_source (google.cloud.retail_v2.types.BigQuerySource): - Required. BigQuery input source. - Add the IAM permission "BigQuery Data Viewer" - for cloud-retail-customer-data- - access@system.gserviceaccount.com before using - this feature otherwise an error is thrown. - - This field is a member of `oneof`_ ``source``. - """ - - big_query_source = proto.Field( - proto.MESSAGE, - number=1, - oneof='source', - message='BigQuerySource', - ) - - -class ImportMetadata(proto.Message): - r"""Metadata related to the progress of the Import operation. - This will be returned by the - google.longrunning.Operation.metadata field. - - Attributes: - create_time (google.protobuf.timestamp_pb2.Timestamp): - Operation create time. - update_time (google.protobuf.timestamp_pb2.Timestamp): - Operation last update time. If the operation - is done, this is also the finish time. - success_count (int): - Count of entries that were processed - successfully. - failure_count (int): - 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. - notification_pubsub_topic (str): - Pub/Sub topic for receiving notification. If this field is - set, when the import is finished, a notification will be - sent to specified Pub/Sub topic. The message data will be - JSON string of a [Operation][google.longrunning.Operation]. - Format of the Pub/Sub topic is - ``projects/{project}/topics/{topic}``. - """ - - 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): - r"""Response of the - [ImportProductsRequest][google.cloud.retail.v2.ImportProductsRequest]. - If the long running operation is done, then this message is returned - by the google.longrunning.Operations.response field if the operation - was successful. - - Attributes: - error_samples (Sequence[google.rpc.status_pb2.Status]): - A sample of errors encountered while - processing the request. - errors_config (google.cloud.retail_v2.types.ImportErrorsConfig): - Echoes the destination for the complete - errors in the request if set. - """ - - error_samples = proto.RepeatedField( - proto.MESSAGE, - number=1, - message=status_pb2.Status, - ) - errors_config = proto.Field( - proto.MESSAGE, - number=2, - message='ImportErrorsConfig', - ) - - -class ImportUserEventsResponse(proto.Message): - r"""Response of the ImportUserEventsRequest. If the long running - operation was successful, then this message is returned by the - google.longrunning.Operations.response field if the operation - was successful. - - Attributes: - error_samples (Sequence[google.rpc.status_pb2.Status]): - A sample of errors encountered while - processing the request. - errors_config (google.cloud.retail_v2.types.ImportErrorsConfig): - Echoes the destination for the complete - errors if this field was set in the request. - import_summary (google.cloud.retail_v2.types.UserEventImportSummary): - Aggregated statistics of user event import - status. - """ - - error_samples = proto.RepeatedField( - proto.MESSAGE, - number=1, - message=status_pb2.Status, - ) - errors_config = proto.Field( - proto.MESSAGE, - number=2, - message='ImportErrorsConfig', - ) - import_summary = proto.Field( - proto.MESSAGE, - number=3, - message='UserEventImportSummary', - ) - - -class UserEventImportSummary(proto.Message): - r"""A summary of import result. The UserEventImportSummary - summarizes the import status for user events. - - Attributes: - joined_events_count (int): - Count of user events imported with complete - existing catalog information. - unjoined_events_count (int): - Count of user events imported, but with - catalog information not found in the imported - catalog. - """ - - joined_events_count = proto.Field( - proto.INT64, - number=1, - ) - unjoined_events_count = proto.Field( - proto.INT64, - number=2, - ) - - -class ImportCompletionDataResponse(proto.Message): - r"""Response of the - [ImportCompletionDataRequest][google.cloud.retail.v2.ImportCompletionDataRequest]. - If the long running operation is done, this message is returned by - the google.longrunning.Operations.response field if the operation is - successful. - - Attributes: - error_samples (Sequence[google.rpc.status_pb2.Status]): - A sample of errors encountered while - processing the request. - """ - - error_samples = proto.RepeatedField( - proto.MESSAGE, - number=1, - message=status_pb2.Status, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/prediction_service.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/prediction_service.py deleted file mode 100644 index 1b668c6d..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/types/prediction_service.py +++ /dev/null @@ -1,260 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import proto # type: ignore - -from google.cloud.retail_v2.types import user_event as gcr_user_event -from google.protobuf import struct_pb2 # type: ignore - - -__protobuf__ = proto.module( - package='google.cloud.retail.v2', - manifest={ - 'PredictRequest', - 'PredictResponse', - }, -) - - -class PredictRequest(proto.Message): - r"""Request message for Predict method. - - Attributes: - placement (str): - Required. Full resource name of the format: - {name=projects/*/locations/global/catalogs/default_catalog/placements/*} - The ID of the Recommendations AI placement. Before you can - request predictions from your model, you must create at - least one placement for it. For more information, see - `Managing - placements `__. - - The full list of available placements can be seen at - https://console.cloud.google.com/recommendation/catalogs/default_catalog/placements - user_event (google.cloud.retail_v2.types.UserEvent): - Required. Context about the user, what they - are looking at and what action they took to - trigger the predict request. Note that this user - event detail won't be ingested to userEvent - logs. Thus, a separate userEvent write request - is required for event logging. - page_size (int): - Maximum number of results to return per page. - Set this property to the number of prediction - results needed. If zero, the service will choose - a reasonable default. The maximum allowed value - is 100. Values above 100 will be coerced to 100. - page_token (str): - The previous PredictResponse.next_page_token. - filter (str): - Filter for restricting prediction results with a length - limit of 5,000 characters. Accepts values for tags and the - ``filterOutOfStockItems`` flag. - - - Tag expressions. Restricts predictions to products that - match all of the specified tags. Boolean operators ``OR`` - and ``NOT`` are supported if the expression is enclosed - in parentheses, and must be separated from the tag values - by a space. ``-"tagA"`` is also supported and is - equivalent to ``NOT "tagA"``. Tag values must be double - quoted UTF-8 encoded strings with a size limit of 1,000 - characters. - - Note: "Recently viewed" models don't support tag - filtering at the moment. - - - filterOutOfStockItems. Restricts predictions to products - that do not have a stockState value of OUT_OF_STOCK. - - Examples: - - - tag=("Red" OR "Blue") tag="New-Arrival" tag=(NOT - "promotional") - - 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``. - validate_only (bool): - Use validate only mode for this prediction - query. If set to true, a dummy model will be - used that returns arbitrary products. Note that - the validate only mode should only be used for - testing the API, or if the model is not ready. - params (Sequence[google.cloud.retail_v2.types.PredictRequest.ParamsEntry]): - Additional domain specific parameters for the predictions. - - Allowed values: - - - ``returnProduct``: Boolean. If set to true, the - associated product object will be returned in the - ``results.metadata`` field in the prediction response. - - ``returnScore``: Boolean. If set to true, the prediction - 'score' corresponding to each returned product will be - set in the ``results.metadata`` field in the prediction - response. The given 'score' indicates the probability of - an product being clicked/purchased given the user's - context and history. - - ``strictFiltering``: Boolean. True by default. If set to - false, the service will return generic (unfiltered) - popular products instead of empty if your filter blocks - all prediction results. - - ``priceRerankLevel``: String. Default empty. If set to be - non-empty, then it needs to be one of - {'no-price-reranking', 'low-price-reranking', - 'medium-price-reranking', 'high-price-reranking'}. This - gives request-level control and adjusts prediction - results based on product price. - - ``diversityLevel``: String. Default empty. If set to be - non-empty, then it needs to be one of {'no-diversity', - 'low-diversity', 'medium-diversity', 'high-diversity', - 'auto-diversity'}. This gives request-level control and - adjusts prediction results based on product category. - labels (Sequence[google.cloud.retail_v2.types.PredictRequest.LabelsEntry]): - The labels applied to a resource must meet the following - requirements: - - - Each resource can have multiple labels, up to a maximum - of 64. - - Each label must be a key-value pair. - - Keys have a minimum length of 1 character and a maximum - length of 63 characters, and cannot be empty. Values can - be empty, and have a maximum length of 63 characters. - - Keys and values can contain only lowercase letters, - numeric characters, underscores, and dashes. All - characters must use UTF-8 encoding, and international - characters are allowed. - - The key portion of a label must be unique. However, you - can use the same key with multiple resources. - - Keys must start with a lowercase letter or international - character. - - See `Google Cloud - Document `__ - 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, - ) - params = proto.MapField( - proto.STRING, - proto.MESSAGE, - number=7, - message=struct_pb2.Value, - ) - labels = proto.MapField( - proto.STRING, - proto.STRING, - number=8, - ) - - -class PredictResponse(proto.Message): - r"""Response message for predict method. - - Attributes: - results (Sequence[google.cloud.retail_v2.types.PredictResponse.PredictionResult]): - A list of recommended products. The order - represents the ranking (from the most relevant - product to the least). - attribution_token (str): - A unique attribution token. This should be included in the - [UserEvent][google.cloud.retail.v2.UserEvent] logs resulting - from this recommendation, which enables accurate attribution - of recommendation model performance. - missing_ids (Sequence[str]): - IDs of products in the request that were - missing from the inventory. - validate_only (bool): - True if the validateOnly property was set in - the request. - """ - - class PredictionResult(proto.Message): - r"""PredictionResult represents the recommendation prediction - results. - - Attributes: - id (str): - ID of the recommended product - metadata (Sequence[google.cloud.retail_v2.types.PredictResponse.PredictionResult.MetadataEntry]): - Additional product metadata / annotations. - - Possible values: - - - ``product``: JSON representation of the product. Will be - set if ``returnProduct`` is set to true in - ``PredictRequest.params``. - - ``score``: Prediction score in double value. Will be set - if ``returnScore`` is set to true in - ``PredictRequest.params``. - """ - - id = proto.Field( - proto.STRING, - number=1, - ) - metadata = proto.MapField( - 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, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/product.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/product.py deleted file mode 100644 index 944233fb..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/types/product.py +++ /dev/null @@ -1,689 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import proto # type: ignore - -from google.cloud.retail_v2.types import common -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', - }, -) - - -class Product(proto.Message): - r"""Product captures all metadata information of items to be - recommended or searched. - - This message has `oneof`_ fields (mutually exclusive fields). - For each oneof, at most one member field can be set at the same time. - Setting any member of the oneof automatically clears all other - members. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - expire_time (google.protobuf.timestamp_pb2.Timestamp): - The timestamp when this product becomes unavailable for - [SearchService.Search][google.cloud.retail.v2.SearchService.Search]. - - If it is set, the [Product][google.cloud.retail.v2.Product] - is not available for - [SearchService.Search][google.cloud.retail.v2.SearchService.Search] - after - [expire_time][google.cloud.retail.v2.Product.expire_time]. - However, the product can still be retrieved by - [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] - and - [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. - - [expire_time][google.cloud.retail.v2.Product.expire_time] - must be later than - [available_time][google.cloud.retail.v2.Product.available_time] - and - [publish_time][google.cloud.retail.v2.Product.publish_time], - otherwise an INVALID_ARGUMENT error is thrown. - - Google Merchant Center property - `expiration_date `__. - - This field is a member of `oneof`_ ``expiration``. - ttl (google.protobuf.duration_pb2.Duration): - Input only. The TTL (time to live) of the product. - - If it is set, it must be a non-negative value, and - [expire_time][google.cloud.retail.v2.Product.expire_time] is - set as current timestamp plus - [ttl][google.cloud.retail.v2.Product.ttl]. The derived - [expire_time][google.cloud.retail.v2.Product.expire_time] is - returned in the output and - [ttl][google.cloud.retail.v2.Product.ttl] is left blank when - retrieving the [Product][google.cloud.retail.v2.Product]. - - If it is set, the product is not available for - [SearchService.Search][google.cloud.retail.v2.SearchService.Search] - after current timestamp plus - [ttl][google.cloud.retail.v2.Product.ttl]. However, the - product can still be retrieved by - [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] - and - [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. - - This field is a member of `oneof`_ ``expiration``. - name (str): - Immutable. Full resource name of the product, such as - ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/product_id``. - id (str): - Immutable. [Product][google.cloud.retail.v2.Product] - identifier, which is the final component of - [name][google.cloud.retail.v2.Product.name]. For example, - this field is "id_1", if - [name][google.cloud.retail.v2.Product.name] is - ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/id_1``. - - This field 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 - `id `__. - Schema.org Property - `Product.sku `__. - type_ (google.cloud.retail_v2.types.Product.Type): - Immutable. The type of the product. Default to - [Catalog.product_level_config.ingestion_product_type][google.cloud.retail.v2.ProductLevelConfig.ingestion_product_type] - if unset. - primary_product_id (str): - Variant group identifier. Must be an - [id][google.cloud.retail.v2.Product.id], with the same - parent branch with this product. Otherwise, an error is - thrown. - - For - [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] - [Product][google.cloud.retail.v2.Product]s, this field can - only be empty or set to the same value as - [id][google.cloud.retail.v2.Product.id]. - - For VARIANT [Product][google.cloud.retail.v2.Product]s, this - field cannot be empty. A maximum of 2,000 products are - allowed to share the same - [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] - [Product][google.cloud.retail.v2.Product]. Otherwise, an - INVALID_ARGUMENT error is returned. - - Google Merchant Center Property - `item_group_id `__. - 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. - gtin (str): - The Global Trade Item Number (GTIN) of the product. - - This field must be a UTF-8 encoded string with a length - limit of 128 characters. Otherwise, an INVALID_ARGUMENT - error is returned. - - This field must be a Unigram. Otherwise, an INVALID_ARGUMENT - error is returned. - - Google Merchant Center property - `gtin `__. - Schema.org property - `Product.isbn `__ or - `Product.gtin8 `__ or - `Product.gtin12 `__ or - `Product.gtin13 `__ or - `Product.gtin14 `__. - - If the value is not a valid GTIN, an INVALID_ARGUMENT error - is returned. - categories (Sequence[str]): - Product categories. This field is repeated for supporting - one product belonging to several parallel categories. - Strongly recommended using the full path for better search / - recommendation quality. - - To represent full path of category, use '>' sign to separate - different hierarchies. If '>' is part of the category name, - please replace it with other character(s). - - For example, if a shoes product belongs to both ["Shoes & - Accessories" -> "Shoes"] and ["Sports & Fitness" -> - "Athletic Clothing" -> "Shoes"], it could be represented as: - - :: - - "categories": [ - "Shoes & Accessories > Shoes", - "Sports & Fitness > Athletic Clothing > Shoes" - ] - - Must be set for - [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] - [Product][google.cloud.retail.v2.Product] otherwise an - INVALID_ARGUMENT error is returned. - - At most 250 values are allowed per - [Product][google.cloud.retail.v2.Product]. Empty values are - not allowed. Each value must be a UTF-8 encoded string with - a length limit of 5,000 characters. Otherwise, an - INVALID_ARGUMENT error is returned. - - Google Merchant Center property - `google_product_category `__. - Schema.org property [Product.category] - (https://schema.org/category). - title (str): - Required. Product title. - - This field must be a UTF-8 encoded string with a length - limit of 1,000 characters. Otherwise, an INVALID_ARGUMENT - error is returned. - - Google Merchant Center property - `title `__. - Schema.org property - `Product.name `__. - brands (Sequence[str]): - The brands of the product. - - A maximum of 30 brands are allowed. Each brand must be a - UTF-8 encoded string with a length limit of 1,000 - characters. Otherwise, an INVALID_ARGUMENT error is - returned. - - Google Merchant Center property - `brand `__. - Schema.org property - `Product.brand `__. - description (str): - Product description. - - This field must be a UTF-8 encoded string with a length - limit of 5,000 characters. Otherwise, an INVALID_ARGUMENT - error is returned. - - Google Merchant Center property - `description `__. - 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]. - - For product prediction, this field is ignored and the model - automatically detects the text language. The - [Product][google.cloud.retail.v2.Product] can include text - in different languages, but duplicating - [Product][google.cloud.retail.v2.Product]s to provide text - in multiple languages can result in degraded model - performance. - - For product search this field is in use. It defaults to - "en-US" if unset. - attributes (Sequence[google.cloud.retail_v2.types.Product.AttributesEntry]): - Highly encouraged. Extra product attributes to be included. - For example, for products, this could include the store - name, vendor, style, color, etc. These are very strong - signals for recommendation model, thus we highly recommend - providing the attributes here. - - Features that can take on one of a limited number of - possible values. Two types of features can be set are: - - Textual features. some examples would be the brand/maker of - a product, or country of a customer. Numerical features. - Some examples would be the height/weight of a product, or - age of a customer. - - For example: - ``{ "vendor": {"text": ["vendor123", "vendor456"]}, "lengths_cm": {"numbers":[2.3, 15.4]}, "heights_cm": {"numbers":[8.1, 6.4]} }``. - - This field needs to pass all below criteria, otherwise an - INVALID_ARGUMENT error is returned: - - - Max entries count: 200. - - 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. - tags (Sequence[str]): - Custom tags associated with the product. - - At most 250 values are allowed per - [Product][google.cloud.retail.v2.Product]. This value must - be a UTF-8 encoded string with a length limit of 1,000 - characters. Otherwise, an INVALID_ARGUMENT error is - returned. - - This tag can be used for filtering recommendation results by - passing the tag as part of the - [PredictRequest.filter][google.cloud.retail.v2.PredictRequest.filter]. - - 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 - `price `__. - rating (google.cloud.retail_v2.types.Rating): - The rating of this product. - available_time (google.protobuf.timestamp_pb2.Timestamp): - The timestamp when this - [Product][google.cloud.retail.v2.Product] becomes available - for - [SearchService.Search][google.cloud.retail.v2.SearchService.Search]. - availability (google.cloud.retail_v2.types.Product.Availability): - The online availability of the - [Product][google.cloud.retail.v2.Product]. Default to - [Availability.IN_STOCK][google.cloud.retail.v2.Product.Availability.IN_STOCK]. - - Google Merchant Center Property - `availability `__. - Schema.org Property - `Offer.availability `__. - available_quantity (google.protobuf.wrappers_pb2.Int32Value): - The available quantity of the item. - fulfillment_info (Sequence[google.cloud.retail_v2.types.FulfillmentInfo]): - Fulfillment information, such as the store IDs for in-store - pickup or region IDs for different shipping methods. - - All the elements must have distinct - [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type]. - Otherwise, an INVALID_ARGUMENT error is returned. - uri (str): - Canonical URL directly linking to the product detail page. - - It is strongly recommended to provide a valid uri for the - product, otherwise the service performance could be - significantly degraded. - - This field must be a UTF-8 encoded string with a length - limit of 5,000 characters. Otherwise, an INVALID_ARGUMENT - error is returned. - - 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. - - A maximum of 300 images are allowed. - - Google Merchant Center property - `image_link `__. - Schema.org property - `Product.image `__. - audience (google.cloud.retail_v2.types.Audience): - The target group associated with a given - audience (e.g. male, veterans, car owners, - musicians, etc.) of the product. - color_info (google.cloud.retail_v2.types.ColorInfo): - The color of the product. - - Google Merchant Center property - `color `__. - Schema.org property - `Product.color `__. - sizes (Sequence[str]): - The size of the product. To represent different size systems - or size types, consider using this format: - [[[size_system:]size_type:]size_value]. - - For example, in "US:MENS:M", "US" represents size system; - "MENS" represents size type; "M" represents size value. In - "GIRLS:27", size system is empty; "GIRLS" represents size - type; "27" represents size value. In "32 inches", both size - system and size type are empty, while size value is "32 - inches". - - A maximum of 20 values are 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 - `size `__, - `size_type `__ - and - `size_system `__. - Schema.org property - `Product.size `__. - materials (Sequence[str]): - The material of the product. For example, "leather", - "wooden". - - A maximum of 20 values are allowed. Each value must be a - UTF-8 encoded string with a length limit of 128 characters. - Otherwise, an INVALID_ARGUMENT error is returned. - - Google Merchant Center property - `material `__. - Schema.org property - `Product.material `__. - patterns (Sequence[str]): - The pattern or graphic print of the product. For example, - "striped", "polka dot", "paisley". - - A maximum of 20 values are 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 - `pattern `__. - Schema.org property - `Product.pattern `__. - conditions (Sequence[str]): - The condition of the product. Strongly encouraged to use the - standard values: "new", "refurbished", "used". - - A maximum of 5 values are 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 - `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]. - 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 - products. Note that this field is different from - [available_time][google.cloud.retail.v2.Product.available_time], - given it purely describes product freshness regardless of - when it is available on search and recommendation. - retrievable_fields (google.protobuf.field_mask_pb2.FieldMask): - Indicates which fields in the - [Product][google.cloud.retail.v2.Product]s are returned in - [SearchResponse][google.cloud.retail.v2.SearchResponse]. - - Supported fields for all - [type][google.cloud.retail.v2.Product.type]s: - - - [audience][google.cloud.retail.v2.Product.audience] - - [availability][google.cloud.retail.v2.Product.availability] - - [brands][google.cloud.retail.v2.Product.brands] - - [color_info][google.cloud.retail.v2.Product.color_info] - - [conditions][google.cloud.retail.v2.Product.conditions] - - [gtin][google.cloud.retail.v2.Product.gtin] - - [materials][google.cloud.retail.v2.Product.materials] - - [name][google.cloud.retail.v2.Product.name] - - [patterns][google.cloud.retail.v2.Product.patterns] - - [price_info][google.cloud.retail.v2.Product.price_info] - - [rating][google.cloud.retail.v2.Product.rating] - - [sizes][google.cloud.retail.v2.Product.sizes] - - [title][google.cloud.retail.v2.Product.title] - - [uri][google.cloud.retail.v2.Product.uri] - - Supported fields only for - [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] - and - [Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION]: - - - [categories][google.cloud.retail.v2.Product.categories] - - [description][google.cloud.retail.v2.Product.description] - - [images][google.cloud.retail.v2.Product.images] - - Supported fields only for - [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT]: - - - Only the first image in - [images][google.cloud.retail.v2.Product.images] - - To mark - [attributes][google.cloud.retail.v2.Product.attributes] as - retrievable, include paths of the form "attributes.key" - where "key" is the key of a custom attribute, as specified - in [attributes][google.cloud.retail.v2.Product.attributes]. - - For - [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] - and - [Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION], - the following fields are always returned in - [SearchResponse][google.cloud.retail.v2.SearchResponse] by - default: - - - [name][google.cloud.retail.v2.Product.name] - - For - [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT], - the following fields are always returned in by default: - - - [name][google.cloud.retail.v2.Product.name] - - [color_info][google.cloud.retail.v2.Product.color_info] - - Maximum number of paths is 30. Otherwise, an - INVALID_ARGUMENT error is returned. - - Note: Returning more fields in - [SearchResponse][google.cloud.retail.v2.SearchResponse] may - increase response payload size and serving latency. - variants (Sequence[google.cloud.retail_v2.types.Product]): - Output only. Product variants grouped together on primary - product which share similar product attributes. It's - automatically grouped by - [primary_product_id][google.cloud.retail.v2.Product.primary_product_id] - for all the product variants. Only populated for - [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] - [Product][google.cloud.retail.v2.Product]s. - - Note: This field is OUTPUT_ONLY for - [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct]. - Do not set this field in API requests. - """ - class Type(proto.Enum): - r"""The type of this product.""" - TYPE_UNSPECIFIED = 0 - PRIMARY = 1 - VARIANT = 2 - COLLECTION = 3 - - class Availability(proto.Enum): - r"""Product availability. If this field is unspecified, the - product is assumed to be in stock. - """ - AVAILABILITY_UNSPECIFIED = 0 - IN_STOCK = 1 - OUT_OF_STOCK = 2 - PREORDER = 3 - BACKORDER = 4 - - expire_time = proto.Field( - 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, - ) - attributes = proto.MapField( - 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, - ) - available_time = proto.Field( - proto.MESSAGE, - number=18, - message=timestamp_pb2.Timestamp, - ) - availability = proto.Field( - proto.ENUM, - number=19, - enum=Availability, - ) - available_quantity = proto.Field( - 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, - ) - promotions = proto.RepeatedField( - proto.MESSAGE, - number=34, - message=common.Promotion, - ) - publish_time = proto.Field( - proto.MESSAGE, - number=33, - message=timestamp_pb2.Timestamp, - ) - retrievable_fields = proto.Field( - proto.MESSAGE, - number=30, - message=field_mask_pb2.FieldMask, - ) - variants = proto.RepeatedField( - proto.MESSAGE, - number=31, - message='Product', - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/product_service.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/product_service.py deleted file mode 100644 index fb13b40c..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/types/product_service.py +++ /dev/null @@ -1,654 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import proto # type: ignore - -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 - - -__protobuf__ = proto.module( - package='google.cloud.retail.v2', - manifest={ - 'CreateProductRequest', - 'GetProductRequest', - 'UpdateProductRequest', - 'DeleteProductRequest', - 'ListProductsRequest', - 'ListProductsResponse', - 'SetInventoryRequest', - 'SetInventoryMetadata', - 'SetInventoryResponse', - 'AddFulfillmentPlacesRequest', - 'AddFulfillmentPlacesMetadata', - 'AddFulfillmentPlacesResponse', - 'RemoveFulfillmentPlacesRequest', - 'RemoveFulfillmentPlacesMetadata', - 'RemoveFulfillmentPlacesResponse', - }, -) - - -class CreateProductRequest(proto.Message): - r"""Request message for [CreateProduct][] method. - - Attributes: - parent (str): - Required. The parent catalog resource name, such as - ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch``. - product (google.cloud.retail_v2.types.Product): - Required. The [Product][google.cloud.retail.v2.Product] to - create. - product_id (str): - Required. The ID to use for the - [Product][google.cloud.retail.v2.Product], which will become - the final component of the - [Product.name][google.cloud.retail.v2.Product.name]. - - If the caller does not have permission to create the - [Product][google.cloud.retail.v2.Product], regardless of - whether or not it exists, a PERMISSION_DENIED error is - returned. - - This field must be unique among all - [Product][google.cloud.retail.v2.Product]s with the same - [parent][google.cloud.retail.v2.CreateProductRequest.parent]. - Otherwise, an ALREADY_EXISTS error is returned. - - This field must be a UTF-8 encoded string with a length - limit of 128 characters. Otherwise, an INVALID_ARGUMENT - 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, - ) - - -class GetProductRequest(proto.Message): - r"""Request message for [GetProduct][] method. - - Attributes: - name (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. - - If the requested [Product][google.cloud.retail.v2.Product] - does not exist, a NOT_FOUND error is returned. - """ - - name = proto.Field( - proto.STRING, - number=1, - ) - - -class UpdateProductRequest(proto.Message): - r"""Request message for [UpdateProduct][] method. - - Attributes: - product (google.cloud.retail_v2.types.Product): - Required. The product to update/create. - - If the caller does not have permission to update the - [Product][google.cloud.retail.v2.Product], regardless of - whether or not it exists, a PERMISSION_DENIED error is - returned. - - If the [Product][google.cloud.retail.v2.Product] to update - does not exist and - [allow_missing][google.cloud.retail.v2.UpdateProductRequest.allow_missing] - is not set, a NOT_FOUND error is returned. - update_mask (google.protobuf.field_mask_pb2.FieldMask): - Indicates which fields in the provided - [Product][google.cloud.retail.v2.Product] to update. The - immutable and output only fields are NOT supported. If not - set, all supported fields (the fields that are neither - immutable nor output only) are updated. - - If an unsupported or unknown field is provided, an - INVALID_ARGUMENT error is returned. - allow_missing (bool): - If set to true, and the - [Product][google.cloud.retail.v2.Product] is not found, a - new [Product][google.cloud.retail.v2.Product] will be - created. In this situation, ``update_mask`` is ignored. - """ - - product = proto.Field( - proto.MESSAGE, - number=1, - message=gcr_product.Product, - ) - update_mask = proto.Field( - proto.MESSAGE, - number=2, - message=field_mask_pb2.FieldMask, - ) - allow_missing = proto.Field( - proto.BOOL, - number=3, - ) - - -class DeleteProductRequest(proto.Message): - r"""Request message for [DeleteProduct][] method. - - Attributes: - name (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 delete the - [Product][google.cloud.retail.v2.Product], regardless of - whether or not it exists, a PERMISSION_DENIED error is - returned. - - If the [Product][google.cloud.retail.v2.Product] to delete - does not exist, a NOT_FOUND error is returned. - - The [Product][google.cloud.retail.v2.Product] to delete can - neither be a - [Product.Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION] - [Product][google.cloud.retail.v2.Product] member nor a - [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] - [Product][google.cloud.retail.v2.Product] with more than one - [variants][google.cloud.retail.v2.Product.Type.VARIANT]. - Otherwise, an INVALID_ARGUMENT error is returned. - - All inventory information for the named - [Product][google.cloud.retail.v2.Product] will be deleted. - """ - - name = proto.Field( - proto.STRING, - number=1, - ) - - -class ListProductsRequest(proto.Message): - r"""Request message for - [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] - method. - - Attributes: - parent (str): - Required. The parent branch resource name, such as - ``projects/*/locations/global/catalogs/default_catalog/branches/0``. - Use ``default_branch`` as the branch ID, to list products - under the default branch. - - If the caller does not have permission to list - [Product][google.cloud.retail.v2.Product]s under this - branch, regardless of whether or not this branch exists, a - PERMISSION_DENIED error is returned. - page_size (int): - Maximum number of [Product][google.cloud.retail.v2.Product]s - to return. If unspecified, defaults to 100. The maximum - allowed value is 1000. Values above 1000 will be coerced to - 1000. - - If this field is negative, an INVALID_ARGUMENT error is - returned. - page_token (str): - A page token - [ListProductsResponse.next_page_token][google.cloud.retail.v2.ListProductsResponse.next_page_token], - received from a previous - [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] - call. Provide this to retrieve the subsequent page. - - When paginating, all other parameters provided to - [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] - must match the call that provided the page token. Otherwise, - an INVALID_ARGUMENT error is returned. - filter (str): - A filter to apply on the list results. Supported features: - - - List all the products under the parent branch if - [filter][google.cloud.retail.v2.ListProductsRequest.filter] - is unset. - - List - [Product.Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT] - [Product][google.cloud.retail.v2.Product]s sharing the - same - [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] - [Product][google.cloud.retail.v2.Product]. For example: - ``primary_product_id = "some_product_id"`` - - List [Product][google.cloud.retail.v2.Product]s bundled - in a - [Product.Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION] - [Product][google.cloud.retail.v2.Product]. For example: - ``collection_product_id = "some_product_id"`` - - List [Product][google.cloud.retail.v2.Product]s with a - partibular type. For example: ``type = "PRIMARY"`` - ``type = "VARIANT"`` ``type = "COLLECTION"`` - - If the field is unrecognizable, an INVALID_ARGUMENT error is - returned. - - If the specified - [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] - [Product][google.cloud.retail.v2.Product] or - [Product.Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION] - [Product][google.cloud.retail.v2.Product] does not exist, a - NOT_FOUND error is returned. - read_mask (google.protobuf.field_mask_pb2.FieldMask): - The fields of [Product][google.cloud.retail.v2.Product] to - return in the responses. If not set or empty, the following - fields are returned: - - - [Product.name][google.cloud.retail.v2.Product.name] - - [Product.id][google.cloud.retail.v2.Product.id] - - [Product.title][google.cloud.retail.v2.Product.title] - - [Product.uri][google.cloud.retail.v2.Product.uri] - - [Product.images][google.cloud.retail.v2.Product.images] - - [Product.price_info][google.cloud.retail.v2.Product.price_info] - - [Product.brands][google.cloud.retail.v2.Product.brands] - - If "*" is provided, all fields are returned. - [Product.name][google.cloud.retail.v2.Product.name] is - always returned no matter what mask is set. - - If an unsupported or unknown field is provided, 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, - ) - filter = proto.Field( - proto.STRING, - number=4, - ) - read_mask = proto.Field( - proto.MESSAGE, - number=5, - message=field_mask_pb2.FieldMask, - ) - - -class ListProductsResponse(proto.Message): - r"""Response message for - [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] - method. - - Attributes: - products (Sequence[google.cloud.retail_v2.types.Product]): - The [Product][google.cloud.retail.v2.Product]s. - next_page_token (str): - A token that can be sent as - [ListProductsRequest.page_token][google.cloud.retail.v2.ListProductsRequest.page_token] - to retrieve the next page. If this field is omitted, there - are no subsequent pages. - """ - - @property - def raw_page(self): - return self - - products = proto.RepeatedField( - proto.MESSAGE, - number=1, - message=gcr_product.Product, - ) - next_page_token = proto.Field( - proto.STRING, - number=2, - ) - - -class SetInventoryRequest(proto.Message): - r"""Request message for [SetInventory][] method. - - Attributes: - inventory (google.cloud.retail_v2.types.Product): - Required. The inventory information to update. The allowable - fields to update are: - - - [Product.price_info][google.cloud.retail.v2.Product.price_info] - - [Product.availability][google.cloud.retail.v2.Product.availability] - - [Product.available_quantity][google.cloud.retail.v2.Product.available_quantity] - - [Product.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] - The updated inventory fields must be specified in - [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask]. - - If [SetInventoryRequest.inventory.name][] is empty or - invalid, an INVALID_ARGUMENT error is returned. - - If the caller does not have permission to update the - [Product][google.cloud.retail.v2.Product] named in - [Product.name][google.cloud.retail.v2.Product.name], - regardless of whether or not it exists, a PERMISSION_DENIED - error is returned. - - If the [Product][google.cloud.retail.v2.Product] to update - does not have existing inventory information, the provided - inventory information will be inserted. - - If the [Product][google.cloud.retail.v2.Product] to update - has existing inventory information, the provided inventory - information will be merged while respecting the last update - time for each inventory field, using the provided or default - value for - [SetInventoryRequest.set_time][google.cloud.retail.v2.SetInventoryRequest.set_time]. - - The last update time is recorded for the following inventory - fields: - - - [Product.price_info][google.cloud.retail.v2.Product.price_info] - - [Product.availability][google.cloud.retail.v2.Product.availability] - - [Product.available_quantity][google.cloud.retail.v2.Product.available_quantity] - - [Product.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] - - If a full overwrite of inventory information while ignoring - timestamps is needed, [UpdateProduct][] should be invoked - 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. - - If an unsupported or unknown field is provided, an - INVALID_ARGUMENT error is returned and the entire update - will be ignored. - set_time (google.protobuf.timestamp_pb2.Timestamp): - The time when the request is issued, used to - prevent out-of-order updates on inventory fields - with the last update time recorded. 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] with name - [Product.name][google.cloud.retail.v2.Product.name] is not - found, the inventory update will still be processed and - retained for at most 1 day until 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. - """ - - 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): - r"""Metadata related to the progress of the SetInventory operation. - Currently empty because there is no meaningful metadata populated - from the [SetInventory][] method. - - """ - - -class SetInventoryResponse(proto.Message): - r"""Response of the SetInventoryRequest. Currently empty because there - is no meaningful response populated from the [SetInventory][] - method. - - """ - - -class AddFulfillmentPlacesRequest(proto.Message): - r"""Request message for [AddFulfillmentPlaces][] 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. - type_ (str): - Required. The fulfillment type, including commonly used - types (such as pickup in store and same day delivery), and - custom types. - - 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. - - This field directly corresponds to - [Product.fulfillment_info.type][]. - place_ids (Sequence[str]): - Required. The IDs for this - [type][google.cloud.retail.v2.AddFulfillmentPlacesRequest.type], - such as the store IDs for "pickup-in-store" or the region - IDs for "same-day-delivery" to be added for this - [type][google.cloud.retail.v2.AddFulfillmentPlacesRequest.type]. - Duplicate IDs will be automatically ignored. - - At least 1 value is required, and a maximum of 2000 values - are allowed. Each value must be a string with a length limit - of 10 characters, matching the pattern ``[a-zA-Z0-9_-]+``, - such as "store1" or "REGION-2". Otherwise, an - INVALID_ARGUMENT error is returned. - - If the total number of place IDs exceeds 2000 for this - [type][google.cloud.retail.v2.AddFulfillmentPlacesRequest.type] - after adding, then the update will be rejected. - add_time (google.protobuf.timestamp_pb2.Timestamp): - The time when the fulfillment updates are - issued, used to prevent out-of-order updates on - fulfillment information. 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 - fulfillment information 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, - ) - 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): - r"""Metadata related to the progress of the AddFulfillmentPlaces - operation. Currently empty because there is no meaningful metadata - populated from the [AddFulfillmentPlaces][] method. - - """ - - -class AddFulfillmentPlacesResponse(proto.Message): - r"""Response of the AddFulfillmentPlacesRequest. Currently empty because - there is no meaningful response populated from the - [AddFulfillmentPlaces][] method. - - """ - - -class RemoveFulfillmentPlacesRequest(proto.Message): - r"""Request message for [RemoveFulfillmentPlaces][] 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. - type_ (str): - Required. The fulfillment type, including commonly used - types (such as pickup in store and same day delivery), and - custom types. - - 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. - - This field directly corresponds to - [Product.fulfillment_info.type][]. - place_ids (Sequence[str]): - Required. The IDs for this - [type][google.cloud.retail.v2.RemoveFulfillmentPlacesRequest.type], - such as the store IDs for "pickup-in-store" or the region - IDs for "same-day-delivery", to be removed for this - [type][google.cloud.retail.v2.RemoveFulfillmentPlacesRequest.type]. - - At least 1 value is required, and a maximum of 2000 values - are allowed. Each value must be a string with a length limit - of 10 characters, matching the pattern ``[a-zA-Z0-9_-]+``, - such as "store1" or "REGION-2". Otherwise, an - INVALID_ARGUMENT error is returned. - remove_time (google.protobuf.timestamp_pb2.Timestamp): - The time when the fulfillment updates are - issued, used to prevent out-of-order updates on - fulfillment information. 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 - fulfillment information 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, - ) - 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): - r"""Metadata related to the progress of the RemoveFulfillmentPlaces - operation. Currently empty because there is no meaningful metadata - populated from the [RemoveFulfillmentPlaces][] method. - - """ - - -class RemoveFulfillmentPlacesResponse(proto.Message): - r"""Response of the RemoveFulfillmentPlacesRequest. Currently empty - because there is no meaningful response populated from the - [RemoveFulfillmentPlaces][] method. - - """ - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/purge_config.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/purge_config.py deleted file mode 100644 index 6c88638c..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/types/purge_config.py +++ /dev/null @@ -1,107 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import proto # type: ignore - - -__protobuf__ = proto.module( - package='google.cloud.retail.v2', - manifest={ - 'PurgeMetadata', - 'PurgeUserEventsRequest', - 'PurgeUserEventsResponse', - }, -) - - -class PurgeMetadata(proto.Message): - r"""Metadata related to the progress of the Purge operation. - This will be returned by the - google.longrunning.Operation.metadata field. - - """ - - -class PurgeUserEventsRequest(proto.Message): - r"""Request message for PurgeUserEvents method. - - Attributes: - parent (str): - Required. The resource name of the catalog under which the - events are created. The format is - ``projects/${projectId}/locations/global/catalogs/${catalogId}`` - filter (str): - Required. The filter string to specify the events to be - deleted with a length limit of 5,000 characters. Empty - string filter is not allowed. The eligible fields for - filtering are: - - - ``eventType``: Double quoted - [UserEvent.event_type][google.cloud.retail.v2.UserEvent.event_type] - string. - - ``eventTime``: in ISO 8601 "zulu" format. - - ``visitorId``: Double quoted string. Specifying this will - delete all events associated with a visitor. - - ``userId``: Double quoted string. Specifying this will - delete all events associated with a user. - - Examples: - - - Deleting all events in a time range: - ``eventTime > "2012-04-23T18:25:43.511Z" eventTime < "2012-04-23T18:30:43.511Z"`` - - Deleting specific eventType in time range: - ``eventTime > "2012-04-23T18:25:43.511Z" eventType = "detail-page-view"`` - - Deleting all events for a specific visitor: - ``visitorId = "visitor1024"`` - - The filtering fields are assumed to have an implicit AND. - force (bool): - Actually perform the purge. If ``force`` is set to false, - the method will return the expected purge count without - 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, - ) - - -class PurgeUserEventsResponse(proto.Message): - r"""Response of the PurgeUserEventsRequest. If the long running - operation is successfully done, then this message is returned by - the google.longrunning.Operations.response field. - - Attributes: - purged_events_count (int): - The total count of events purged as a result - of the operation. - """ - - purged_events_count = proto.Field( - proto.INT64, - number=1, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/search_service.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/search_service.py deleted file mode 100644 index 7e2664f0..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/types/search_service.py +++ /dev/null @@ -1,1001 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -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 struct_pb2 # type: ignore - - -__protobuf__ = proto.module( - package='google.cloud.retail.v2', - manifest={ - 'SearchRequest', - 'SearchResponse', - }, -) - - -class SearchRequest(proto.Message): - r"""Request message for - [SearchService.Search][google.cloud.retail.v2.SearchService.Search] - method. - - Attributes: - placement (str): - Required. The resource name of the search engine placement, - such as - ``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. - branch (str): - The branch resource name, such as - ``projects/*/locations/global/catalogs/default_catalog/branches/0``. - - Use "default_branch" as the branch ID or leave this field - empty, to search products under the default branch. - query (str): - Raw search query. - visitor_id (str): - Required. 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. - user_info (google.cloud.retail_v2.types.UserInfo): - User information. - page_size (int): - Maximum number of [Product][google.cloud.retail.v2.Product]s - to return. If unspecified, defaults to a reasonable value. - The maximum allowed value is 120. Values above 120 will be - coerced to 120. - - If this field is negative, an INVALID_ARGUMENT is returned. - page_token (str): - A page token - [SearchResponse.next_page_token][google.cloud.retail.v2.SearchResponse.next_page_token], - received from a previous - [SearchService.Search][google.cloud.retail.v2.SearchService.Search] - call. Provide this to retrieve the subsequent page. - - When paginating, all other parameters provided to - [SearchService.Search][google.cloud.retail.v2.SearchService.Search] - must match the call that provided the page token. Otherwise, - an INVALID_ARGUMENT error is returned. - offset (int): - A 0-indexed integer that specifies the current offset (that - is, starting result location, amongst the - [Product][google.cloud.retail.v2.Product]s deemed by the API - as relevant) in search results. This field is only - considered if - [page_token][google.cloud.retail.v2.SearchRequest.page_token] - is unset. - - If this field is negative, an INVALID_ARGUMENT is returned. - filter (str): - The filter syntax consists of an expression language for - constructing a predicate from one or more fields of the - products being filtered. Filter expression is - case-sensitive. See more details at this `user - guide `__. - - If this field is unrecognizable, an INVALID_ARGUMENT is - returned. - canonical_filter (str): - 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 - with - [SearchRequest.canonical_filter][google.cloud.retail.v2.SearchRequest.canonical_filter] - will be returned as a supplement of the original query. This - field is strongly recommended to achieve high search - quality. - - See - [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter] - for more details about filter syntax. - order_by (str): - The order in which products are returned. Products can be - ordered by a field in an - [Product][google.cloud.retail.v2.Product] object. Leave it - unset if ordered by relevance. OrderBy expression is - case-sensitive. See more details at this `user - guide `__. - - If this field is unrecognizable, an INVALID_ARGUMENT is - returned. - facet_specs (Sequence[google.cloud.retail_v2.types.SearchRequest.FacetSpec]): - Facet specifications for faceted search. If empty, no facets - are returned. - - A maximum of 100 values are allowed. Otherwise, an - INVALID_ARGUMENT error is returned. - dynamic_facet_spec (google.cloud.retail_v2.types.SearchRequest.DynamicFacetSpec): - 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 - guide `__. - - Notice that if both [ServingConfig.boost_control_ids][] and - [SearchRequest.boost_spec] are set, the boost conditions - from both places are evaluated. If a search request matches - multiple boost conditions, the final boost score is equal to - the sum of the boost scores from all matched boost - conditions. - query_expansion_spec (google.cloud.retail_v2.types.SearchRequest.QueryExpansionSpec): - The query expansion specification that specifies the - conditions under which query expansion will occur. See more - details at this `user - guide `__. - 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 - [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. - - For - [FulfillmentInfo][google.cloud.retail.v2.FulfillmentInfo], a - fulfillment type and a fulfillment ID must be provided in - the format of "fulfillmentType.fulfillmentId". E.g., in - "pickupInStore.store123", "pickupInStore" is fulfillment - type and "store123" is the store ID. - - Supported keys are: - - - colorFamilies - - price - - originalPrice - - discount - - variantId - - inventory(place_id,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 - [Product.attributes][google.cloud.retail.v2.Product.attributes] - map. - - pickupInStore.id, where id is any - [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] - for - [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] - "pickup-in-store". - - shipToStore.id, where id is any - [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] - for - [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] - "ship-to-store". - - sameDayDelivery.id, where id is any - [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] - for - [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] - "same-day-delivery". - - nextDayDelivery.id, where id is any - [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] - for - [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] - "next-day-delivery". - - customFulfillment1.id, where id is any - [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] - for - [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] - "custom-type-1". - - customFulfillment2.id, where id is any - [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] - for - [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] - "custom-type-2". - - customFulfillment3.id, where id is any - [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] - for - [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] - "custom-type-3". - - customFulfillment4.id, where id is any - [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] - for - [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] - "custom-type-4". - - customFulfillment5.id, where id is any - [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] - for - [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] - "custom-type-5". - - If this field is set to an invalid value other than these, - an INVALID_ARGUMENT error is returned. - page_categories (Sequence[str]): - The categories associated with a category page. Required for - category navigation queries to achieve good search quality. - The format should be the same as - [UserEvent.page_categories][google.cloud.retail.v2.UserEvent.page_categories]; - - To represent full path of category, use '>' sign to separate - different hierarchies. If '>' is part of the category name, - please replace it with other character(s). - - Category pages include special pages such as sales or - promotions. For instance, a special sale page may have the - category hierarchy: "pageCategories" : ["Sales > 2017 Black - Friday Deals"]. - search_mode (google.cloud.retail_v2.types.SearchRequest.SearchMode): - The search mode of the search request. If not - specified, a single search request triggers both - product search and faceted search. - """ - class SearchMode(proto.Enum): - r"""The search mode of each search request.""" - SEARCH_MODE_UNSPECIFIED = 0 - PRODUCT_SEARCH_ONLY = 1 - FACETED_SEARCH_ONLY = 2 - - class FacetSpec(proto.Message): - r"""A facet specification to perform faceted search. - - Attributes: - facet_key (google.cloud.retail_v2.types.SearchRequest.FacetSpec.FacetKey): - Required. The facet key specification. - limit (int): - Maximum of facet values that should be returned for this - facet. If unspecified, defaults to 20. The maximum allowed - value is 300. Values above 300 will be coerced to 300. - - If this field is negative, an INVALID_ARGUMENT is returned. - excluded_filter_keys (Sequence[str]): - List of keys to exclude when faceting. - - By default, - [FacetKey.key][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key] - is not excluded from the filter unless it is listed in this - field. - - For example, suppose there are 100 products with color facet - "Red" and 200 products with color facet "Blue". A query - containing the filter "colorFamilies:ANY("Red")" and have - "colorFamilies" as - [FacetKey.key][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key] - will by default return the "Red" with count 100. - - If this field contains "colorFamilies", then the query - returns both the "Red" with count 100 and "Blue" with count - 200, because the "colorFamilies" key is now excluded from - the filter. - - A maximum of 100 values are allowed. Otherwise, an - INVALID_ARGUMENT error is returned. - enable_dynamic_position (bool): - Enables dynamic position for this facet. If set to true, the - position of this facet among all facets in the response is - determined by Google Retail Search. It will be ordered - together with dynamic facets if dynamic facets is enabled. - If set to false, the position of this facet in the response - will be the same as in the request, and it will be ranked - before the facets with dynamic position enable and all - dynamic facets. - - For example, you may always want to have rating facet - returned in the response, but it's not necessarily to always - display the rating facet at the top. In that case, you can - set enable_dynamic_position to true so that the position of - rating facet in response will be determined by Google Retail - Search. - - Another example, assuming you have the following facets in - the request: - - - "rating", enable_dynamic_position = true - - - "price", enable_dynamic_position = false - - - "brands", enable_dynamic_position = false - - And also you have a dynamic facets enable, which will - generate a facet 'gender'. Then the final order of the - facets in the response can be ("price", "brands", "rating", - "gender") or ("price", "brands", "gender", "rating") depends - on how Google Retail Search orders "gender" and "rating" - facets. However, notice that "price" and "brands" will - always be ranked at 1st and 2nd position since their - enable_dynamic_position are false. - """ - - class FacetKey(proto.Message): - r"""Specifies how a facet is computed. - - Attributes: - key (str): - Required. Supported textual and numerical facet keys in - [Product][google.cloud.retail.v2.Product] object, over which - the facet values are computed. Facet key is case-sensitive. - - Allowed facet keys when - [FacetKey.query][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.query] - is not specified: - - - textual_field = - - - "brands" - - "categories" - - "genders" - - "ageGroups" - - "availability" - - "colorFamilies" - - "colors" - - "sizes" - - "materials" - - "patterns" - - "conditions" - - "attributes.key" - - "pickupInStore" - - "shipToStore" - - "sameDayDelivery" - - "nextDayDelivery" - - "customFulfillment1" - - "customFulfillment2" - - "customFulfillment3" - - "customFulfillment4" - - "customFulfillment5" - - "inventory(place_id,attributes.key)" - - - numerical_field = - - - "price" - - "discount" - - "rating" - - "ratingCount" - - "attributes.key" - - "inventory(place_id,price)" - - "inventory(place_id,attributes.key)". - intervals (Sequence[google.cloud.retail_v2.types.Interval]): - Set only if values should be bucketized into - intervals. Must be set for facets with numerical - values. Must not be set for facet with text - values. Maximum number of intervals is 30. - restricted_values (Sequence[str]): - Only get facet for the given restricted values. For example, - when using "pickupInStore" as key and set restricted values - to ["store123", "store456"], only facets for "store123" and - "store456" are returned. Only supported on textual fields - and fulfillments. Maximum is 20. - - Must be set for the fulfillment facet keys: - - - pickupInStore - - - shipToStore - - - sameDayDelivery - - - nextDayDelivery - - - customFulfillment1 - - - customFulfillment2 - - - customFulfillment3 - - - customFulfillment4 - - - customFulfillment5 - prefixes (Sequence[str]): - Only get facet values that start with the - given string prefix. For example, suppose - "categories" has three values "Women > Shoe", - "Women > Dress" and "Men > Shoe". If set - "prefixes" to "Women", the "categories" facet - will give only "Women > Shoe" and "Women > - Dress". Only supported on textual fields. - Maximum is 10. - contains (Sequence[str]): - Only get facet values that contains the given - strings. For example, suppose "categories" has - three values "Women > Shoe", "Women > Dress" and - "Men > Shoe". If set "contains" to "Shoe", the - "categories" facet will give only "Women > Shoe" - and "Men > Shoe". Only supported on textual - fields. Maximum is 10. - order_by (str): - The order in which [Facet.values][] are returned. - - Allowed values are: - - - "count desc", which means order by - [Facet.FacetValue.count][] descending. - - - "value desc", which means order by - [Facet.FacetValue.value][] descending. Only applies to - textual facets. - - If not set, textual values are sorted in `natural - order `__; - numerical intervals are sorted in the order given by - [FacetSpec.FacetKey.intervals][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.intervals]; - [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] - are sorted in the order given by - [FacetSpec.FacetKey.restricted_values][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.restricted_values]. - query (str): - The query that is used to compute facet for the given facet - key. When provided, it will override the default behavior of - facet computation. The query syntax is the same as a filter - expression. See - [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter] - for detail syntax and limitations. Notice that there is no - limitation on - [FacetKey.key][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key] - when query is specified. - - In the response, [FacetValue.value][] will be always "1" and - [FacetValue.count][] will be the number of results that - matches the query. - - For example, you can set a customized facet for - "shipToStore", where - [FacetKey.key][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key] - is "customizedShipToStore", and - [FacetKey.query][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.query] - is "availability: ANY("IN_STOCK") AND shipToStore: - ANY("123")". Then the facet will count the products that are - both in stock and ship to store "123". - """ - - key = proto.Field( - proto.STRING, - number=1, - ) - intervals = proto.RepeatedField( - 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, - ) - - facet_key = proto.Field( - 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, - ) - - class DynamicFacetSpec(proto.Message): - r"""The specifications of dynamically generated facets. - - Attributes: - mode (google.cloud.retail_v2.types.SearchRequest.DynamicFacetSpec.Mode): - Mode of the DynamicFacet feature. Defaults to - [Mode.DISABLED][google.cloud.retail.v2.SearchRequest.DynamicFacetSpec.Mode.DISABLED] - if it's unset. - """ - class Mode(proto.Enum): - r"""Enum to control DynamicFacet mode""" - MODE_UNSPECIFIED = 0 - DISABLED = 1 - ENABLED = 2 - - mode = proto.Field( - proto.ENUM, - number=1, - enum='SearchRequest.DynamicFacetSpec.Mode', - ) - - class BoostSpec(proto.Message): - r"""Boost specification to boost certain items. - - Attributes: - condition_boost_specs (Sequence[google.cloud.retail_v2.types.SearchRequest.BoostSpec.ConditionBoostSpec]): - Condition boost specifications. If a product - matches multiple conditions in the - specifictions, boost scores from these - specifications are all applied and combined in a - non-linear way. Maximum number of specifications - is 10. - """ - - class ConditionBoostSpec(proto.Message): - r"""Boost applies to products which match a condition. - - Attributes: - condition (str): - An expression which specifies a boost condition. The syntax - and supported fields are the same as a filter expression. - See - [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter] - for detail syntax and limitations. - - Examples: - - - To boost products with product ID "product_1" or - "product_2", and color "Red" or "Blue": - - - (id: ANY("product_1", "product_2")) AND - (colorFamilies: ANY("Red","Blue")) - boost (float): - Strength of the condition boost, which should be in [-1, 1]. - Negative boost means demotion. Default is 0.0. - - Setting to 1.0 gives the item a big promotion. However, it - does not necessarily mean that the boosted item will be the - top result at all times, nor that other items will be - excluded. Results could still be shown even when none of - them matches the condition. And results that are - significantly more relevant to the search query can still - trump your heavily favored but irrelevant items. - - Setting to -1.0 gives the item a big demotion. However, - results that are deeply relevant might still be shown. The - item will have an upstream battle to get a fairly high - ranking, but it is not blocked out completely. - - Setting to 0.0 means no boost applied. The boosting - condition is ignored. - """ - - 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', - ) - - class QueryExpansionSpec(proto.Message): - r"""Specification to determine under which conditions query - expansion should occur. - - Attributes: - condition (google.cloud.retail_v2.types.SearchRequest.QueryExpansionSpec.Condition): - The condition under which query expansion should occur. - Default to - [Condition.DISABLED][google.cloud.retail.v2.SearchRequest.QueryExpansionSpec.Condition.DISABLED]. - pin_unexpanded_results (bool): - Whether to pin unexpanded results. If this - field is set to true, unexpanded products are - always at the top of the search results, - followed by the expanded results. - """ - class Condition(proto.Enum): - r"""Enum describing under which condition query expansion should - occur. - """ - CONDITION_UNSPECIFIED = 0 - DISABLED = 1 - AUTO = 3 - - condition = proto.Field( - 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, - ) - dynamic_facet_spec = proto.Field( - proto.MESSAGE, - number=21, - message=DynamicFacetSpec, - ) - boost_spec = proto.Field( - proto.MESSAGE, - number=13, - message=BoostSpec, - ) - query_expansion_spec = proto.Field( - 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, - ) - - -class SearchResponse(proto.Message): - r"""Response message for - [SearchService.Search][google.cloud.retail.v2.SearchService.Search] - method. - - Attributes: - results (Sequence[google.cloud.retail_v2.types.SearchResponse.SearchResult]): - A list of matched items. The order represents - the ranking. - facets (Sequence[google.cloud.retail_v2.types.SearchResponse.Facet]): - Results of facets requested by user. - total_size (int): - The estimated total count of matched items irrespective of - pagination. The count of - [results][google.cloud.retail.v2.SearchResponse.results] - returned by pagination may be less than the - [total_size][google.cloud.retail.v2.SearchResponse.total_size] - that matches. - corrected_query (str): - If spell correction applies, the corrected - query. Otherwise, empty. - attribution_token (str): - A unique search token. This should be included in the - [UserEvent][google.cloud.retail.v2.UserEvent] logs resulting - from this search, which enables accurate attribution of - search model performance. - next_page_token (str): - A token that can be sent as - [SearchRequest.page_token][google.cloud.retail.v2.SearchRequest.page_token] - to retrieve the next page. If this field is omitted, there - are no subsequent pages. - query_expansion_info (google.cloud.retail_v2.types.SearchResponse.QueryExpansionInfo): - Query expansion information for the returned - results. - redirect_uri (str): - The URI of a customer-defined redirect page. If redirect - action is triggered, no search will be performed, and only - [redirect_uri][google.cloud.retail.v2.SearchResponse.redirect_uri] - and - [attribution_token][google.cloud.retail.v2.SearchResponse.attribution_token] - will be set in the response. - """ - - class SearchResult(proto.Message): - r"""Represents the search results. - - Attributes: - id (str): - [Product.id][google.cloud.retail.v2.Product.id] of the - searched [Product][google.cloud.retail.v2.Product]. - product (google.cloud.retail_v2.types.Product): - The product data snippet in the search response. Only - [Product.name][google.cloud.retail.v2.Product.name] is - guaranteed to be populated. - - [Product.variants][google.cloud.retail.v2.Product.variants] - contains the product variants that match the search query. - If there are multiple product variants matching the query, - top 5 most relevant product variants are returned and - ordered by relevancy. - - If relevancy can be deternmined, use - [matching_variant_fields][google.cloud.retail.v2.SearchResponse.SearchResult.matching_variant_fields] - to look up matched product variants fields. If relevancy - cannot be determined, e.g. when searching "shoe" all - products in a shoe product can be a match, 5 product - variants are returned but order is meaningless. - matching_variant_count (int): - The count of matched - [variant][google.cloud.retail.v2.Product.Type.VARIANT] - [Product][google.cloud.retail.v2.Product]s. - matching_variant_fields (Sequence[google.cloud.retail_v2.types.SearchResponse.SearchResult.MatchingVariantFieldsEntry]): - If a [variant][google.cloud.retail.v2.Product.Type.VARIANT] - [Product][google.cloud.retail.v2.Product] matches the search - query, this map indicates which - [Product][google.cloud.retail.v2.Product] fields are - matched. The key is the - [Product.name][google.cloud.retail.v2.Product.name], the - value is a field mask of the matched - [Product][google.cloud.retail.v2.Product] fields. If matched - attributes cannot be determined, this map will be empty. - - For example, a key "sku1" with field mask - "products.color_info" indicates there is a match between - "sku1" [ColorInfo][google.cloud.retail.v2.ColorInfo] and the - query. - variant_rollup_values (Sequence[google.cloud.retail_v2.types.SearchResponse.SearchResult.VariantRollupValuesEntry]): - The rollup matching - [variant][google.cloud.retail.v2.Product.Type.VARIANT] - [Product][google.cloud.retail.v2.Product] attributes. The - key is one of the - [SearchRequest.variant_rollup_keys][google.cloud.retail.v2.SearchRequest.variant_rollup_keys]. - The values are the merged and de-duplicated - [Product][google.cloud.retail.v2.Product] attributes. Notice - that the rollup values are respect filter. For example, when - filtering by "colorFamilies:ANY("red")" and rollup - "colorFamilies", only "red" is returned. - - For textual and numerical attributes, the rollup values is a - list of string or double values with type - [google.protobuf.ListValue][google.protobuf.ListValue]. For - example, if there are two variants with colors "red" and - "blue", the rollup values are - - :: - - { key: "colorFamilies" - value { - list_value { - values { string_value: "red" } - values { string_value: "blue" } - } - } - } - - For - [FulfillmentInfo][google.cloud.retail.v2.FulfillmentInfo], - the rollup values is a double value with type - [google.protobuf.Value][google.protobuf.Value]. For example, - ``{key: "pickupInStore.store1" value { number_value: 10 }}`` - means a there are 10 variants in this product are available - 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, - ) - matching_variant_fields = proto.MapField( - 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, - ) - - class Facet(proto.Message): - r"""A facet result. - - Attributes: - key (str): - The key for this facet. E.g., "colorFamilies" - or "price" or "attributes.attr1". - values (Sequence[google.cloud.retail_v2.types.SearchResponse.Facet.FacetValue]): - The facet values for this field. - dynamic_facet (bool): - Whether the facet is dynamically generated. - """ - - class FacetValue(proto.Message): - r"""A facet value which contains value names and their count. - - This message has `oneof`_ fields (mutually exclusive fields). - For each oneof, at most one member field can be set at the same time. - Setting any member of the oneof automatically clears all other - members. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - value (str): - Text value of a facet, such as "Black" for - facet "colorFamilies". - - This field is a member of `oneof`_ ``facet_value``. - interval (google.cloud.retail_v2.types.Interval): - Interval value for a facet, such as [10, 20) for facet - "price". - - This field is a member of `oneof`_ ``facet_value``. - count (int): - Number of items that have this 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, - ) - count = proto.Field( - proto.INT64, - number=3, - ) - - key = proto.Field( - proto.STRING, - number=1, - ) - values = proto.RepeatedField( - proto.MESSAGE, - number=2, - message='SearchResponse.Facet.FacetValue', - ) - dynamic_facet = proto.Field( - proto.BOOL, - number=3, - ) - - class QueryExpansionInfo(proto.Message): - r"""Information describing query expansion including whether - expansion has occurred. - - Attributes: - expanded_query (bool): - Bool describing whether query expansion has - occurred. - pinned_result_count (int): - Number of pinned results. This field will only be set when - expansion happens and - [SearchRequest.QueryExpansionSpec.pin_unexpanded_results][google.cloud.retail.v2.SearchRequest.QueryExpansionSpec.pin_unexpanded_results] - is set to true. - """ - - 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, - ) - query_expansion_info = proto.Field( - proto.MESSAGE, - number=7, - message=QueryExpansionInfo, - ) - redirect_uri = proto.Field( - proto.STRING, - number=10, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/user_event.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/user_event.py deleted file mode 100644 index 8d9faa33..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/types/user_event.py +++ /dev/null @@ -1,492 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -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 timestamp_pb2 # type: ignore -from google.protobuf import wrappers_pb2 # type: ignore - - -__protobuf__ = proto.module( - package='google.cloud.retail.v2', - manifest={ - 'UserEvent', - 'ProductDetail', - 'CompletionDetail', - 'PurchaseTransaction', - }, -) - - -class UserEvent(proto.Message): - r"""UserEvent captures all metadata information Retail API needs - to know about how end users interact with customers' website. - - Attributes: - event_type (str): - Required. User event type. Allowed values are: - - - ``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. - - ``promotion-not-offered``: Promotion is not offered to a - user. - - ``purchase-complete``: User finishing a purchase. - - ``search``: Product search. - - ``shopping-cart-page-view``: User viewing a shopping - cart. - visitor_id (str): - Required. 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 log in/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. - - The field should not contain PII or user-data. We recommend - to use Google Analystics `Client - ID `__ - for this field. - session_id (str): - A unique identifier for tracking a visitor session with a - length limit of 128 bytes. A session is an aggregation of an - end user behavior in a time span. - - A general guideline to populate the sesion_id: - - 1. If user has no activity for 30 min, a new session_id - should be assigned. - 2. The session_id should be unique across users, suggest use - uuid or add visitor_id as prefix. - event_time (google.protobuf.timestamp_pb2.Timestamp): - Only required for - [UserEventService.ImportUserEvents][google.cloud.retail.v2.UserEventService.ImportUserEvents] - method. Timestamp of when the user event happened. - experiment_ids (Sequence[str]): - A list of identifiers for the independent - experiment groups this user event belongs to. - This is used to distinguish between user events - associated with different experiment setups - (e.g. using Retail API, using different - recommendation models). - attribution_token (str): - Highly recommended for user events that are the result of - [PredictionService.Predict][google.cloud.retail.v2.PredictionService.Predict]. - This field enables accurate attribution of recommendation - model performance. - - The value must be a valid - [PredictResponse.attribution_token][google.cloud.retail.v2.PredictResponse.attribution_token] - for user events that are the result of - [PredictionService.Predict][google.cloud.retail.v2.PredictionService.Predict]. - The value must be a valid - [SearchResponse.attribution_token][google.cloud.retail.v2.SearchResponse.attribution_token] - for user events that are the result of - [SearchService.Search][google.cloud.retail.v2.SearchService.Search]. - - This token enables us to accurately attribute page view or - purchase back to the event and the particular predict - response containing this clicked/purchased product. If user - clicks on product K in the recommendation results, pass - [PredictResponse.attribution_token][google.cloud.retail.v2.PredictResponse.attribution_token] - as a URL parameter to product K's page. When recording - events on product K's page, log the - [PredictResponse.attribution_token][google.cloud.retail.v2.PredictResponse.attribution_token] - to this field. - product_details (Sequence[google.cloud.retail_v2.types.ProductDetail]): - The main product details related to the event. - - This field is required for the following event types: - - - ``add-to-cart`` - - ``detail-page-view`` - - ``purchase-complete`` - - In a ``search`` event, this field represents the products - returned to the end user on the current page (the end user - may have not finished browsing the whole page yet). When a - new page is returned to the end user, after - pagination/filtering/ordering even for the same query, a new - ``search`` event with different - [product_details][google.cloud.retail.v2.UserEvent.product_details] - 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. - - 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. - 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. - 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 - cart before purchase. - - This can only be set for ``add-to-cart``, - ``purchase-complete``, or ``shopping-cart-page-view`` - events. - purchase_transaction (google.cloud.retail_v2.types.PurchaseTransaction): - A transaction represents the entire purchase transaction. - - Required for ``purchase-complete`` events. Other event types - should not set this field. Otherwise, an INVALID_ARGUMENT - error is returned. - search_query (str): - The user's search query. - - See - [SearchRequest.query][google.cloud.retail.v2.SearchRequest.query] - for definition. - - The value must be a UTF-8 encoded string with a length limit - of 5,000 characters. Otherwise, an INVALID_ARGUMENT error is - returned. - - At least one of - [search_query][google.cloud.retail.v2.UserEvent.search_query] - or - [page_categories][google.cloud.retail.v2.UserEvent.page_categories] - is required for ``search`` events. Other event types should - not set this field. Otherwise, an INVALID_ARGUMENT error is - returned. - filter (str): - The filter syntax consists of an expression language for - constructing a predicate from one or more fields of the - products being filtered. - - See - [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter] - for definition and syntax. - - The value must be a UTF-8 encoded string with a length limit - of 1,000 characters. Otherwise, an INVALID_ARGUMENT error is - returned. - order_by (str): - The order in which products are returned. - - See - [SearchRequest.order_by][google.cloud.retail.v2.SearchRequest.order_by] - for definition and syntax. - - The value must be a UTF-8 encoded string with a length limit - of 1,000 characters. Otherwise, an INVALID_ARGUMENT error is - returned. - - This can only be set for ``search`` events. Other event - types should not set this field. Otherwise, an - INVALID_ARGUMENT error is returned. - offset (int): - An integer that specifies the current offset for pagination - (the 0-indexed starting location, amongst the products - deemed by the API as relevant). - - See - [SearchRequest.offset][google.cloud.retail.v2.SearchRequest.offset] - for definition. - - If this field is negative, an INVALID_ARGUMENT is returned. - - This can only be set for ``search`` events. Other event - types should not set this field. Otherwise, an - INVALID_ARGUMENT error is returned. - page_categories (Sequence[str]): - The categories associated with a category page. - - To represent full path of category, use '>' sign to separate - different hierarchies. If '>' is part of the category name, - please replace it with other character(s). - - Category pages include special pages such as sales or - promotions. For instance, a special sale page may have the - category hierarchy: "pageCategories" : ["Sales > 2017 Black - Friday Deals"]. - - Required for ``category-page-view`` events. At least one of - [search_query][google.cloud.retail.v2.UserEvent.search_query] - or - [page_categories][google.cloud.retail.v2.UserEvent.page_categories] - is required for ``search`` events. Other event types should - not set this field. Otherwise, an INVALID_ARGUMENT error is - returned. - user_info (google.cloud.retail_v2.types.UserInfo): - User information. - uri (str): - Complete URL (window.location.href) of the - user's current page. - When using the client side event reporting with - JavaScript pixel and Google Tag Manager, this - value is filled in automatically. Maximum length - 5,000 characters. - referrer_uri (str): - The referrer URL of the current page. - When using the client side event reporting with - JavaScript pixel and Google Tag Manager, this - value is filled in automatically. - page_view_id (str): - A unique ID of a web page view. - - This should be kept the same for all user events triggered - from the same pageview. For example, an item detail page - view could trigger multiple events as the user is browsing - the page. The ``pageViewId`` property should be kept the - same for all these events so that they can be grouped - together properly. - - When using the client side event reporting with JavaScript - pixel and Google Tag Manager, this value is filled in - 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, - ) - product_details = proto.RepeatedField( - proto.MESSAGE, - number=6, - message='ProductDetail', - ) - completion_detail = proto.Field( - proto.MESSAGE, - number=22, - message='CompletionDetail', - ) - attributes = proto.MapField( - proto.STRING, - proto.MESSAGE, - number=7, - message=common.CustomAttribute, - ) - cart_id = proto.Field( - proto.STRING, - number=8, - ) - purchase_transaction = proto.Field( - 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, - ) - - -class ProductDetail(proto.Message): - r"""Detailed product information associated with a user event. - - Attributes: - product (google.cloud.retail_v2.types.Product): - Required. [Product][google.cloud.retail.v2.Product] - information. - - Required field(s): - - - [Product.id][google.cloud.retail.v2.Product.id] - - Optional override field(s): - - - [Product.price_info][google.cloud.retail.v2.Product.price_info] - - If any supported optional fields are provided, we will treat - them as a full override when looking up product information - from the catalog. Thus, it is important to ensure that the - overriding fields are accurate and complete. - - All other product fields are ignored and instead populated - via catalog lookup after event ingestion. - quantity (google.protobuf.wrappers_pb2.Int32Value): - Quantity of the product associated with the user event. - - For example, this field will be 2 if two products are added - to the shopping cart for ``purchase-complete`` event. - Required for ``add-to-cart`` and ``purchase-complete`` event - types. - """ - - 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): - r"""Detailed completion information including completion - attribution token and clicked completion info. - - Attributes: - completion_attribution_token (str): - Completion attribution token in - [CompleteQueryResponse.attribution_token][google.cloud.retail.v2.CompleteQueryResponse.attribution_token]. - selected_suggestion (str): - End user selected - [CompleteQueryResponse.CompletionResult.suggestion][google.cloud.retail.v2.CompleteQueryResponse.CompletionResult.suggestion]. - selected_position (int): - End user selected - [CompleteQueryResponse.CompletionResult.suggestion][google.cloud.retail.v2.CompleteQueryResponse.CompletionResult.suggestion] - 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, - ) - - -class PurchaseTransaction(proto.Message): - r"""A transaction represents the entire purchase transaction. - - Attributes: - id (str): - The transaction ID with a length limit of 128 - characters. - revenue (float): - Required. Total non-zero revenue or grand - total associated with the transaction. This - value include shipping, tax, or other - adjustments to total revenue that you want to - include as part of your revenue calculations. - tax (float): - All the taxes associated with the - transaction. - cost (float): - All the costs associated with the products. These can be - manufacturing costs, shipping expenses not borne by the end - user, or any other costs, such that: - - - Profit = - [revenue][google.cloud.retail.v2.PurchaseTransaction.revenue] - - [tax][google.cloud.retail.v2.PurchaseTransaction.tax] - - [cost][google.cloud.retail.v2.PurchaseTransaction.cost] - currency_code (str): - Required. Currency code. Use three-character - 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, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/user_event_service.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/user_event_service.py deleted file mode 100644 index bb0a336c..00000000 --- a/owl-bot-staging/v2/google/cloud/retail_v2/types/user_event_service.py +++ /dev/null @@ -1,154 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import proto # type: ignore - -from google.cloud.retail_v2.types import user_event as gcr_user_event - - -__protobuf__ = proto.module( - package='google.cloud.retail.v2', - manifest={ - 'WriteUserEventRequest', - 'CollectUserEventRequest', - 'RejoinUserEventsRequest', - 'RejoinUserEventsResponse', - 'RejoinUserEventsMetadata', - }, -) - - -class WriteUserEventRequest(proto.Message): - r"""Request message for WriteUserEvent method. - - Attributes: - parent (str): - Required. The parent catalog resource name, such as - ``projects/1234/locations/global/catalogs/default_catalog``. - user_event (google.cloud.retail_v2.types.UserEvent): - 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, - ) - - -class CollectUserEventRequest(proto.Message): - r"""Request message for CollectUserEvent method. - - Attributes: - parent (str): - Required. The parent catalog name, such as - ``projects/1234/locations/global/catalogs/default_catalog``. - user_event (str): - Required. URL encoded UserEvent proto with a - length limit of 2,000,000 characters. - uri (str): - The URL including cgi-parameters but - excluding the hash fragment with a length limit - of 5,000 characters. This is often more useful - than the referer URL, because many browsers only - send the domain for 3rd party requests. - ets (int): - The event timestamp in milliseconds. This - prevents browser caching of otherwise identical - get requests. The name is abbreviated to reduce - 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, - ) - - -class RejoinUserEventsRequest(proto.Message): - r"""Request message for RejoinUserEvents method. - - Attributes: - parent (str): - Required. The parent catalog resource name, such as - ``projects/1234/locations/global/catalogs/default_catalog``. - user_event_rejoin_scope (google.cloud.retail_v2.types.RejoinUserEventsRequest.UserEventRejoinScope): - The type of the user event rejoin to define the scope and - range of the user events to be rejoined with the latest - product catalog. Defaults to - USER_EVENT_REJOIN_SCOPE_UNSPECIFIED if this field is not - set, or set to an invalid integer value. - """ - class UserEventRejoinScope(proto.Enum): - r"""The scope of user events to be rejoined with the latest product - catalog. If the rejoining aims at reducing number of unjoined - events, set UserEventRejoinScope to UNJOINED_EVENTS. If the - rejoining aims at correcting product catalog information in joined - events, set UserEventRejoinScope to JOINED_EVENTS. If all events - needs to be rejoined, set UserEventRejoinScope to - USER_EVENT_REJOIN_SCOPE_UNSPECIFIED. - """ - USER_EVENT_REJOIN_SCOPE_UNSPECIFIED = 0 - JOINED_EVENTS = 1 - UNJOINED_EVENTS = 2 - - parent = proto.Field( - proto.STRING, - number=1, - ) - user_event_rejoin_scope = proto.Field( - proto.ENUM, - number=2, - enum=UserEventRejoinScope, - ) - - -class RejoinUserEventsResponse(proto.Message): - r"""Response message for RejoinUserEvents method. - - Attributes: - rejoined_user_events_count (int): - Number of user events that were joined with - latest product catalog. - """ - - rejoined_user_events_count = proto.Field( - proto.INT64, - number=1, - ) - - -class RejoinUserEventsMetadata(proto.Message): - r"""Metadata for RejoinUserEvents method. - """ - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/mypy.ini b/owl-bot-staging/v2/mypy.ini deleted file mode 100644 index 4505b485..00000000 --- a/owl-bot-staging/v2/mypy.ini +++ /dev/null @@ -1,3 +0,0 @@ -[mypy] -python_version = 3.6 -namespace_packages = True diff --git a/owl-bot-staging/v2/noxfile.py b/owl-bot-staging/v2/noxfile.py deleted file mode 100644 index 771bbfee..00000000 --- a/owl-bot-staging/v2/noxfile.py +++ /dev/null @@ -1,132 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import os -import pathlib -import shutil -import subprocess -import sys - - -import nox # type: ignore - -CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() - -LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" -PACKAGE_NAME = subprocess.check_output([sys.executable, "setup.py", "--name"], encoding="utf-8") - - -nox.sessions = [ - "unit", - "cover", - "mypy", - "check_lower_bounds" - # exclude update_lower_bounds from default - "docs", -] - -@nox.session(python=['3.6', '3.7', '3.8', '3.9', '3.10']) -def unit(session): - """Run the unit test suite.""" - - session.install('coverage', 'pytest', 'pytest-cov', 'asyncmock', 'pytest-asyncio') - session.install('-e', '.') - - session.run( - 'py.test', - '--quiet', - '--cov=google/cloud/retail_v2/', - '--cov-config=.coveragerc', - '--cov-report=term', - '--cov-report=html', - os.path.join('tests', 'unit', ''.join(session.posargs)) - ) - - -@nox.session(python='3.9') -def cover(session): - """Run the final coverage report. - This outputs the coverage report aggregating coverage from the unit - test runs (not system test runs), and then erases coverage data. - """ - session.install("coverage", "pytest-cov") - session.run("coverage", "report", "--show-missing", "--fail-under=100") - - session.run("coverage", "erase") - - -@nox.session(python=['3.6', '3.7', '3.8', '3.9']) -def mypy(session): - """Run the type checker.""" - session.install('mypy', 'types-pkg_resources') - session.install('.') - session.run( - 'mypy', - '--explicit-package-bases', - 'google', - ) - - -@nox.session -def update_lower_bounds(session): - """Update lower bounds in constraints.txt to match setup.py""" - session.install('google-cloud-testutils') - session.install('.') - - session.run( - 'lower-bound-checker', - 'update', - '--package-name', - PACKAGE_NAME, - '--constraints-file', - str(LOWER_BOUND_CONSTRAINTS_FILE), - ) - - -@nox.session -def check_lower_bounds(session): - """Check lower bounds in setup.py are reflected in constraints file""" - session.install('google-cloud-testutils') - session.install('.') - - session.run( - 'lower-bound-checker', - 'check', - '--package-name', - PACKAGE_NAME, - '--constraints-file', - str(LOWER_BOUND_CONSTRAINTS_FILE), - ) - -@nox.session(python='3.9') -def docs(session): - """Build the docs for this library.""" - - session.install("-e", ".") - session.install("sphinx<3.0.0", "alabaster", "recommonmark") - - shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) - session.run( - "sphinx-build", - "-W", # warnings as errors - "-T", # show full traceback on exception - "-N", # no colors - "-b", - "html", - "-d", - os.path.join("docs", "_build", "doctrees", ""), - os.path.join("docs", ""), - os.path.join("docs", "_build", "html", ""), - ) diff --git a/owl-bot-staging/v2/scripts/fixup_retail_v2_keywords.py b/owl-bot-staging/v2/scripts/fixup_retail_v2_keywords.py deleted file mode 100644 index 2688d8b7..00000000 --- a/owl-bot-staging/v2/scripts/fixup_retail_v2_keywords.py +++ /dev/null @@ -1,197 +0,0 @@ -#! /usr/bin/env python3 -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import argparse -import os -import libcst as cst -import pathlib -import sys -from typing import (Any, Callable, Dict, List, Sequence, Tuple) - - -def partition( - predicate: Callable[[Any], bool], - iterator: Sequence[Any] -) -> Tuple[List[Any], List[Any]]: - """A stable, out-of-place partition.""" - results = ([], []) - - for i in iterator: - results[int(predicate(i))].append(i) - - # Returns trueList, falseList - return results[1], results[0] - - -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', ), - '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', ), - 'delete_product': ('name', ), - 'get_default_branch': ('catalog', ), - 'get_product': ('name', ), - 'import_completion_data': ('parent', 'input_config', 'notification_pubsub_topic', ), - 'import_products': ('parent', 'input_config', 'request_id', 'errors_config', 'update_mask', 'reconciliation_mode', 'notification_pubsub_topic', ), - 'import_user_events': ('parent', 'input_config', 'errors_config', ), - 'list_catalogs': ('parent', 'page_size', 'page_token', ), - 'list_products': ('parent', 'page_size', 'page_token', 'filter', 'read_mask', ), - 'predict': ('placement', 'user_event', 'page_size', 'page_token', 'filter', 'validate_only', 'params', 'labels', ), - 'purge_user_events': ('parent', 'filter', 'force', ), - 'rejoin_user_events': ('parent', 'user_event_rejoin_scope', ), - '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', ), - 'set_inventory': ('inventory', 'set_mask', 'set_time', 'allow_missing', ), - 'update_catalog': ('catalog', 'update_mask', ), - 'update_product': ('product', 'update_mask', 'allow_missing', ), - 'write_user_event': ('parent', 'user_event', ), - } - - def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: - try: - key = original.func.attr.value - kword_params = self.METHOD_TO_PARAMS[key] - except (AttributeError, KeyError): - # Either not a method from the API or too convoluted to be sure. - return updated - - # If the existing code is valid, keyword args come after positional args. - # Therefore, all positional args must map to the first parameters. - args, kwargs = partition(lambda a: not bool(a.keyword), updated.args) - if any(k.keyword.value == "request" for k in kwargs): - # We've already fixed this file, don't fix it again. - return updated - - kwargs, ctrl_kwargs = partition( - lambda a: a.keyword.value not in self.CTRL_PARAMS, - kwargs - ) - - args, ctrl_args = args[:len(kword_params)], args[len(kword_params):] - ctrl_kwargs.extend(cst.Arg(value=a.value, keyword=cst.Name(value=ctrl)) - for a, ctrl in zip(ctrl_args, self.CTRL_PARAMS)) - - request_arg = cst.Arg( - value=cst.Dict([ - cst.DictElement( - cst.SimpleString("'{}'".format(name)), -cst.Element(value=arg.value) - ) - # Note: the args + kwargs looks silly, but keep in mind that - # the control parameters had to be stripped out, and that - # those could have been passed positionally or by keyword. - for name, arg in zip(kword_params, args + kwargs)]), - keyword=cst.Name("request") - ) - - return updated.with_changes( - args=[request_arg] + ctrl_kwargs - ) - - -def fix_files( - in_dir: pathlib.Path, - out_dir: pathlib.Path, - *, - transformer=retailCallTransformer(), -): - """Duplicate the input dir to the output dir, fixing file method calls. - - Preconditions: - * in_dir is a real directory - * out_dir is a real, empty directory - """ - pyfile_gen = ( - pathlib.Path(os.path.join(root, f)) - for root, _, files in os.walk(in_dir) - for f in files if os.path.splitext(f)[1] == ".py" - ) - - for fpath in pyfile_gen: - with open(fpath, 'r') as f: - src = f.read() - - # Parse the code and insert method call fixes. - tree = cst.parse_module(src) - updated = tree.visit(transformer) - - # Create the path and directory structure for the new file. - updated_path = out_dir.joinpath(fpath.relative_to(in_dir)) - updated_path.parent.mkdir(parents=True, exist_ok=True) - - # Generate the updated source file at the corresponding path. - with open(updated_path, 'w') as f: - f.write(updated.code) - - -if __name__ == '__main__': - parser = argparse.ArgumentParser( - description="""Fix up source that uses the retail client library. - -The existing sources are NOT overwritten but are copied to output_dir with changes made. - -Note: This tool operates at a best-effort level at converting positional - parameters in client method calls to keyword based parameters. - Cases where it WILL FAIL include - A) * or ** expansion in a method call. - B) Calls via function or method alias (includes free function calls) - C) Indirect or dispatched calls (e.g. the method is looked up dynamically) - - These all constitute false negatives. The tool will also detect false - positives when an API method shares a name with another method. -""") - parser.add_argument( - '-d', - '--input-directory', - required=True, - dest='input_dir', - help='the input directory to walk for python files to fix up', - ) - parser.add_argument( - '-o', - '--output-directory', - required=True, - dest='output_dir', - help='the directory to output files fixed via un-flattening', - ) - args = parser.parse_args() - input_dir = pathlib.Path(args.input_dir) - output_dir = pathlib.Path(args.output_dir) - if not input_dir.is_dir(): - print( - f"input directory '{input_dir}' does not exist or is not a directory", - file=sys.stderr, - ) - sys.exit(-1) - - if not output_dir.is_dir(): - print( - f"output directory '{output_dir}' does not exist or is not a directory", - file=sys.stderr, - ) - sys.exit(-1) - - if os.listdir(output_dir): - print( - f"output directory '{output_dir}' is not empty", - file=sys.stderr, - ) - sys.exit(-1) - - fix_files(input_dir, output_dir) diff --git a/owl-bot-staging/v2/setup.py b/owl-bot-staging/v2/setup.py deleted file mode 100644 index baa5fefe..00000000 --- a/owl-bot-staging/v2/setup.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import io -import os -import setuptools # type: ignore - -version = '0.1.0' - -package_root = os.path.abspath(os.path.dirname(__file__)) - -readme_filename = os.path.join(package_root, 'README.rst') -with io.open(readme_filename, encoding='utf-8') as readme_file: - readme = readme_file.read() - -setuptools.setup( - name='google-cloud-retail', - version=version, - long_description=readme, - packages=setuptools.PEP420PackageFinder.find(), - namespace_packages=('google', 'google.cloud'), - platforms='Posix; MacOS X; Windows', - include_package_data=True, - install_requires=( - 'google-api-core[grpc] >= 1.28.0, < 3.0.0dev', - 'libcst >= 0.2.5', - 'proto-plus >= 1.19.7', - ), - python_requires='>=3.6', - classifiers=[ - 'Development Status :: 3 - Alpha', - 'Intended Audience :: Developers', - 'Operating System :: OS Independent', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Topic :: Internet', - 'Topic :: Software Development :: Libraries :: Python Modules', - ], - zip_safe=False, -) diff --git a/owl-bot-staging/v2/tests/__init__.py b/owl-bot-staging/v2/tests/__init__.py deleted file mode 100644 index b54a5fcc..00000000 --- a/owl-bot-staging/v2/tests/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# diff --git a/owl-bot-staging/v2/tests/unit/__init__.py b/owl-bot-staging/v2/tests/unit/__init__.py deleted file mode 100644 index b54a5fcc..00000000 --- a/owl-bot-staging/v2/tests/unit/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# diff --git a/owl-bot-staging/v2/tests/unit/gapic/__init__.py b/owl-bot-staging/v2/tests/unit/gapic/__init__.py deleted file mode 100644 index b54a5fcc..00000000 --- a/owl-bot-staging/v2/tests/unit/gapic/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# diff --git a/owl-bot-staging/v2/tests/unit/gapic/retail_v2/__init__.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/__init__.py deleted file mode 100644 index b54a5fcc..00000000 --- a/owl-bot-staging/v2/tests/unit/gapic/retail_v2/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# diff --git a/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_catalog_service.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_catalog_service.py deleted file mode 100644 index 331b536a..00000000 --- a/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_catalog_service.py +++ /dev/null @@ -1,2184 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import os -import mock - -import grpc -from grpc.experimental import aio -import math -import pytest -from proto.marshal.rules.dates import DurationRule, TimestampRule - - -from google.api_core import client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers -from google.api_core import grpc_helpers_async -from google.api_core import path_template -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.cloud.retail_v2.services.catalog_service import CatalogServiceAsyncClient -from google.cloud.retail_v2.services.catalog_service import CatalogServiceClient -from google.cloud.retail_v2.services.catalog_service import pagers -from google.cloud.retail_v2.services.catalog_service import transports -from google.cloud.retail_v2.types import catalog -from google.cloud.retail_v2.types import catalog as gcr_catalog -from google.cloud.retail_v2.types import catalog_service -from google.oauth2 import service_account -from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore -import google.auth - - -def client_cert_source_callback(): - return b"cert bytes", b"key bytes" - - -# If default endpoint is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint(client): - return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT - - -def test__get_default_mtls_endpoint(): - api_endpoint = "example.googleapis.com" - api_mtls_endpoint = "example.mtls.googleapis.com" - sandbox_endpoint = "example.sandbox.googleapis.com" - sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" - non_googleapi = "api.example.com" - - assert CatalogServiceClient._get_default_mtls_endpoint(None) is None - assert CatalogServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint - assert CatalogServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint - assert CatalogServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint - assert CatalogServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint - assert CatalogServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi - - -@pytest.mark.parametrize("client_class", [ - CatalogServiceClient, - CatalogServiceAsyncClient, -]) -def test_catalog_service_client_from_service_account_info(client_class): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: - factory.return_value = creds - info = {"valid": True} - client = client_class.from_service_account_info(info) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == 'retail.googleapis.com:443' - - -@pytest.mark.parametrize("transport_class,transport_name", [ - (transports.CatalogServiceGrpcTransport, "grpc"), - (transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -def test_catalog_service_client_service_account_always_use_jwt(transport_class, transport_name): - with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=True) - use_jwt.assert_called_once_with(True) - - with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=False) - use_jwt.assert_not_called() - - -@pytest.mark.parametrize("client_class", [ - CatalogServiceClient, - CatalogServiceAsyncClient, -]) -def test_catalog_service_client_from_service_account_file(client_class): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: - factory.return_value = creds - client = client_class.from_service_account_file("dummy/file/path.json") - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - client = client_class.from_service_account_json("dummy/file/path.json") - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == 'retail.googleapis.com:443' - - -def test_catalog_service_client_get_transport_class(): - transport = CatalogServiceClient.get_transport_class() - available_transports = [ - transports.CatalogServiceGrpcTransport, - ] - assert transport in available_transports - - transport = CatalogServiceClient.get_transport_class("grpc") - assert transport == transports.CatalogServiceGrpcTransport - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc"), - (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -@mock.patch.object(CatalogServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceClient)) -@mock.patch.object(CatalogServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceAsyncClient)) -def test_catalog_service_client_client_options(client_class, transport_class, transport_name): - # Check that if channel is provided we won't create a new one. - with mock.patch.object(CatalogServiceClient, 'get_transport_class') as gtc: - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ) - client = client_class(transport=transport) - gtc.assert_not_called() - - # Check that if channel is provided via str we will create a new one. - with mock.patch.object(CatalogServiceClient, 'get_transport_class') as gtc: - client = client_class(transport=transport_name) - gtc.assert_called() - - # Check the case api_endpoint is provided. - options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name, client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class(transport=transport_name) - - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): - with pytest.raises(ValueError): - client = client_class(transport=transport_name) - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - -@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ - (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc", "true"), - (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), - (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc", "false"), - (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), -]) -@mock.patch.object(CatalogServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceClient)) -@mock.patch.object(CatalogServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceAsyncClient)) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_catalog_service_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): - # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default - # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. - - # Check the case client_cert_source is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - - if use_client_cert_env == "false": - expected_client_cert_source = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_client_cert_source = client_cert_source_callback - expected_host = client.DEFAULT_MTLS_ENDPOINT - - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case ADC client cert is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - with mock.patch.object(transport_class, '__init__') as patched: - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): - with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): - if use_client_cert_env == "false": - expected_host = client.DEFAULT_ENDPOINT - expected_client_cert_source = None - else: - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_client_cert_source = client_cert_source_callback - - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - with mock.patch.object(transport_class, '__init__') as patched: - with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - -@pytest.mark.parametrize("client_class", [ - CatalogServiceClient, CatalogServiceAsyncClient -]) -@mock.patch.object(CatalogServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceClient)) -@mock.patch.object(CatalogServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceAsyncClient)) -def test_catalog_service_client_get_mtls_endpoint_and_cert_source(client_class): - mock_client_cert_source = mock.Mock() - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - mock_api_endpoint = "foo" - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source == mock_client_cert_source - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - mock_client_cert_source = mock.Mock() - mock_api_endpoint = "foo" - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): - with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source == mock_client_cert_source - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc"), - (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -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"], - ) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=["1", "2"], - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc"), - (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -def test_catalog_service_client_client_options_credentials_file(client_class, transport_class, transport_name): - # Check the case credentials file is provided. - options = client_options.ClientOptions( - credentials_file="credentials.json" - ) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file="credentials.json", - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - -def test_catalog_service_client_client_options_from_dict(): - with mock.patch('google.cloud.retail_v2.services.catalog_service.transports.CatalogServiceGrpcTransport.__init__') as grpc_transport: - grpc_transport.return_value = None - client = CatalogServiceClient( - client_options={'api_endpoint': 'squid.clam.whelk'} - ) - grpc_transport.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - -@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, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_catalogs), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = catalog_service.ListCatalogsResponse( - next_page_token='next_page_token_value', - ) - response = client.list_catalogs(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == catalog_service.ListCatalogsRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListCatalogsPager) - assert response.next_page_token == 'next_page_token_value' - - -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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_catalogs), - '__call__') as call: - client.list_catalogs() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == catalog_service.ListCatalogsRequest() - - -@pytest.mark.asyncio -async def test_list_catalogs_async(transport: str = 'grpc_asyncio', request_type=catalog_service.ListCatalogsRequest): - client = CatalogServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_catalogs), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.ListCatalogsResponse( - next_page_token='next_page_token_value', - )) - response = await client.list_catalogs(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == catalog_service.ListCatalogsRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListCatalogsAsyncPager) - assert response.next_page_token == 'next_page_token_value' - - -@pytest.mark.asyncio -async def test_list_catalogs_async_from_dict(): - await test_list_catalogs_async(request_type=dict) - - -def test_list_catalogs_field_headers(): - client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = catalog_service.ListCatalogsRequest() - - request.parent = 'parent/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_catalogs), - '__call__') as call: - call.return_value = catalog_service.ListCatalogsResponse() - client.list_catalogs(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'parent=parent/value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_list_catalogs_field_headers_async(): - client = CatalogServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = catalog_service.ListCatalogsRequest() - - request.parent = 'parent/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_catalogs), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.ListCatalogsResponse()) - await client.list_catalogs(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'parent=parent/value', - ) in kw['metadata'] - - -def test_list_catalogs_flattened(): - 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: - # Designate an appropriate return value for the call. - 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', - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - arg = args[0].parent - mock_val = 'parent_value' - assert arg == mock_val - - -def test_list_catalogs_flattened_error(): - 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', - ) - - -@pytest.mark.asyncio -async def test_list_catalogs_flattened_async(): - client = CatalogServiceAsyncClient( - 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: - # Designate an appropriate return value for the call. - call.return_value = catalog_service.ListCatalogsResponse() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.ListCatalogsResponse()) - # 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', - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].parent - mock_val = 'parent_value' - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_list_catalogs_flattened_error_async(): - client = CatalogServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.list_catalogs( - catalog_service.ListCatalogsRequest(), - parent='parent_value', - ) - - -def test_list_catalogs_pager(transport_name: str = "grpc"): - client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials, - transport=transport_name, - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_catalogs), - '__call__') as call: - # Set the response to a series of pages. - call.side_effect = ( - catalog_service.ListCatalogsResponse( - 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', - ), - catalog_service.ListCatalogsResponse( - catalogs=[ - catalog.Catalog(), - catalog.Catalog(), - ], - ), - RuntimeError, - ) - - metadata = () - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ('parent', ''), - )), - ) - pager = client.list_catalogs(request={}) - - assert pager._metadata == metadata - - results = [i for i in pager] - assert len(results) == 6 - assert all(isinstance(i, catalog.Catalog) - for i in results) -def test_list_catalogs_pages(transport_name: str = "grpc"): - client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials, - transport=transport_name, - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_catalogs), - '__call__') as call: - # Set the response to a series of pages. - call.side_effect = ( - catalog_service.ListCatalogsResponse( - 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', - ), - catalog_service.ListCatalogsResponse( - catalogs=[ - catalog.Catalog(), - catalog.Catalog(), - ], - ), - RuntimeError, - ) - pages = list(client.list_catalogs(request={}).pages) - for page_, token in zip(pages, ['abc','def','ghi', '']): - assert page_.raw_page.next_page_token == token - -@pytest.mark.asyncio -async def test_list_catalogs_async_pager(): - client = CatalogServiceAsyncClient( - 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__', new_callable=mock.AsyncMock) as call: - # Set the response to a series of pages. - call.side_effect = ( - catalog_service.ListCatalogsResponse( - 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', - ), - catalog_service.ListCatalogsResponse( - catalogs=[ - catalog.Catalog(), - catalog.Catalog(), - ], - ), - RuntimeError, - ) - async_pager = await client.list_catalogs(request={},) - assert async_pager.next_page_token == 'abc' - responses = [] - async for response in async_pager: - responses.append(response) - - assert len(responses) == 6 - assert all(isinstance(i, catalog.Catalog) - for i in responses) - - -@pytest.mark.asyncio -async def test_list_catalogs_async_pages(): - client = CatalogServiceAsyncClient( - 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__', new_callable=mock.AsyncMock) as call: - # Set the response to a series of pages. - call.side_effect = ( - catalog_service.ListCatalogsResponse( - 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', - ), - catalog_service.ListCatalogsResponse( - catalogs=[ - catalog.Catalog(), - catalog.Catalog(), - ], - ), - RuntimeError, - ) - pages = [] - async for page_ in (await client.list_catalogs(request={})).pages: - pages.append(page_) - for page_, token in zip(pages, ['abc','def','ghi', '']): - assert page_.raw_page.next_page_token == token - -@pytest.mark.parametrize("request_type", [ - catalog_service.UpdateCatalogRequest, - dict, -]) -def test_update_catalog(request_type, transport: str = 'grpc'): - client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.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', - ) - response = client.update_catalog(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == catalog_service.UpdateCatalogRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, gcr_catalog.Catalog) - assert response.name == 'name_value' - assert response.display_name == 'display_name_value' - - -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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_catalog), - '__call__') as call: - client.update_catalog() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == catalog_service.UpdateCatalogRequest() - - -@pytest.mark.asyncio -async def test_update_catalog_async(transport: str = 'grpc_asyncio', request_type=catalog_service.UpdateCatalogRequest): - client = CatalogServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.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', - )) - response = await client.update_catalog(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == catalog_service.UpdateCatalogRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, gcr_catalog.Catalog) - assert response.name == 'name_value' - assert response.display_name == 'display_name_value' - - -@pytest.mark.asyncio -async def test_update_catalog_async_from_dict(): - await test_update_catalog_async(request_type=dict) - - -def test_update_catalog_field_headers(): - client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = catalog_service.UpdateCatalogRequest() - - request.catalog.name = 'catalog.name/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_catalog), - '__call__') as call: - call.return_value = gcr_catalog.Catalog() - client.update_catalog(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', - 'catalog.name=catalog.name/value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_update_catalog_field_headers_async(): - client = CatalogServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = catalog_service.UpdateCatalogRequest() - - request.catalog.name = 'catalog.name/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_catalog), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_catalog.Catalog()) - await client.update_catalog(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', - 'catalog.name=catalog.name/value', - ) in kw['metadata'] - - -def test_update_catalog_flattened(): - 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: - # Designate an appropriate return value for the call. - call.return_value = gcr_catalog.Catalog() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.update_catalog( - catalog=gcr_catalog.Catalog(name='name_value'), - update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - arg = args[0].catalog - mock_val = gcr_catalog.Catalog(name='name_value') - assert arg == mock_val - arg = args[0].update_mask - mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) - assert arg == mock_val - - -def test_update_catalog_flattened_error(): - 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.update_catalog( - catalog_service.UpdateCatalogRequest(), - catalog=gcr_catalog.Catalog(name='name_value'), - update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), - ) - - -@pytest.mark.asyncio -async def test_update_catalog_flattened_async(): - client = CatalogServiceAsyncClient( - 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: - # Designate an appropriate return value for the call. - call.return_value = gcr_catalog.Catalog() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_catalog.Catalog()) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.update_catalog( - catalog=gcr_catalog.Catalog(name='name_value'), - update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].catalog - mock_val = gcr_catalog.Catalog(name='name_value') - assert arg == mock_val - arg = args[0].update_mask - mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_update_catalog_flattened_error_async(): - client = CatalogServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.update_catalog( - catalog_service.UpdateCatalogRequest(), - catalog=gcr_catalog.Catalog(name='name_value'), - update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), - ) - - -@pytest.mark.parametrize("request_type", [ - catalog_service.SetDefaultBranchRequest, - dict, -]) -def test_set_default_branch(request_type, transport: str = 'grpc'): - client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.set_default_branch), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = None - response = client.set_default_branch(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == catalog_service.SetDefaultBranchRequest() - - # Establish that the response is the type that we expect. - assert response is None - - -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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.set_default_branch), - '__call__') as call: - client.set_default_branch() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == catalog_service.SetDefaultBranchRequest() - - -@pytest.mark.asyncio -async def test_set_default_branch_async(transport: str = 'grpc_asyncio', request_type=catalog_service.SetDefaultBranchRequest): - client = CatalogServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.set_default_branch), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.set_default_branch(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == catalog_service.SetDefaultBranchRequest() - - # Establish that the response is the type that we expect. - assert response is None - - -@pytest.mark.asyncio -async def test_set_default_branch_async_from_dict(): - await test_set_default_branch_async(request_type=dict) - - -def test_set_default_branch_field_headers(): - client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = catalog_service.SetDefaultBranchRequest() - - request.catalog = 'catalog/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.set_default_branch), - '__call__') as call: - call.return_value = None - client.set_default_branch(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', - 'catalog=catalog/value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_set_default_branch_field_headers_async(): - client = CatalogServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = catalog_service.SetDefaultBranchRequest() - - request.catalog = 'catalog/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.set_default_branch), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - await client.set_default_branch(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', - 'catalog=catalog/value', - ) in kw['metadata'] - - -def test_set_default_branch_flattened(): - 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.set_default_branch), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = None - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.set_default_branch( - catalog='catalog_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].catalog - mock_val = 'catalog_value' - assert arg == mock_val - - -def test_set_default_branch_flattened_error(): - 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', - ) - - -@pytest.mark.asyncio -async def test_set_default_branch_flattened_async(): - client = CatalogServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.set_default_branch), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = None - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.set_default_branch( - catalog='catalog_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].catalog - mock_val = 'catalog_value' - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_set_default_branch_flattened_error_async(): - client = CatalogServiceAsyncClient( - 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.set_default_branch( - catalog_service.SetDefaultBranchRequest(), - catalog='catalog_value', - ) - - -@pytest.mark.parametrize("request_type", [ - catalog_service.GetDefaultBranchRequest, - dict, -]) -def test_get_default_branch(request_type, transport: str = 'grpc'): - client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_default_branch), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = catalog_service.GetDefaultBranchResponse( - branch='branch_value', - note='note_value', - ) - response = client.get_default_branch(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == catalog_service.GetDefaultBranchRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, catalog_service.GetDefaultBranchResponse) - assert response.branch == 'branch_value' - assert response.note == 'note_value' - - -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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_default_branch), - '__call__') as call: - client.get_default_branch() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == catalog_service.GetDefaultBranchRequest() - - -@pytest.mark.asyncio -async def test_get_default_branch_async(transport: str = 'grpc_asyncio', request_type=catalog_service.GetDefaultBranchRequest): - client = CatalogServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_default_branch), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.GetDefaultBranchResponse( - branch='branch_value', - note='note_value', - )) - response = await client.get_default_branch(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == catalog_service.GetDefaultBranchRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, catalog_service.GetDefaultBranchResponse) - assert response.branch == 'branch_value' - assert response.note == 'note_value' - - -@pytest.mark.asyncio -async def test_get_default_branch_async_from_dict(): - await test_get_default_branch_async(request_type=dict) - - -def test_get_default_branch_field_headers(): - client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = catalog_service.GetDefaultBranchRequest() - - request.catalog = 'catalog/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_default_branch), - '__call__') as call: - call.return_value = catalog_service.GetDefaultBranchResponse() - client.get_default_branch(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', - 'catalog=catalog/value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_get_default_branch_field_headers_async(): - client = CatalogServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = catalog_service.GetDefaultBranchRequest() - - request.catalog = 'catalog/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_default_branch), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.GetDefaultBranchResponse()) - await client.get_default_branch(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', - 'catalog=catalog/value', - ) in kw['metadata'] - - -def test_get_default_branch_flattened(): - 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.get_default_branch), - '__call__') as call: - # Designate an appropriate return value for the call. - 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', - ) - - # 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].catalog - mock_val = 'catalog_value' - assert arg == mock_val - - -def test_get_default_branch_flattened_error(): - 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', - ) - - -@pytest.mark.asyncio -async def test_get_default_branch_flattened_async(): - client = CatalogServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_default_branch), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = catalog_service.GetDefaultBranchResponse() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.GetDefaultBranchResponse()) - # 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', - ) - - # 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].catalog - mock_val = 'catalog_value' - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_get_default_branch_flattened_error_async(): - client = CatalogServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.get_default_branch( - catalog_service.GetDefaultBranchRequest(), - catalog='catalog_value', - ) - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.CatalogServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.CatalogServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = CatalogServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.CatalogServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = CatalogServiceClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = mock.Mock() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = CatalogServiceClient( - client_options=options, - credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.CatalogServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = CatalogServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.CatalogServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = CatalogServiceClient(transport=transport) - assert client.transport is transport - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.CatalogServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.CatalogServiceGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize("transport_class", [ - transports.CatalogServiceGrpcTransport, - transports.CatalogServiceGrpcAsyncIOTransport, -]) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, 'default') as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - -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, - ) - -def test_catalog_service_base_transport_error(): - # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(core_exceptions.DuplicateCredentialArgs): - transport = transports.CatalogServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - credentials_file="credentials.json" - ) - - -def test_catalog_service_base_transport(): - # Instantiate the base transport. - with mock.patch('google.cloud.retail_v2.services.catalog_service.transports.CatalogServiceTransport.__init__') as Transport: - Transport.return_value = None - transport = transports.CatalogServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Every method on the transport should just blindly - # raise NotImplementedError. - methods = ( - 'list_catalogs', - 'update_catalog', - 'set_default_branch', - 'get_default_branch', - ) - for method in methods: - with pytest.raises(NotImplementedError): - getattr(transport, method)(request=object()) - - with pytest.raises(NotImplementedError): - transport.close() - - -def test_catalog_service_base_transport_with_credentials_file(): - # Instantiate the base transport with a credentials file - with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('google.cloud.retail_v2.services.catalog_service.transports.CatalogServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.CatalogServiceTransport( - credentials_file="credentials.json", - quota_project_id="octopus", - ) - load_creds.assert_called_once_with("credentials.json", - scopes=None, - default_scopes=( - 'https://www.googleapis.com/auth/cloud-platform', -), - quota_project_id="octopus", - ) - - -def test_catalog_service_base_transport_with_adc(): - # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(google.auth, 'default', autospec=True) as adc, mock.patch('google.cloud.retail_v2.services.catalog_service.transports.CatalogServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.CatalogServiceTransport() - adc.assert_called_once() - - -def test_catalog_service_auth_adc(): - # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(google.auth, 'default', autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - CatalogServiceClient() - adc.assert_called_once_with( - scopes=None, - default_scopes=( - 'https://www.googleapis.com/auth/cloud-platform', -), - quota_project_id=None, - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.CatalogServiceGrpcTransport, - transports.CatalogServiceGrpcAsyncIOTransport, - ], -) -def test_catalog_service_transport_auth_adc(transport_class): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, 'default', autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class(quota_project_id="octopus", scopes=["1", "2"]) - adc.assert_called_once_with( - scopes=["1", "2"], - default_scopes=( 'https://www.googleapis.com/auth/cloud-platform',), - quota_project_id="octopus", - ) - - -@pytest.mark.parametrize( - "transport_class,grpc_helpers", - [ - (transports.CatalogServiceGrpcTransport, grpc_helpers), - (transports.CatalogServiceGrpcAsyncIOTransport, grpc_helpers_async) - ], -) -def test_catalog_service_transport_create_channel(transport_class, grpc_helpers): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( - grpc_helpers, "create_channel", autospec=True - ) as create_channel: - creds = ga_credentials.AnonymousCredentials() - adc.return_value = (creds, None) - transport_class( - quota_project_id="octopus", - scopes=["1", "2"] - ) - - create_channel.assert_called_with( - "retail.googleapis.com:443", - credentials=creds, - credentials_file=None, - quota_project_id="octopus", - default_scopes=( - 'https://www.googleapis.com/auth/cloud-platform', -), - scopes=["1", "2"], - default_host="retail.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize("transport_class", [transports.CatalogServiceGrpcTransport, transports.CatalogServiceGrpcAsyncIOTransport]) -def test_catalog_service_grpc_transport_client_cert_source_for_mtls( - transport_class -): - cred = ga_credentials.AnonymousCredentials() - - # Check ssl_channel_credentials is used if provided. - with mock.patch.object(transport_class, "create_channel") as mock_create_channel: - mock_ssl_channel_creds = mock.Mock() - transport_class( - host="squid.clam.whelk", - credentials=cred, - ssl_channel_credentials=mock_ssl_channel_creds - ) - mock_create_channel.assert_called_once_with( - "squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_channel_creds, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls - # is used. - with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): - with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: - transport_class( - credentials=cred, - client_cert_source_for_mtls=client_cert_source_callback - ) - expected_cert, expected_key = client_cert_source_callback() - mock_ssl_cred.assert_called_once_with( - certificate_chain=expected_cert, - private_key=expected_key - ) - - -def test_catalog_service_host_no_port(): - client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), - ) - assert client.transport._host == 'retail.googleapis.com:443' - - -def test_catalog_service_host_with_port(): - client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), - ) - assert client.transport._host == 'retail.googleapis.com:8000' - -def test_catalog_service_grpc_transport_channel(): - channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.CatalogServiceGrpcTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -def test_catalog_service_grpc_asyncio_transport_channel(): - channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.CatalogServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.parametrize("transport_class", [transports.CatalogServiceGrpcTransport, transports.CatalogServiceGrpcAsyncIOTransport]) -def test_catalog_service_transport_channel_mtls_with_client_cert_source( - transport_class -): - with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: - with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - cred = ga_credentials.AnonymousCredentials() - with pytest.warns(DeprecationWarning): - with mock.patch.object(google.auth, 'default') as adc: - adc.return_value = (cred, None) - transport = transport_class( - host="squid.clam.whelk", - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - adc.assert_called_once() - - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - assert transport._ssl_channel_credentials == mock_ssl_cred - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.parametrize("transport_class", [transports.CatalogServiceGrpcTransport, transports.CatalogServiceGrpcAsyncIOTransport]) -def test_catalog_service_transport_channel_mtls_with_adc( - transport_class -): - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - mock_cred = mock.Mock() - - with pytest.warns(DeprecationWarning): - transport = transport_class( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=None, - ) - - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - - -def test_branch_path(): - project = "squid" - location = "clam" - catalog = "whelk" - branch = "octopus" - expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) - actual = CatalogServiceClient.branch_path(project, location, catalog, branch) - assert expected == actual - - -def test_parse_branch_path(): - expected = { - "project": "oyster", - "location": "nudibranch", - "catalog": "cuttlefish", - "branch": "mussel", - } - path = CatalogServiceClient.branch_path(**expected) - - # Check that the path construction is reversible. - actual = CatalogServiceClient.parse_branch_path(path) - assert expected == actual - -def test_catalog_path(): - project = "winkle" - location = "nautilus" - catalog = "scallop" - expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) - actual = CatalogServiceClient.catalog_path(project, location, catalog) - assert expected == actual - - -def test_parse_catalog_path(): - expected = { - "project": "abalone", - "location": "squid", - "catalog": "clam", - } - path = CatalogServiceClient.catalog_path(**expected) - - # Check that the path construction is reversible. - actual = CatalogServiceClient.parse_catalog_path(path) - assert expected == actual - -def test_common_billing_account_path(): - billing_account = "whelk" - expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) - actual = CatalogServiceClient.common_billing_account_path(billing_account) - assert expected == actual - - -def test_parse_common_billing_account_path(): - expected = { - "billing_account": "octopus", - } - path = CatalogServiceClient.common_billing_account_path(**expected) - - # Check that the path construction is reversible. - actual = CatalogServiceClient.parse_common_billing_account_path(path) - assert expected == actual - -def test_common_folder_path(): - folder = "oyster" - expected = "folders/{folder}".format(folder=folder, ) - actual = CatalogServiceClient.common_folder_path(folder) - assert expected == actual - - -def test_parse_common_folder_path(): - expected = { - "folder": "nudibranch", - } - path = CatalogServiceClient.common_folder_path(**expected) - - # Check that the path construction is reversible. - actual = CatalogServiceClient.parse_common_folder_path(path) - assert expected == actual - -def test_common_organization_path(): - organization = "cuttlefish" - expected = "organizations/{organization}".format(organization=organization, ) - actual = CatalogServiceClient.common_organization_path(organization) - assert expected == actual - - -def test_parse_common_organization_path(): - expected = { - "organization": "mussel", - } - path = CatalogServiceClient.common_organization_path(**expected) - - # Check that the path construction is reversible. - actual = CatalogServiceClient.parse_common_organization_path(path) - assert expected == actual - -def test_common_project_path(): - project = "winkle" - expected = "projects/{project}".format(project=project, ) - actual = CatalogServiceClient.common_project_path(project) - assert expected == actual - - -def test_parse_common_project_path(): - expected = { - "project": "nautilus", - } - path = CatalogServiceClient.common_project_path(**expected) - - # Check that the path construction is reversible. - actual = CatalogServiceClient.parse_common_project_path(path) - assert expected == actual - -def test_common_location_path(): - project = "scallop" - location = "abalone" - expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) - actual = CatalogServiceClient.common_location_path(project, location) - assert expected == actual - - -def test_parse_common_location_path(): - expected = { - "project": "squid", - "location": "clam", - } - path = CatalogServiceClient.common_location_path(**expected) - - # Check that the path construction is reversible. - actual = CatalogServiceClient.parse_common_location_path(path) - assert expected == actual - - -def test_client_with_default_client_info(): - client_info = gapic_v1.client_info.ClientInfo() - - with mock.patch.object(transports.CatalogServiceTransport, '_prep_wrapped_messages') as prep: - client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - with mock.patch.object(transports.CatalogServiceTransport, '_prep_wrapped_messages') as prep: - transport_class = CatalogServiceClient.get_transport_class() - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - -@pytest.mark.asyncio -async def test_transport_close_async(): - client = CatalogServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - with mock.patch.object(type(getattr(client.transport, "grpc_channel")), "close") as close: - async with client: - close.assert_not_called() - close.assert_called_once() - -def test_transport_close(): - transports = { - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport - ) - with mock.patch.object(type(getattr(client.transport, close_name)), "close") as close: - with client: - close.assert_not_called() - close.assert_called_once() - -def test_client_ctx(): - transports = [ - 'grpc', - ] - for transport in transports: - client = CatalogServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport - ) - # Test client calls underlying transport. - with mock.patch.object(type(client.transport), "close") as close: - close.assert_not_called() - with client: - pass - close.assert_called() - -@pytest.mark.parametrize("client_class,transport_class", [ - (CatalogServiceClient, transports.CatalogServiceGrpcTransport), - (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport), -]) -def test_api_key_credentials(client_class, transport_class): - with mock.patch.object( - google.auth._default, "get_api_key_credentials", create=True - ) as get_api_key_credentials: - mock_cred = mock.Mock() - get_api_key_credentials.return_value = mock_cred - options = client_options.ClientOptions() - options.api_key = "api_key" - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=mock_cred, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) diff --git a/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_completion_service.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_completion_service.py deleted file mode 100644 index 3426748c..00000000 --- a/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_completion_service.py +++ /dev/null @@ -1,1357 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import os -import mock - -import grpc -from grpc.experimental import aio -import math -import pytest -from proto.marshal.rules.dates import DurationRule, TimestampRule - - -from google.api_core import client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import future -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers -from google.api_core import grpc_helpers_async -from google.api_core import operation_async # type: ignore -from google.api_core import operations_v1 -from google.api_core import path_template -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.cloud.retail_v2.services.completion_service import CompletionServiceAsyncClient -from google.cloud.retail_v2.services.completion_service import CompletionServiceClient -from google.cloud.retail_v2.services.completion_service import transports -from google.cloud.retail_v2.types import completion_service -from google.cloud.retail_v2.types import import_config -from google.longrunning import operations_pb2 -from google.oauth2 import service_account -from google.type import date_pb2 # type: ignore -import google.auth - - -def client_cert_source_callback(): - return b"cert bytes", b"key bytes" - - -# If default endpoint is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint(client): - return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT - - -def test__get_default_mtls_endpoint(): - api_endpoint = "example.googleapis.com" - api_mtls_endpoint = "example.mtls.googleapis.com" - sandbox_endpoint = "example.sandbox.googleapis.com" - sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" - non_googleapi = "api.example.com" - - assert CompletionServiceClient._get_default_mtls_endpoint(None) is None - assert CompletionServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint - assert CompletionServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint - assert CompletionServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint - assert CompletionServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint - assert CompletionServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi - - -@pytest.mark.parametrize("client_class", [ - CompletionServiceClient, - CompletionServiceAsyncClient, -]) -def test_completion_service_client_from_service_account_info(client_class): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: - factory.return_value = creds - info = {"valid": True} - client = client_class.from_service_account_info(info) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == 'retail.googleapis.com:443' - - -@pytest.mark.parametrize("transport_class,transport_name", [ - (transports.CompletionServiceGrpcTransport, "grpc"), - (transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -def test_completion_service_client_service_account_always_use_jwt(transport_class, transport_name): - with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=True) - use_jwt.assert_called_once_with(True) - - with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=False) - use_jwt.assert_not_called() - - -@pytest.mark.parametrize("client_class", [ - CompletionServiceClient, - CompletionServiceAsyncClient, -]) -def test_completion_service_client_from_service_account_file(client_class): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: - factory.return_value = creds - client = client_class.from_service_account_file("dummy/file/path.json") - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - client = client_class.from_service_account_json("dummy/file/path.json") - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == 'retail.googleapis.com:443' - - -def test_completion_service_client_get_transport_class(): - transport = CompletionServiceClient.get_transport_class() - available_transports = [ - transports.CompletionServiceGrpcTransport, - ] - assert transport in available_transports - - transport = CompletionServiceClient.get_transport_class("grpc") - assert transport == transports.CompletionServiceGrpcTransport - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc"), - (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -@mock.patch.object(CompletionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceClient)) -@mock.patch.object(CompletionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceAsyncClient)) -def test_completion_service_client_client_options(client_class, transport_class, transport_name): - # Check that if channel is provided we won't create a new one. - with mock.patch.object(CompletionServiceClient, 'get_transport_class') as gtc: - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ) - client = client_class(transport=transport) - gtc.assert_not_called() - - # Check that if channel is provided via str we will create a new one. - with mock.patch.object(CompletionServiceClient, 'get_transport_class') as gtc: - client = client_class(transport=transport_name) - gtc.assert_called() - - # Check the case api_endpoint is provided. - options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name, client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class(transport=transport_name) - - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): - with pytest.raises(ValueError): - client = client_class(transport=transport_name) - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - -@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ - (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc", "true"), - (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), - (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc", "false"), - (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), -]) -@mock.patch.object(CompletionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceClient)) -@mock.patch.object(CompletionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceAsyncClient)) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_completion_service_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): - # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default - # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. - - # Check the case client_cert_source is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - - if use_client_cert_env == "false": - expected_client_cert_source = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_client_cert_source = client_cert_source_callback - expected_host = client.DEFAULT_MTLS_ENDPOINT - - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case ADC client cert is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - with mock.patch.object(transport_class, '__init__') as patched: - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): - with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): - if use_client_cert_env == "false": - expected_host = client.DEFAULT_ENDPOINT - expected_client_cert_source = None - else: - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_client_cert_source = client_cert_source_callback - - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - with mock.patch.object(transport_class, '__init__') as patched: - with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - -@pytest.mark.parametrize("client_class", [ - CompletionServiceClient, CompletionServiceAsyncClient -]) -@mock.patch.object(CompletionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceClient)) -@mock.patch.object(CompletionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceAsyncClient)) -def test_completion_service_client_get_mtls_endpoint_and_cert_source(client_class): - mock_client_cert_source = mock.Mock() - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - mock_api_endpoint = "foo" - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source == mock_client_cert_source - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - mock_client_cert_source = mock.Mock() - mock_api_endpoint = "foo" - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): - with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source == mock_client_cert_source - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc"), - (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -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"], - ) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=["1", "2"], - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc"), - (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -def test_completion_service_client_client_options_credentials_file(client_class, transport_class, transport_name): - # Check the case credentials file is provided. - options = client_options.ClientOptions( - credentials_file="credentials.json" - ) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file="credentials.json", - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - -def test_completion_service_client_client_options_from_dict(): - with mock.patch('google.cloud.retail_v2.services.completion_service.transports.CompletionServiceGrpcTransport.__init__') as grpc_transport: - grpc_transport.return_value = None - client = CompletionServiceClient( - client_options={'api_endpoint': 'squid.clam.whelk'} - ) - grpc_transport.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - -@pytest.mark.parametrize("request_type", [ - completion_service.CompleteQueryRequest, - dict, -]) -def test_complete_query(request_type, transport: str = 'grpc'): - client = CompletionServiceClient( - 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.complete_query), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = completion_service.CompleteQueryResponse( - attribution_token='attribution_token_value', - ) - response = client.complete_query(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == completion_service.CompleteQueryRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, completion_service.CompleteQueryResponse) - assert response.attribution_token == 'attribution_token_value' - - -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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.complete_query), - '__call__') as call: - client.complete_query() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == completion_service.CompleteQueryRequest() - - -@pytest.mark.asyncio -async def test_complete_query_async(transport: str = 'grpc_asyncio', request_type=completion_service.CompleteQueryRequest): - client = CompletionServiceAsyncClient( - 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.complete_query), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(completion_service.CompleteQueryResponse( - attribution_token='attribution_token_value', - )) - response = await client.complete_query(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == completion_service.CompleteQueryRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, completion_service.CompleteQueryResponse) - assert response.attribution_token == 'attribution_token_value' - - -@pytest.mark.asyncio -async def test_complete_query_async_from_dict(): - await test_complete_query_async(request_type=dict) - - -def test_complete_query_field_headers(): - 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. - request = completion_service.CompleteQueryRequest() - - request.catalog = 'catalog/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.complete_query), - '__call__') as call: - call.return_value = completion_service.CompleteQueryResponse() - client.complete_query(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', - 'catalog=catalog/value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_complete_query_field_headers_async(): - client = CompletionServiceAsyncClient( - 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 = completion_service.CompleteQueryRequest() - - request.catalog = 'catalog/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.complete_query), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(completion_service.CompleteQueryResponse()) - await client.complete_query(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', - 'catalog=catalog/value', - ) in kw['metadata'] - - -@pytest.mark.parametrize("request_type", [ - import_config.ImportCompletionDataRequest, - dict, -]) -def test_import_completion_data(request_type, transport: str = 'grpc'): - client = CompletionServiceClient( - 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.import_completion_data), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation(name='operations/spam') - response = client.import_completion_data(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == import_config.ImportCompletionDataRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.import_completion_data), - '__call__') as call: - client.import_completion_data() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == import_config.ImportCompletionDataRequest() - - -@pytest.mark.asyncio -async def test_import_completion_data_async(transport: str = 'grpc_asyncio', request_type=import_config.ImportCompletionDataRequest): - client = CompletionServiceAsyncClient( - 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.import_completion_data), - '__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.import_completion_data(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == import_config.ImportCompletionDataRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -@pytest.mark.asyncio -async def test_import_completion_data_async_from_dict(): - await test_import_completion_data_async(request_type=dict) - - -def test_import_completion_data_field_headers(): - 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. - request = import_config.ImportCompletionDataRequest() - - request.parent = 'parent/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.import_completion_data), - '__call__') as call: - call.return_value = operations_pb2.Operation(name='operations/op') - client.import_completion_data(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'parent=parent/value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_import_completion_data_field_headers_async(): - client = CompletionServiceAsyncClient( - 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 = import_config.ImportCompletionDataRequest() - - request.parent = 'parent/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.import_completion_data), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) - await client.import_completion_data(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'parent=parent/value', - ) in kw['metadata'] - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.CompletionServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = CompletionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.CompletionServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = CompletionServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.CompletionServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = CompletionServiceClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = mock.Mock() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = CompletionServiceClient( - client_options=options, - credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.CompletionServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = CompletionServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.CompletionServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = CompletionServiceClient(transport=transport) - assert client.transport is transport - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.CompletionServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.CompletionServiceGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize("transport_class", [ - transports.CompletionServiceGrpcTransport, - transports.CompletionServiceGrpcAsyncIOTransport, -]) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, 'default') as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - -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, - ) - -def test_completion_service_base_transport_error(): - # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(core_exceptions.DuplicateCredentialArgs): - transport = transports.CompletionServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - credentials_file="credentials.json" - ) - - -def test_completion_service_base_transport(): - # Instantiate the base transport. - with mock.patch('google.cloud.retail_v2.services.completion_service.transports.CompletionServiceTransport.__init__') as Transport: - Transport.return_value = None - transport = transports.CompletionServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Every method on the transport should just blindly - # raise NotImplementedError. - methods = ( - 'complete_query', - 'import_completion_data', - ) - for method in methods: - with pytest.raises(NotImplementedError): - getattr(transport, method)(request=object()) - - with pytest.raises(NotImplementedError): - transport.close() - - # Additionally, the LRO client (a property) should - # also raise NotImplementedError - with pytest.raises(NotImplementedError): - transport.operations_client - - -def test_completion_service_base_transport_with_credentials_file(): - # Instantiate the base transport with a credentials file - with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('google.cloud.retail_v2.services.completion_service.transports.CompletionServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.CompletionServiceTransport( - credentials_file="credentials.json", - quota_project_id="octopus", - ) - load_creds.assert_called_once_with("credentials.json", - scopes=None, - default_scopes=( - 'https://www.googleapis.com/auth/cloud-platform', -), - quota_project_id="octopus", - ) - - -def test_completion_service_base_transport_with_adc(): - # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(google.auth, 'default', autospec=True) as adc, mock.patch('google.cloud.retail_v2.services.completion_service.transports.CompletionServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.CompletionServiceTransport() - adc.assert_called_once() - - -def test_completion_service_auth_adc(): - # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(google.auth, 'default', autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - CompletionServiceClient() - adc.assert_called_once_with( - scopes=None, - default_scopes=( - 'https://www.googleapis.com/auth/cloud-platform', -), - quota_project_id=None, - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.CompletionServiceGrpcTransport, - transports.CompletionServiceGrpcAsyncIOTransport, - ], -) -def test_completion_service_transport_auth_adc(transport_class): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, 'default', autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class(quota_project_id="octopus", scopes=["1", "2"]) - adc.assert_called_once_with( - scopes=["1", "2"], - default_scopes=( 'https://www.googleapis.com/auth/cloud-platform',), - quota_project_id="octopus", - ) - - -@pytest.mark.parametrize( - "transport_class,grpc_helpers", - [ - (transports.CompletionServiceGrpcTransport, grpc_helpers), - (transports.CompletionServiceGrpcAsyncIOTransport, grpc_helpers_async) - ], -) -def test_completion_service_transport_create_channel(transport_class, grpc_helpers): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( - grpc_helpers, "create_channel", autospec=True - ) as create_channel: - creds = ga_credentials.AnonymousCredentials() - adc.return_value = (creds, None) - transport_class( - quota_project_id="octopus", - scopes=["1", "2"] - ) - - create_channel.assert_called_with( - "retail.googleapis.com:443", - credentials=creds, - credentials_file=None, - quota_project_id="octopus", - default_scopes=( - 'https://www.googleapis.com/auth/cloud-platform', -), - scopes=["1", "2"], - default_host="retail.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize("transport_class", [transports.CompletionServiceGrpcTransport, transports.CompletionServiceGrpcAsyncIOTransport]) -def test_completion_service_grpc_transport_client_cert_source_for_mtls( - transport_class -): - cred = ga_credentials.AnonymousCredentials() - - # Check ssl_channel_credentials is used if provided. - with mock.patch.object(transport_class, "create_channel") as mock_create_channel: - mock_ssl_channel_creds = mock.Mock() - transport_class( - host="squid.clam.whelk", - credentials=cred, - ssl_channel_credentials=mock_ssl_channel_creds - ) - mock_create_channel.assert_called_once_with( - "squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_channel_creds, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls - # is used. - with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): - with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: - transport_class( - credentials=cred, - client_cert_source_for_mtls=client_cert_source_callback - ) - expected_cert, expected_key = client_cert_source_callback() - mock_ssl_cred.assert_called_once_with( - certificate_chain=expected_cert, - private_key=expected_key - ) - - -def test_completion_service_host_no_port(): - client = CompletionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), - ) - assert client.transport._host == 'retail.googleapis.com:443' - - -def test_completion_service_host_with_port(): - client = CompletionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), - ) - assert client.transport._host == 'retail.googleapis.com:8000' - -def test_completion_service_grpc_transport_channel(): - channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.CompletionServiceGrpcTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -def test_completion_service_grpc_asyncio_transport_channel(): - channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.CompletionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.parametrize("transport_class", [transports.CompletionServiceGrpcTransport, transports.CompletionServiceGrpcAsyncIOTransport]) -def test_completion_service_transport_channel_mtls_with_client_cert_source( - transport_class -): - with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: - with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - cred = ga_credentials.AnonymousCredentials() - with pytest.warns(DeprecationWarning): - with mock.patch.object(google.auth, 'default') as adc: - adc.return_value = (cred, None) - transport = transport_class( - host="squid.clam.whelk", - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - adc.assert_called_once() - - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - assert transport._ssl_channel_credentials == mock_ssl_cred - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.parametrize("transport_class", [transports.CompletionServiceGrpcTransport, transports.CompletionServiceGrpcAsyncIOTransport]) -def test_completion_service_transport_channel_mtls_with_adc( - transport_class -): - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - mock_cred = mock.Mock() - - with pytest.warns(DeprecationWarning): - transport = transport_class( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=None, - ) - - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - - -def test_completion_service_grpc_lro_client(): - client = CompletionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - transport = client.transport - - # Ensure that we have a api-core operations client. - assert isinstance( - transport.operations_client, - operations_v1.OperationsClient, - ) - - # Ensure that subsequent calls to the property send the exact same object. - assert transport.operations_client is transport.operations_client - - -def test_completion_service_grpc_lro_async_client(): - client = CompletionServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc_asyncio', - ) - transport = client.transport - - # Ensure that we have a api-core operations client. - assert isinstance( - transport.operations_client, - operations_v1.OperationsAsyncClient, - ) - - # Ensure that subsequent calls to the property send the exact same object. - assert transport.operations_client is transport.operations_client - - -def test_catalog_path(): - project = "squid" - location = "clam" - catalog = "whelk" - expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) - actual = CompletionServiceClient.catalog_path(project, location, catalog) - assert expected == actual - - -def test_parse_catalog_path(): - expected = { - "project": "octopus", - "location": "oyster", - "catalog": "nudibranch", - } - path = CompletionServiceClient.catalog_path(**expected) - - # Check that the path construction is reversible. - actual = CompletionServiceClient.parse_catalog_path(path) - assert expected == actual - -def test_common_billing_account_path(): - billing_account = "cuttlefish" - expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) - actual = CompletionServiceClient.common_billing_account_path(billing_account) - assert expected == actual - - -def test_parse_common_billing_account_path(): - expected = { - "billing_account": "mussel", - } - path = CompletionServiceClient.common_billing_account_path(**expected) - - # Check that the path construction is reversible. - actual = CompletionServiceClient.parse_common_billing_account_path(path) - assert expected == actual - -def test_common_folder_path(): - folder = "winkle" - expected = "folders/{folder}".format(folder=folder, ) - actual = CompletionServiceClient.common_folder_path(folder) - assert expected == actual - - -def test_parse_common_folder_path(): - expected = { - "folder": "nautilus", - } - path = CompletionServiceClient.common_folder_path(**expected) - - # Check that the path construction is reversible. - actual = CompletionServiceClient.parse_common_folder_path(path) - assert expected == actual - -def test_common_organization_path(): - organization = "scallop" - expected = "organizations/{organization}".format(organization=organization, ) - actual = CompletionServiceClient.common_organization_path(organization) - assert expected == actual - - -def test_parse_common_organization_path(): - expected = { - "organization": "abalone", - } - path = CompletionServiceClient.common_organization_path(**expected) - - # Check that the path construction is reversible. - actual = CompletionServiceClient.parse_common_organization_path(path) - assert expected == actual - -def test_common_project_path(): - project = "squid" - expected = "projects/{project}".format(project=project, ) - actual = CompletionServiceClient.common_project_path(project) - assert expected == actual - - -def test_parse_common_project_path(): - expected = { - "project": "clam", - } - path = CompletionServiceClient.common_project_path(**expected) - - # Check that the path construction is reversible. - actual = CompletionServiceClient.parse_common_project_path(path) - assert expected == actual - -def test_common_location_path(): - project = "whelk" - location = "octopus" - expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) - actual = CompletionServiceClient.common_location_path(project, location) - assert expected == actual - - -def test_parse_common_location_path(): - expected = { - "project": "oyster", - "location": "nudibranch", - } - path = CompletionServiceClient.common_location_path(**expected) - - # Check that the path construction is reversible. - actual = CompletionServiceClient.parse_common_location_path(path) - assert expected == actual - - -def test_client_with_default_client_info(): - client_info = gapic_v1.client_info.ClientInfo() - - with mock.patch.object(transports.CompletionServiceTransport, '_prep_wrapped_messages') as prep: - client = CompletionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - with mock.patch.object(transports.CompletionServiceTransport, '_prep_wrapped_messages') as prep: - transport_class = CompletionServiceClient.get_transport_class() - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - -@pytest.mark.asyncio -async def test_transport_close_async(): - client = CompletionServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - with mock.patch.object(type(getattr(client.transport, "grpc_channel")), "close") as close: - async with client: - close.assert_not_called() - close.assert_called_once() - -def test_transport_close(): - transports = { - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = CompletionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport - ) - with mock.patch.object(type(getattr(client.transport, close_name)), "close") as close: - with client: - close.assert_not_called() - close.assert_called_once() - -def test_client_ctx(): - transports = [ - 'grpc', - ] - for transport in transports: - client = CompletionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport - ) - # Test client calls underlying transport. - with mock.patch.object(type(client.transport), "close") as close: - close.assert_not_called() - with client: - pass - close.assert_called() - -@pytest.mark.parametrize("client_class,transport_class", [ - (CompletionServiceClient, transports.CompletionServiceGrpcTransport), - (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport), -]) -def test_api_key_credentials(client_class, transport_class): - with mock.patch.object( - google.auth._default, "get_api_key_credentials", create=True - ) as get_api_key_credentials: - mock_cred = mock.Mock() - get_api_key_credentials.return_value = mock_cred - options = client_options.ClientOptions() - options.api_key = "api_key" - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=mock_cred, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) diff --git a/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_prediction_service.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_prediction_service.py deleted file mode 100644 index cb282921..00000000 --- a/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_prediction_service.py +++ /dev/null @@ -1,1184 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import os -import mock - -import grpc -from grpc.experimental import aio -import math -import pytest -from proto.marshal.rules.dates import DurationRule, TimestampRule - - -from google.api_core import client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers -from google.api_core import grpc_helpers_async -from google.api_core import path_template -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.cloud.retail_v2.services.prediction_service import PredictionServiceAsyncClient -from google.cloud.retail_v2.services.prediction_service import PredictionServiceClient -from google.cloud.retail_v2.services.prediction_service import transports -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 user_event -from google.oauth2 import service_account -from google.protobuf import duration_pb2 # type: ignore -from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import struct_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore -from google.protobuf import wrappers_pb2 # type: ignore -import google.auth - - -def client_cert_source_callback(): - return b"cert bytes", b"key bytes" - - -# If default endpoint is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint(client): - return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT - - -def test__get_default_mtls_endpoint(): - api_endpoint = "example.googleapis.com" - api_mtls_endpoint = "example.mtls.googleapis.com" - sandbox_endpoint = "example.sandbox.googleapis.com" - sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" - non_googleapi = "api.example.com" - - assert PredictionServiceClient._get_default_mtls_endpoint(None) is None - assert PredictionServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint - assert PredictionServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint - assert PredictionServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint - assert PredictionServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint - assert PredictionServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi - - -@pytest.mark.parametrize("client_class", [ - PredictionServiceClient, - PredictionServiceAsyncClient, -]) -def test_prediction_service_client_from_service_account_info(client_class): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: - factory.return_value = creds - info = {"valid": True} - client = client_class.from_service_account_info(info) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == 'retail.googleapis.com:443' - - -@pytest.mark.parametrize("transport_class,transport_name", [ - (transports.PredictionServiceGrpcTransport, "grpc"), - (transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -def test_prediction_service_client_service_account_always_use_jwt(transport_class, transport_name): - with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=True) - use_jwt.assert_called_once_with(True) - - with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=False) - use_jwt.assert_not_called() - - -@pytest.mark.parametrize("client_class", [ - PredictionServiceClient, - PredictionServiceAsyncClient, -]) -def test_prediction_service_client_from_service_account_file(client_class): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: - factory.return_value = creds - client = client_class.from_service_account_file("dummy/file/path.json") - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - client = client_class.from_service_account_json("dummy/file/path.json") - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == 'retail.googleapis.com:443' - - -def test_prediction_service_client_get_transport_class(): - transport = PredictionServiceClient.get_transport_class() - available_transports = [ - transports.PredictionServiceGrpcTransport, - ] - assert transport in available_transports - - transport = PredictionServiceClient.get_transport_class("grpc") - assert transport == transports.PredictionServiceGrpcTransport - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc"), - (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -@mock.patch.object(PredictionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceClient)) -@mock.patch.object(PredictionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceAsyncClient)) -def test_prediction_service_client_client_options(client_class, transport_class, transport_name): - # Check that if channel is provided we won't create a new one. - with mock.patch.object(PredictionServiceClient, 'get_transport_class') as gtc: - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ) - client = client_class(transport=transport) - gtc.assert_not_called() - - # Check that if channel is provided via str we will create a new one. - with mock.patch.object(PredictionServiceClient, 'get_transport_class') as gtc: - client = client_class(transport=transport_name) - gtc.assert_called() - - # Check the case api_endpoint is provided. - options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name, client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class(transport=transport_name) - - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): - with pytest.raises(ValueError): - client = client_class(transport=transport_name) - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - -@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ - (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc", "true"), - (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), - (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc", "false"), - (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), -]) -@mock.patch.object(PredictionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceClient)) -@mock.patch.object(PredictionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceAsyncClient)) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_prediction_service_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): - # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default - # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. - - # Check the case client_cert_source is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - - if use_client_cert_env == "false": - expected_client_cert_source = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_client_cert_source = client_cert_source_callback - expected_host = client.DEFAULT_MTLS_ENDPOINT - - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case ADC client cert is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - with mock.patch.object(transport_class, '__init__') as patched: - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): - with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): - if use_client_cert_env == "false": - expected_host = client.DEFAULT_ENDPOINT - expected_client_cert_source = None - else: - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_client_cert_source = client_cert_source_callback - - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - with mock.patch.object(transport_class, '__init__') as patched: - with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - -@pytest.mark.parametrize("client_class", [ - PredictionServiceClient, PredictionServiceAsyncClient -]) -@mock.patch.object(PredictionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceClient)) -@mock.patch.object(PredictionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceAsyncClient)) -def test_prediction_service_client_get_mtls_endpoint_and_cert_source(client_class): - mock_client_cert_source = mock.Mock() - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - mock_api_endpoint = "foo" - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source == mock_client_cert_source - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - mock_client_cert_source = mock.Mock() - mock_api_endpoint = "foo" - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): - with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source == mock_client_cert_source - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc"), - (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -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"], - ) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=["1", "2"], - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc"), - (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -def test_prediction_service_client_client_options_credentials_file(client_class, transport_class, transport_name): - # Check the case credentials file is provided. - options = client_options.ClientOptions( - credentials_file="credentials.json" - ) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file="credentials.json", - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - -def test_prediction_service_client_client_options_from_dict(): - with mock.patch('google.cloud.retail_v2.services.prediction_service.transports.PredictionServiceGrpcTransport.__init__') as grpc_transport: - grpc_transport.return_value = None - client = PredictionServiceClient( - client_options={'api_endpoint': 'squid.clam.whelk'} - ) - grpc_transport.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - -@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, - ) - - # 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.predict), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = prediction_service.PredictResponse( - attribution_token='attribution_token_value', - missing_ids=['missing_ids_value'], - validate_only=True, - ) - response = client.predict(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == prediction_service.PredictRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, prediction_service.PredictResponse) - assert response.attribution_token == 'attribution_token_value' - assert response.missing_ids == ['missing_ids_value'] - assert response.validate_only is True - - -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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.predict), - '__call__') as call: - client.predict() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == prediction_service.PredictRequest() - - -@pytest.mark.asyncio -async def test_predict_async(transport: str = 'grpc_asyncio', request_type=prediction_service.PredictRequest): - client = PredictionServiceAsyncClient( - 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.predict), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(prediction_service.PredictResponse( - attribution_token='attribution_token_value', - missing_ids=['missing_ids_value'], - validate_only=True, - )) - response = await client.predict(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == prediction_service.PredictRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, prediction_service.PredictResponse) - assert response.attribution_token == 'attribution_token_value' - assert response.missing_ids == ['missing_ids_value'] - assert response.validate_only is True - - -@pytest.mark.asyncio -async def test_predict_async_from_dict(): - await test_predict_async(request_type=dict) - - -def test_predict_field_headers(): - 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. - request = prediction_service.PredictRequest() - - request.placement = 'placement/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.predict), - '__call__') as call: - call.return_value = prediction_service.PredictResponse() - client.predict(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', - 'placement=placement/value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_predict_field_headers_async(): - client = PredictionServiceAsyncClient( - 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 = prediction_service.PredictRequest() - - request.placement = 'placement/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.predict), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(prediction_service.PredictResponse()) - await client.predict(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', - 'placement=placement/value', - ) in kw['metadata'] - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.PredictionServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = PredictionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.PredictionServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = PredictionServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.PredictionServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = PredictionServiceClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = mock.Mock() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = PredictionServiceClient( - client_options=options, - credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.PredictionServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = PredictionServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.PredictionServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = PredictionServiceClient(transport=transport) - assert client.transport is transport - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.PredictionServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.PredictionServiceGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize("transport_class", [ - transports.PredictionServiceGrpcTransport, - transports.PredictionServiceGrpcAsyncIOTransport, -]) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, 'default') as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - -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, - ) - -def test_prediction_service_base_transport_error(): - # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(core_exceptions.DuplicateCredentialArgs): - transport = transports.PredictionServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - credentials_file="credentials.json" - ) - - -def test_prediction_service_base_transport(): - # Instantiate the base transport. - with mock.patch('google.cloud.retail_v2.services.prediction_service.transports.PredictionServiceTransport.__init__') as Transport: - Transport.return_value = None - transport = transports.PredictionServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Every method on the transport should just blindly - # raise NotImplementedError. - methods = ( - 'predict', - ) - for method in methods: - with pytest.raises(NotImplementedError): - getattr(transport, method)(request=object()) - - with pytest.raises(NotImplementedError): - transport.close() - - -def test_prediction_service_base_transport_with_credentials_file(): - # Instantiate the base transport with a credentials file - with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('google.cloud.retail_v2.services.prediction_service.transports.PredictionServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.PredictionServiceTransport( - credentials_file="credentials.json", - quota_project_id="octopus", - ) - load_creds.assert_called_once_with("credentials.json", - scopes=None, - default_scopes=( - 'https://www.googleapis.com/auth/cloud-platform', -), - quota_project_id="octopus", - ) - - -def test_prediction_service_base_transport_with_adc(): - # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(google.auth, 'default', autospec=True) as adc, mock.patch('google.cloud.retail_v2.services.prediction_service.transports.PredictionServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.PredictionServiceTransport() - adc.assert_called_once() - - -def test_prediction_service_auth_adc(): - # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(google.auth, 'default', autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - PredictionServiceClient() - adc.assert_called_once_with( - scopes=None, - default_scopes=( - 'https://www.googleapis.com/auth/cloud-platform', -), - quota_project_id=None, - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.PredictionServiceGrpcTransport, - transports.PredictionServiceGrpcAsyncIOTransport, - ], -) -def test_prediction_service_transport_auth_adc(transport_class): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, 'default', autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class(quota_project_id="octopus", scopes=["1", "2"]) - adc.assert_called_once_with( - scopes=["1", "2"], - default_scopes=( 'https://www.googleapis.com/auth/cloud-platform',), - quota_project_id="octopus", - ) - - -@pytest.mark.parametrize( - "transport_class,grpc_helpers", - [ - (transports.PredictionServiceGrpcTransport, grpc_helpers), - (transports.PredictionServiceGrpcAsyncIOTransport, grpc_helpers_async) - ], -) -def test_prediction_service_transport_create_channel(transport_class, grpc_helpers): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( - grpc_helpers, "create_channel", autospec=True - ) as create_channel: - creds = ga_credentials.AnonymousCredentials() - adc.return_value = (creds, None) - transport_class( - quota_project_id="octopus", - scopes=["1", "2"] - ) - - create_channel.assert_called_with( - "retail.googleapis.com:443", - credentials=creds, - credentials_file=None, - quota_project_id="octopus", - default_scopes=( - 'https://www.googleapis.com/auth/cloud-platform', -), - scopes=["1", "2"], - default_host="retail.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize("transport_class", [transports.PredictionServiceGrpcTransport, transports.PredictionServiceGrpcAsyncIOTransport]) -def test_prediction_service_grpc_transport_client_cert_source_for_mtls( - transport_class -): - cred = ga_credentials.AnonymousCredentials() - - # Check ssl_channel_credentials is used if provided. - with mock.patch.object(transport_class, "create_channel") as mock_create_channel: - mock_ssl_channel_creds = mock.Mock() - transport_class( - host="squid.clam.whelk", - credentials=cred, - ssl_channel_credentials=mock_ssl_channel_creds - ) - mock_create_channel.assert_called_once_with( - "squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_channel_creds, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls - # is used. - with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): - with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: - transport_class( - credentials=cred, - client_cert_source_for_mtls=client_cert_source_callback - ) - expected_cert, expected_key = client_cert_source_callback() - mock_ssl_cred.assert_called_once_with( - certificate_chain=expected_cert, - private_key=expected_key - ) - - -def test_prediction_service_host_no_port(): - client = PredictionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), - ) - assert client.transport._host == 'retail.googleapis.com:443' - - -def test_prediction_service_host_with_port(): - client = PredictionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), - ) - assert client.transport._host == 'retail.googleapis.com:8000' - -def test_prediction_service_grpc_transport_channel(): - channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -def test_prediction_service_grpc_asyncio_transport_channel(): - channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.parametrize("transport_class", [transports.PredictionServiceGrpcTransport, transports.PredictionServiceGrpcAsyncIOTransport]) -def test_prediction_service_transport_channel_mtls_with_client_cert_source( - transport_class -): - with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: - with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - cred = ga_credentials.AnonymousCredentials() - with pytest.warns(DeprecationWarning): - with mock.patch.object(google.auth, 'default') as adc: - adc.return_value = (cred, None) - transport = transport_class( - host="squid.clam.whelk", - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - adc.assert_called_once() - - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - assert transport._ssl_channel_credentials == mock_ssl_cred - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.parametrize("transport_class", [transports.PredictionServiceGrpcTransport, transports.PredictionServiceGrpcAsyncIOTransport]) -def test_prediction_service_transport_channel_mtls_with_adc( - transport_class -): - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - mock_cred = mock.Mock() - - with pytest.warns(DeprecationWarning): - transport = transport_class( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=None, - ) - - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - - -def test_product_path(): - project = "squid" - location = "clam" - catalog = "whelk" - branch = "octopus" - product = "oyster" - expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, product=product, ) - actual = PredictionServiceClient.product_path(project, location, catalog, branch, product) - assert expected == actual - - -def test_parse_product_path(): - expected = { - "project": "nudibranch", - "location": "cuttlefish", - "catalog": "mussel", - "branch": "winkle", - "product": "nautilus", - } - path = PredictionServiceClient.product_path(**expected) - - # Check that the path construction is reversible. - actual = PredictionServiceClient.parse_product_path(path) - assert expected == actual - -def test_common_billing_account_path(): - billing_account = "scallop" - expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) - actual = PredictionServiceClient.common_billing_account_path(billing_account) - assert expected == actual - - -def test_parse_common_billing_account_path(): - expected = { - "billing_account": "abalone", - } - path = PredictionServiceClient.common_billing_account_path(**expected) - - # Check that the path construction is reversible. - actual = PredictionServiceClient.parse_common_billing_account_path(path) - assert expected == actual - -def test_common_folder_path(): - folder = "squid" - expected = "folders/{folder}".format(folder=folder, ) - actual = PredictionServiceClient.common_folder_path(folder) - assert expected == actual - - -def test_parse_common_folder_path(): - expected = { - "folder": "clam", - } - path = PredictionServiceClient.common_folder_path(**expected) - - # Check that the path construction is reversible. - actual = PredictionServiceClient.parse_common_folder_path(path) - assert expected == actual - -def test_common_organization_path(): - organization = "whelk" - expected = "organizations/{organization}".format(organization=organization, ) - actual = PredictionServiceClient.common_organization_path(organization) - assert expected == actual - - -def test_parse_common_organization_path(): - expected = { - "organization": "octopus", - } - path = PredictionServiceClient.common_organization_path(**expected) - - # Check that the path construction is reversible. - actual = PredictionServiceClient.parse_common_organization_path(path) - assert expected == actual - -def test_common_project_path(): - project = "oyster" - expected = "projects/{project}".format(project=project, ) - actual = PredictionServiceClient.common_project_path(project) - assert expected == actual - - -def test_parse_common_project_path(): - expected = { - "project": "nudibranch", - } - path = PredictionServiceClient.common_project_path(**expected) - - # Check that the path construction is reversible. - actual = PredictionServiceClient.parse_common_project_path(path) - assert expected == actual - -def test_common_location_path(): - project = "cuttlefish" - location = "mussel" - expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) - actual = PredictionServiceClient.common_location_path(project, location) - assert expected == actual - - -def test_parse_common_location_path(): - expected = { - "project": "winkle", - "location": "nautilus", - } - path = PredictionServiceClient.common_location_path(**expected) - - # Check that the path construction is reversible. - actual = PredictionServiceClient.parse_common_location_path(path) - assert expected == actual - - -def test_client_with_default_client_info(): - client_info = gapic_v1.client_info.ClientInfo() - - with mock.patch.object(transports.PredictionServiceTransport, '_prep_wrapped_messages') as prep: - client = PredictionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - with mock.patch.object(transports.PredictionServiceTransport, '_prep_wrapped_messages') as prep: - transport_class = PredictionServiceClient.get_transport_class() - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - -@pytest.mark.asyncio -async def test_transport_close_async(): - client = PredictionServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - with mock.patch.object(type(getattr(client.transport, "grpc_channel")), "close") as close: - async with client: - close.assert_not_called() - close.assert_called_once() - -def test_transport_close(): - transports = { - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = PredictionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport - ) - with mock.patch.object(type(getattr(client.transport, close_name)), "close") as close: - with client: - close.assert_not_called() - close.assert_called_once() - -def test_client_ctx(): - transports = [ - 'grpc', - ] - for transport in transports: - client = PredictionServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport - ) - # Test client calls underlying transport. - with mock.patch.object(type(client.transport), "close") as close: - close.assert_not_called() - with client: - pass - close.assert_called() - -@pytest.mark.parametrize("client_class,transport_class", [ - (PredictionServiceClient, transports.PredictionServiceGrpcTransport), - (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport), -]) -def test_api_key_credentials(client_class, transport_class): - with mock.patch.object( - google.auth._default, "get_api_key_credentials", create=True - ) as get_api_key_credentials: - mock_cred = mock.Mock() - get_api_key_credentials.return_value = mock_cred - options = client_options.ClientOptions() - options.api_key = "api_key" - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=mock_cred, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) diff --git a/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_product_service.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_product_service.py deleted file mode 100644 index 1ab3a754..00000000 --- a/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_product_service.py +++ /dev/null @@ -1,3551 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import os -import mock - -import grpc -from grpc.experimental import aio -import math -import pytest -from proto.marshal.rules.dates import DurationRule, TimestampRule - - -from google.api_core import client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import future -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers -from google.api_core import grpc_helpers_async -from google.api_core import operation_async # type: ignore -from google.api_core import operations_v1 -from google.api_core import path_template -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.cloud.retail_v2.services.product_service import ProductServiceAsyncClient -from google.cloud.retail_v2.services.product_service import ProductServiceClient -from google.cloud.retail_v2.services.product_service import pagers -from google.cloud.retail_v2.services.product_service import transports -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 product as gcr_product -from google.cloud.retail_v2.types import product_service -from google.longrunning import operations_pb2 -from google.oauth2 import service_account -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 -from google.type import date_pb2 # type: ignore -import google.auth - - -def client_cert_source_callback(): - return b"cert bytes", b"key bytes" - - -# If default endpoint is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint(client): - return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT - - -def test__get_default_mtls_endpoint(): - api_endpoint = "example.googleapis.com" - api_mtls_endpoint = "example.mtls.googleapis.com" - sandbox_endpoint = "example.sandbox.googleapis.com" - sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" - non_googleapi = "api.example.com" - - assert ProductServiceClient._get_default_mtls_endpoint(None) is None - assert ProductServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint - assert ProductServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint - assert ProductServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint - assert ProductServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint - assert ProductServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi - - -@pytest.mark.parametrize("client_class", [ - ProductServiceClient, - ProductServiceAsyncClient, -]) -def test_product_service_client_from_service_account_info(client_class): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: - factory.return_value = creds - info = {"valid": True} - client = client_class.from_service_account_info(info) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == 'retail.googleapis.com:443' - - -@pytest.mark.parametrize("transport_class,transport_name", [ - (transports.ProductServiceGrpcTransport, "grpc"), - (transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -def test_product_service_client_service_account_always_use_jwt(transport_class, transport_name): - with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=True) - use_jwt.assert_called_once_with(True) - - with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=False) - use_jwt.assert_not_called() - - -@pytest.mark.parametrize("client_class", [ - ProductServiceClient, - ProductServiceAsyncClient, -]) -def test_product_service_client_from_service_account_file(client_class): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: - factory.return_value = creds - client = client_class.from_service_account_file("dummy/file/path.json") - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - client = client_class.from_service_account_json("dummy/file/path.json") - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == 'retail.googleapis.com:443' - - -def test_product_service_client_get_transport_class(): - transport = ProductServiceClient.get_transport_class() - available_transports = [ - transports.ProductServiceGrpcTransport, - ] - assert transport in available_transports - - transport = ProductServiceClient.get_transport_class("grpc") - assert transport == transports.ProductServiceGrpcTransport - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc"), - (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -@mock.patch.object(ProductServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceClient)) -@mock.patch.object(ProductServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceAsyncClient)) -def test_product_service_client_client_options(client_class, transport_class, transport_name): - # Check that if channel is provided we won't create a new one. - with mock.patch.object(ProductServiceClient, 'get_transport_class') as gtc: - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ) - client = client_class(transport=transport) - gtc.assert_not_called() - - # Check that if channel is provided via str we will create a new one. - with mock.patch.object(ProductServiceClient, 'get_transport_class') as gtc: - client = client_class(transport=transport_name) - gtc.assert_called() - - # Check the case api_endpoint is provided. - options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name, client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class(transport=transport_name) - - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): - with pytest.raises(ValueError): - client = client_class(transport=transport_name) - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - -@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ - (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc", "true"), - (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), - (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc", "false"), - (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), -]) -@mock.patch.object(ProductServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceClient)) -@mock.patch.object(ProductServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceAsyncClient)) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_product_service_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): - # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default - # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. - - # Check the case client_cert_source is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - - if use_client_cert_env == "false": - expected_client_cert_source = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_client_cert_source = client_cert_source_callback - expected_host = client.DEFAULT_MTLS_ENDPOINT - - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case ADC client cert is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - with mock.patch.object(transport_class, '__init__') as patched: - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): - with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): - if use_client_cert_env == "false": - expected_host = client.DEFAULT_ENDPOINT - expected_client_cert_source = None - else: - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_client_cert_source = client_cert_source_callback - - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - with mock.patch.object(transport_class, '__init__') as patched: - with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - -@pytest.mark.parametrize("client_class", [ - ProductServiceClient, ProductServiceAsyncClient -]) -@mock.patch.object(ProductServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceClient)) -@mock.patch.object(ProductServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceAsyncClient)) -def test_product_service_client_get_mtls_endpoint_and_cert_source(client_class): - mock_client_cert_source = mock.Mock() - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - mock_api_endpoint = "foo" - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source == mock_client_cert_source - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - mock_client_cert_source = mock.Mock() - mock_api_endpoint = "foo" - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): - with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source == mock_client_cert_source - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc"), - (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -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"], - ) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=["1", "2"], - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc"), - (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -def test_product_service_client_client_options_credentials_file(client_class, transport_class, transport_name): - # Check the case credentials file is provided. - options = client_options.ClientOptions( - credentials_file="credentials.json" - ) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file="credentials.json", - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - -def test_product_service_client_client_options_from_dict(): - with mock.patch('google.cloud.retail_v2.services.product_service.transports.ProductServiceGrpcTransport.__init__') as grpc_transport: - grpc_transport.return_value = None - client = ProductServiceClient( - client_options={'api_endpoint': 'squid.clam.whelk'} - ) - grpc_transport.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - -@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, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_product), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = gcr_product.Product( - name='name_value', - id='id_value', - type_=gcr_product.Product.Type.PRIMARY, - primary_product_id='primary_product_id_value', - collection_member_ids=['collection_member_ids_value'], - gtin='gtin_value', - categories=['categories_value'], - title='title_value', - brands=['brands_value'], - description='description_value', - language_code='language_code_value', - tags=['tags_value'], - availability=gcr_product.Product.Availability.IN_STOCK, - uri='uri_value', - sizes=['sizes_value'], - materials=['materials_value'], - patterns=['patterns_value'], - conditions=['conditions_value'], - expire_time=timestamp_pb2.Timestamp(seconds=751), - ) - response = client.create_product(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.CreateProductRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, gcr_product.Product) - assert response.name == 'name_value' - assert response.id == 'id_value' - assert response.type_ == gcr_product.Product.Type.PRIMARY - assert response.primary_product_id == 'primary_product_id_value' - assert response.collection_member_ids == ['collection_member_ids_value'] - assert response.gtin == 'gtin_value' - assert response.categories == ['categories_value'] - assert response.title == 'title_value' - assert response.brands == ['brands_value'] - assert response.description == 'description_value' - assert response.language_code == 'language_code_value' - assert response.tags == ['tags_value'] - assert response.availability == gcr_product.Product.Availability.IN_STOCK - assert response.uri == 'uri_value' - assert response.sizes == ['sizes_value'] - assert response.materials == ['materials_value'] - assert response.patterns == ['patterns_value'] - assert response.conditions == ['conditions_value'] - - -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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_product), - '__call__') as call: - client.create_product() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == product_service.CreateProductRequest() - - -@pytest.mark.asyncio -async def test_create_product_async(transport: str = 'grpc_asyncio', request_type=product_service.CreateProductRequest): - 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.create_product), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_product.Product( - name='name_value', - id='id_value', - type_=gcr_product.Product.Type.PRIMARY, - primary_product_id='primary_product_id_value', - collection_member_ids=['collection_member_ids_value'], - gtin='gtin_value', - categories=['categories_value'], - title='title_value', - brands=['brands_value'], - description='description_value', - language_code='language_code_value', - tags=['tags_value'], - availability=gcr_product.Product.Availability.IN_STOCK, - uri='uri_value', - sizes=['sizes_value'], - materials=['materials_value'], - patterns=['patterns_value'], - conditions=['conditions_value'], - )) - response = await client.create_product(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.CreateProductRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, gcr_product.Product) - assert response.name == 'name_value' - assert response.id == 'id_value' - assert response.type_ == gcr_product.Product.Type.PRIMARY - assert response.primary_product_id == 'primary_product_id_value' - assert response.collection_member_ids == ['collection_member_ids_value'] - assert response.gtin == 'gtin_value' - assert response.categories == ['categories_value'] - assert response.title == 'title_value' - assert response.brands == ['brands_value'] - assert response.description == 'description_value' - assert response.language_code == 'language_code_value' - assert response.tags == ['tags_value'] - assert response.availability == gcr_product.Product.Availability.IN_STOCK - assert response.uri == 'uri_value' - assert response.sizes == ['sizes_value'] - assert response.materials == ['materials_value'] - assert response.patterns == ['patterns_value'] - assert response.conditions == ['conditions_value'] - - -@pytest.mark.asyncio -async def test_create_product_async_from_dict(): - await test_create_product_async(request_type=dict) - - -def test_create_product_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.CreateProductRequest() - - request.parent = 'parent/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_product), - '__call__') as call: - call.return_value = gcr_product.Product() - client.create_product(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'parent=parent/value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_create_product_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.CreateProductRequest() - - request.parent = 'parent/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_product), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_product.Product()) - await client.create_product(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'parent=parent/value', - ) in kw['metadata'] - - -def test_create_product_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.create_product), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = gcr_product.Product() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.create_product( - parent='parent_value', - product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), - product_id='product_id_value', - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - arg = args[0].parent - mock_val = 'parent_value' - assert arg == mock_val - arg = args[0].product - mock_val = gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) - assert arg == mock_val - arg = args[0].product_id - mock_val = 'product_id_value' - assert arg == mock_val - - -def test_create_product_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.create_product( - product_service.CreateProductRequest(), - parent='parent_value', - product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), - product_id='product_id_value', - ) - - -@pytest.mark.asyncio -async def test_create_product_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.create_product), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = gcr_product.Product() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_product.Product()) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.create_product( - parent='parent_value', - product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), - product_id='product_id_value', - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].parent - mock_val = 'parent_value' - assert arg == mock_val - arg = args[0].product - mock_val = gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) - assert arg == mock_val - arg = args[0].product_id - mock_val = 'product_id_value' - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_create_product_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.create_product( - product_service.CreateProductRequest(), - parent='parent_value', - product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), - product_id='product_id_value', - ) - - -@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, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_product), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = product.Product( - name='name_value', - id='id_value', - type_=product.Product.Type.PRIMARY, - primary_product_id='primary_product_id_value', - collection_member_ids=['collection_member_ids_value'], - gtin='gtin_value', - categories=['categories_value'], - title='title_value', - brands=['brands_value'], - description='description_value', - language_code='language_code_value', - tags=['tags_value'], - availability=product.Product.Availability.IN_STOCK, - uri='uri_value', - sizes=['sizes_value'], - materials=['materials_value'], - patterns=['patterns_value'], - conditions=['conditions_value'], - expire_time=timestamp_pb2.Timestamp(seconds=751), - ) - response = client.get_product(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.GetProductRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, product.Product) - assert response.name == 'name_value' - assert response.id == 'id_value' - assert response.type_ == product.Product.Type.PRIMARY - assert response.primary_product_id == 'primary_product_id_value' - assert response.collection_member_ids == ['collection_member_ids_value'] - assert response.gtin == 'gtin_value' - assert response.categories == ['categories_value'] - assert response.title == 'title_value' - assert response.brands == ['brands_value'] - assert response.description == 'description_value' - assert response.language_code == 'language_code_value' - assert response.tags == ['tags_value'] - assert response.availability == product.Product.Availability.IN_STOCK - assert response.uri == 'uri_value' - assert response.sizes == ['sizes_value'] - assert response.materials == ['materials_value'] - assert response.patterns == ['patterns_value'] - assert response.conditions == ['conditions_value'] - - -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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_product), - '__call__') as call: - client.get_product() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == product_service.GetProductRequest() - - -@pytest.mark.asyncio -async def test_get_product_async(transport: str = 'grpc_asyncio', request_type=product_service.GetProductRequest): - 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.get_product), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product.Product( - name='name_value', - id='id_value', - type_=product.Product.Type.PRIMARY, - primary_product_id='primary_product_id_value', - collection_member_ids=['collection_member_ids_value'], - gtin='gtin_value', - categories=['categories_value'], - title='title_value', - brands=['brands_value'], - description='description_value', - language_code='language_code_value', - tags=['tags_value'], - availability=product.Product.Availability.IN_STOCK, - uri='uri_value', - sizes=['sizes_value'], - materials=['materials_value'], - patterns=['patterns_value'], - conditions=['conditions_value'], - )) - response = await client.get_product(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.GetProductRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, product.Product) - assert response.name == 'name_value' - assert response.id == 'id_value' - assert response.type_ == product.Product.Type.PRIMARY - assert response.primary_product_id == 'primary_product_id_value' - assert response.collection_member_ids == ['collection_member_ids_value'] - assert response.gtin == 'gtin_value' - assert response.categories == ['categories_value'] - assert response.title == 'title_value' - assert response.brands == ['brands_value'] - assert response.description == 'description_value' - assert response.language_code == 'language_code_value' - assert response.tags == ['tags_value'] - assert response.availability == product.Product.Availability.IN_STOCK - assert response.uri == 'uri_value' - assert response.sizes == ['sizes_value'] - assert response.materials == ['materials_value'] - assert response.patterns == ['patterns_value'] - assert response.conditions == ['conditions_value'] - - -@pytest.mark.asyncio -async def test_get_product_async_from_dict(): - await test_get_product_async(request_type=dict) - - -def test_get_product_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.GetProductRequest() - - request.name = 'name/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_product), - '__call__') as call: - call.return_value = product.Product() - client.get_product(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'name=name/value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_get_product_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.GetProductRequest() - - request.name = 'name/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_product), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product.Product()) - await client.get_product(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'name=name/value', - ) in kw['metadata'] - - -def test_get_product_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.get_product), - '__call__') as call: - # Designate an appropriate return value for the call. - 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', - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - arg = args[0].name - mock_val = 'name_value' - assert arg == mock_val - - -def test_get_product_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.get_product( - product_service.GetProductRequest(), - name='name_value', - ) - - -@pytest.mark.asyncio -async def test_get_product_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.get_product), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = product.Product() - - 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', - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].name - mock_val = 'name_value' - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_get_product_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.get_product( - product_service.GetProductRequest(), - name='name_value', - ) - - -@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, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_products), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = product_service.ListProductsResponse( - next_page_token='next_page_token_value', - ) - response = client.list_products(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.ListProductsRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListProductsPager) - assert response.next_page_token == 'next_page_token_value' - - -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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_products), - '__call__') as call: - client.list_products() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == product_service.ListProductsRequest() - - -@pytest.mark.asyncio -async def test_list_products_async(transport: str = 'grpc_asyncio', request_type=product_service.ListProductsRequest): - 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.list_products), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_service.ListProductsResponse( - next_page_token='next_page_token_value', - )) - response = await client.list_products(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.ListProductsRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListProductsAsyncPager) - assert response.next_page_token == 'next_page_token_value' - - -@pytest.mark.asyncio -async def test_list_products_async_from_dict(): - await test_list_products_async(request_type=dict) - - -def test_list_products_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.ListProductsRequest() - - request.parent = 'parent/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_products), - '__call__') as call: - call.return_value = product_service.ListProductsResponse() - client.list_products(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'parent=parent/value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_list_products_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.ListProductsRequest() - - request.parent = 'parent/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_products), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_service.ListProductsResponse()) - await client.list_products(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'parent=parent/value', - ) in kw['metadata'] - - -def test_list_products_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.list_products), - '__call__') as call: - # Designate an appropriate return value for the call. - 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', - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - arg = args[0].parent - mock_val = 'parent_value' - assert arg == mock_val - - -def test_list_products_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.list_products( - product_service.ListProductsRequest(), - parent='parent_value', - ) - - -@pytest.mark.asyncio -async def test_list_products_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.list_products), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = product_service.ListProductsResponse() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_service.ListProductsResponse()) - # 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', - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].parent - mock_val = 'parent_value' - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_list_products_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.list_products( - product_service.ListProductsRequest(), - parent='parent_value', - ) - - -def test_list_products_pager(transport_name: str = "grpc"): - client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials, - transport=transport_name, - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_products), - '__call__') as call: - # Set the response to a series of pages. - call.side_effect = ( - product_service.ListProductsResponse( - 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', - ), - product_service.ListProductsResponse( - products=[ - product.Product(), - product.Product(), - ], - ), - RuntimeError, - ) - - metadata = () - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ('parent', ''), - )), - ) - pager = client.list_products(request={}) - - assert pager._metadata == metadata - - results = [i for i in pager] - assert len(results) == 6 - assert all(isinstance(i, product.Product) - for i in results) -def test_list_products_pages(transport_name: str = "grpc"): - client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials, - transport=transport_name, - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_products), - '__call__') as call: - # Set the response to a series of pages. - call.side_effect = ( - product_service.ListProductsResponse( - 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', - ), - product_service.ListProductsResponse( - products=[ - product.Product(), - product.Product(), - ], - ), - RuntimeError, - ) - pages = list(client.list_products(request={}).pages) - for page_, token in zip(pages, ['abc','def','ghi', '']): - assert page_.raw_page.next_page_token == token - -@pytest.mark.asyncio -async def test_list_products_async_pager(): - 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.list_products), - '__call__', new_callable=mock.AsyncMock) as call: - # Set the response to a series of pages. - call.side_effect = ( - product_service.ListProductsResponse( - 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', - ), - product_service.ListProductsResponse( - products=[ - product.Product(), - product.Product(), - ], - ), - RuntimeError, - ) - async_pager = await client.list_products(request={},) - assert async_pager.next_page_token == 'abc' - responses = [] - async for response in async_pager: - responses.append(response) - - assert len(responses) == 6 - assert all(isinstance(i, product.Product) - for i in responses) - - -@pytest.mark.asyncio -async def test_list_products_async_pages(): - 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.list_products), - '__call__', new_callable=mock.AsyncMock) as call: - # Set the response to a series of pages. - call.side_effect = ( - product_service.ListProductsResponse( - 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', - ), - product_service.ListProductsResponse( - products=[ - product.Product(), - product.Product(), - ], - ), - RuntimeError, - ) - pages = [] - async for page_ in (await client.list_products(request={})).pages: - pages.append(page_) - for page_, token in zip(pages, ['abc','def','ghi', '']): - assert page_.raw_page.next_page_token == token - -@pytest.mark.parametrize("request_type", [ - product_service.UpdateProductRequest, - dict, -]) -def test_update_product(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.update_product), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = gcr_product.Product( - name='name_value', - id='id_value', - type_=gcr_product.Product.Type.PRIMARY, - primary_product_id='primary_product_id_value', - collection_member_ids=['collection_member_ids_value'], - gtin='gtin_value', - categories=['categories_value'], - title='title_value', - brands=['brands_value'], - description='description_value', - language_code='language_code_value', - tags=['tags_value'], - availability=gcr_product.Product.Availability.IN_STOCK, - uri='uri_value', - sizes=['sizes_value'], - materials=['materials_value'], - patterns=['patterns_value'], - conditions=['conditions_value'], - expire_time=timestamp_pb2.Timestamp(seconds=751), - ) - response = client.update_product(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.UpdateProductRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, gcr_product.Product) - assert response.name == 'name_value' - assert response.id == 'id_value' - assert response.type_ == gcr_product.Product.Type.PRIMARY - assert response.primary_product_id == 'primary_product_id_value' - assert response.collection_member_ids == ['collection_member_ids_value'] - assert response.gtin == 'gtin_value' - assert response.categories == ['categories_value'] - assert response.title == 'title_value' - assert response.brands == ['brands_value'] - assert response.description == 'description_value' - assert response.language_code == 'language_code_value' - assert response.tags == ['tags_value'] - assert response.availability == gcr_product.Product.Availability.IN_STOCK - assert response.uri == 'uri_value' - assert response.sizes == ['sizes_value'] - assert response.materials == ['materials_value'] - assert response.patterns == ['patterns_value'] - assert response.conditions == ['conditions_value'] - - -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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_product), - '__call__') as call: - client.update_product() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == product_service.UpdateProductRequest() - - -@pytest.mark.asyncio -async def test_update_product_async(transport: str = 'grpc_asyncio', request_type=product_service.UpdateProductRequest): - 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.update_product), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_product.Product( - name='name_value', - id='id_value', - type_=gcr_product.Product.Type.PRIMARY, - primary_product_id='primary_product_id_value', - collection_member_ids=['collection_member_ids_value'], - gtin='gtin_value', - categories=['categories_value'], - title='title_value', - brands=['brands_value'], - description='description_value', - language_code='language_code_value', - tags=['tags_value'], - availability=gcr_product.Product.Availability.IN_STOCK, - uri='uri_value', - sizes=['sizes_value'], - materials=['materials_value'], - patterns=['patterns_value'], - conditions=['conditions_value'], - )) - response = await client.update_product(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.UpdateProductRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, gcr_product.Product) - assert response.name == 'name_value' - assert response.id == 'id_value' - assert response.type_ == gcr_product.Product.Type.PRIMARY - assert response.primary_product_id == 'primary_product_id_value' - assert response.collection_member_ids == ['collection_member_ids_value'] - assert response.gtin == 'gtin_value' - assert response.categories == ['categories_value'] - assert response.title == 'title_value' - assert response.brands == ['brands_value'] - assert response.description == 'description_value' - assert response.language_code == 'language_code_value' - assert response.tags == ['tags_value'] - assert response.availability == gcr_product.Product.Availability.IN_STOCK - assert response.uri == 'uri_value' - assert response.sizes == ['sizes_value'] - assert response.materials == ['materials_value'] - assert response.patterns == ['patterns_value'] - assert response.conditions == ['conditions_value'] - - -@pytest.mark.asyncio -async def test_update_product_async_from_dict(): - await test_update_product_async(request_type=dict) - - -def test_update_product_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.UpdateProductRequest() - - request.product.name = 'product.name/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_product), - '__call__') as call: - call.return_value = gcr_product.Product() - client.update_product(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.name=product.name/value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_update_product_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.UpdateProductRequest() - - request.product.name = 'product.name/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_product), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_product.Product()) - await client.update_product(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.name=product.name/value', - ) in kw['metadata'] - - -def test_update_product_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.update_product), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = gcr_product.Product() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.update_product( - product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), - update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - arg = args[0].product - mock_val = gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) - assert arg == mock_val - arg = args[0].update_mask - mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) - assert arg == mock_val - - -def test_update_product_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.update_product( - product_service.UpdateProductRequest(), - product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), - update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), - ) - - -@pytest.mark.asyncio -async def test_update_product_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.update_product), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = gcr_product.Product() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_product.Product()) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.update_product( - product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), - update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].product - mock_val = gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) - assert arg == mock_val - arg = args[0].update_mask - mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_update_product_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.update_product( - product_service.UpdateProductRequest(), - product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), - update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), - ) - - -@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, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_product), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = None - response = client.delete_product(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.DeleteProductRequest() - - # Establish that the response is the type that we expect. - assert response is None - - -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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_product), - '__call__') as call: - client.delete_product() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == product_service.DeleteProductRequest() - - -@pytest.mark.asyncio -async def test_delete_product_async(transport: str = 'grpc_asyncio', request_type=product_service.DeleteProductRequest): - 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.delete_product), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.delete_product(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.DeleteProductRequest() - - # Establish that the response is the type that we expect. - assert response is None - - -@pytest.mark.asyncio -async def test_delete_product_async_from_dict(): - await test_delete_product_async(request_type=dict) - - -def test_delete_product_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.DeleteProductRequest() - - request.name = 'name/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_product), - '__call__') as call: - call.return_value = None - client.delete_product(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'name=name/value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_delete_product_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.DeleteProductRequest() - - request.name = 'name/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_product), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - await client.delete_product(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'name=name/value', - ) in kw['metadata'] - - -def test_delete_product_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.delete_product), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = None - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.delete_product( - name='name_value', - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - arg = args[0].name - mock_val = 'name_value' - assert arg == mock_val - - -def test_delete_product_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.delete_product( - product_service.DeleteProductRequest(), - name='name_value', - ) - - -@pytest.mark.asyncio -async def test_delete_product_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.delete_product), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = None - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.delete_product( - name='name_value', - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].name - mock_val = 'name_value' - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_delete_product_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.delete_product( - product_service.DeleteProductRequest(), - name='name_value', - ) - - -@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, - ) - - # 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.import_products), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation(name='operations/spam') - response = client.import_products(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == import_config.ImportProductsRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.import_products), - '__call__') as call: - client.import_products() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == import_config.ImportProductsRequest() - - -@pytest.mark.asyncio -async def test_import_products_async(transport: str = 'grpc_asyncio', request_type=import_config.ImportProductsRequest): - 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.import_products), - '__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.import_products(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == import_config.ImportProductsRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -@pytest.mark.asyncio -async def test_import_products_async_from_dict(): - await test_import_products_async(request_type=dict) - - -def test_import_products_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 = import_config.ImportProductsRequest() - - request.parent = 'parent/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.import_products), - '__call__') as call: - call.return_value = operations_pb2.Operation(name='operations/op') - client.import_products(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'parent=parent/value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_import_products_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 = import_config.ImportProductsRequest() - - request.parent = 'parent/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.import_products), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) - await client.import_products(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'parent=parent/value', - ) in kw['metadata'] - - -@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, - ) - - # 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.set_inventory), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation(name='operations/spam') - response = client.set_inventory(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.SetInventoryRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.set_inventory), - '__call__') as call: - client.set_inventory() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == product_service.SetInventoryRequest() - - -@pytest.mark.asyncio -async def test_set_inventory_async(transport: str = 'grpc_asyncio', request_type=product_service.SetInventoryRequest): - 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.set_inventory), - '__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.set_inventory(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.SetInventoryRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -@pytest.mark.asyncio -async def test_set_inventory_async_from_dict(): - await test_set_inventory_async(request_type=dict) - - -def test_set_inventory_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.SetInventoryRequest() - - request.inventory.name = 'inventory.name/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.set_inventory), - '__call__') as call: - call.return_value = operations_pb2.Operation(name='operations/op') - client.set_inventory(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', - 'inventory.name=inventory.name/value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_set_inventory_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.SetInventoryRequest() - - request.inventory.name = 'inventory.name/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.set_inventory), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) - await client.set_inventory(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', - 'inventory.name=inventory.name/value', - ) in kw['metadata'] - - -def test_set_inventory_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.set_inventory), - '__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.set_inventory( - inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), - set_mask=field_mask_pb2.FieldMask(paths=['paths_value']), - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - arg = args[0].inventory - mock_val = product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) - assert arg == mock_val - arg = args[0].set_mask - mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) - assert arg == mock_val - - -def test_set_inventory_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.set_inventory( - product_service.SetInventoryRequest(), - inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), - set_mask=field_mask_pb2.FieldMask(paths=['paths_value']), - ) - - -@pytest.mark.asyncio -async def test_set_inventory_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.set_inventory), - '__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.set_inventory( - inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), - set_mask=field_mask_pb2.FieldMask(paths=['paths_value']), - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].inventory - mock_val = product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) - assert arg == mock_val - arg = args[0].set_mask - mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_set_inventory_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.set_inventory( - product_service.SetInventoryRequest(), - inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), - set_mask=field_mask_pb2.FieldMask(paths=['paths_value']), - ) - - -@pytest.mark.parametrize("request_type", [ - product_service.AddFulfillmentPlacesRequest, - dict, -]) -def test_add_fulfillment_places(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.add_fulfillment_places), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation(name='operations/spam') - response = client.add_fulfillment_places(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.AddFulfillmentPlacesRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.add_fulfillment_places), - '__call__') as call: - client.add_fulfillment_places() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == product_service.AddFulfillmentPlacesRequest() - - -@pytest.mark.asyncio -async def test_add_fulfillment_places_async(transport: str = 'grpc_asyncio', request_type=product_service.AddFulfillmentPlacesRequest): - 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_fulfillment_places), - '__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_fulfillment_places(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.AddFulfillmentPlacesRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -@pytest.mark.asyncio -async def test_add_fulfillment_places_async_from_dict(): - await test_add_fulfillment_places_async(request_type=dict) - - -def test_add_fulfillment_places_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.AddFulfillmentPlacesRequest() - - request.product = 'product/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.add_fulfillment_places), - '__call__') as call: - call.return_value = operations_pb2.Operation(name='operations/op') - client.add_fulfillment_places(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_fulfillment_places_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.AddFulfillmentPlacesRequest() - - request.product = 'product/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.add_fulfillment_places), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) - await client.add_fulfillment_places(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_fulfillment_places_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_fulfillment_places), - '__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_fulfillment_places( - 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_fulfillment_places_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_fulfillment_places( - product_service.AddFulfillmentPlacesRequest(), - product='product_value', - ) - - -@pytest.mark.asyncio -async def test_add_fulfillment_places_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_fulfillment_places), - '__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_fulfillment_places( - 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_fulfillment_places_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_fulfillment_places( - product_service.AddFulfillmentPlacesRequest(), - product='product_value', - ) - - -@pytest.mark.parametrize("request_type", [ - product_service.RemoveFulfillmentPlacesRequest, - dict, -]) -def test_remove_fulfillment_places(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_fulfillment_places), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation(name='operations/spam') - response = client.remove_fulfillment_places(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.RemoveFulfillmentPlacesRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.remove_fulfillment_places), - '__call__') as call: - client.remove_fulfillment_places() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == product_service.RemoveFulfillmentPlacesRequest() - - -@pytest.mark.asyncio -async def test_remove_fulfillment_places_async(transport: str = 'grpc_asyncio', request_type=product_service.RemoveFulfillmentPlacesRequest): - 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_fulfillment_places), - '__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_fulfillment_places(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.RemoveFulfillmentPlacesRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -@pytest.mark.asyncio -async def test_remove_fulfillment_places_async_from_dict(): - await test_remove_fulfillment_places_async(request_type=dict) - - -def test_remove_fulfillment_places_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.RemoveFulfillmentPlacesRequest() - - request.product = 'product/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.remove_fulfillment_places), - '__call__') as call: - call.return_value = operations_pb2.Operation(name='operations/op') - client.remove_fulfillment_places(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_fulfillment_places_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.RemoveFulfillmentPlacesRequest() - - request.product = 'product/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.remove_fulfillment_places), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) - await client.remove_fulfillment_places(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_fulfillment_places_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_fulfillment_places), - '__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_fulfillment_places( - 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_fulfillment_places_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_fulfillment_places( - product_service.RemoveFulfillmentPlacesRequest(), - product='product_value', - ) - - -@pytest.mark.asyncio -async def test_remove_fulfillment_places_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_fulfillment_places), - '__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_fulfillment_places( - 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_fulfillment_places_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_fulfillment_places( - 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( - 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, - ) - - # It is an error to provide an api_key and a credential. - options = mock.Mock() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ProductServiceClient( - client_options=options, - credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.ProductServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ProductServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.ProductServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = ProductServiceClient(transport=transport) - assert client.transport is transport - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.ProductServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.ProductServiceGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize("transport_class", [ - transports.ProductServiceGrpcTransport, - transports.ProductServiceGrpcAsyncIOTransport, -]) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, 'default') as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - -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, - ) - -def test_product_service_base_transport_error(): - # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(core_exceptions.DuplicateCredentialArgs): - transport = transports.ProductServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - credentials_file="credentials.json" - ) - - -def test_product_service_base_transport(): - # Instantiate the base transport. - with mock.patch('google.cloud.retail_v2.services.product_service.transports.ProductServiceTransport.__init__') as Transport: - Transport.return_value = None - transport = transports.ProductServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Every method on the transport should just blindly - # raise NotImplementedError. - methods = ( - 'create_product', - 'get_product', - 'list_products', - 'update_product', - 'delete_product', - 'import_products', - 'set_inventory', - 'add_fulfillment_places', - 'remove_fulfillment_places', - ) - for method in methods: - with pytest.raises(NotImplementedError): - getattr(transport, method)(request=object()) - - with pytest.raises(NotImplementedError): - transport.close() - - # Additionally, the LRO client (a property) should - # also raise NotImplementedError - with pytest.raises(NotImplementedError): - transport.operations_client - - -def test_product_service_base_transport_with_credentials_file(): - # Instantiate the base transport with a credentials file - with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('google.cloud.retail_v2.services.product_service.transports.ProductServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.ProductServiceTransport( - credentials_file="credentials.json", - quota_project_id="octopus", - ) - load_creds.assert_called_once_with("credentials.json", - scopes=None, - default_scopes=( - 'https://www.googleapis.com/auth/cloud-platform', -), - quota_project_id="octopus", - ) - - -def test_product_service_base_transport_with_adc(): - # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(google.auth, 'default', autospec=True) as adc, mock.patch('google.cloud.retail_v2.services.product_service.transports.ProductServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.ProductServiceTransport() - adc.assert_called_once() - - -def test_product_service_auth_adc(): - # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(google.auth, 'default', autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - ProductServiceClient() - adc.assert_called_once_with( - scopes=None, - default_scopes=( - 'https://www.googleapis.com/auth/cloud-platform', -), - quota_project_id=None, - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.ProductServiceGrpcTransport, - transports.ProductServiceGrpcAsyncIOTransport, - ], -) -def test_product_service_transport_auth_adc(transport_class): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, 'default', autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class(quota_project_id="octopus", scopes=["1", "2"]) - adc.assert_called_once_with( - scopes=["1", "2"], - default_scopes=( 'https://www.googleapis.com/auth/cloud-platform',), - quota_project_id="octopus", - ) - - -@pytest.mark.parametrize( - "transport_class,grpc_helpers", - [ - (transports.ProductServiceGrpcTransport, grpc_helpers), - (transports.ProductServiceGrpcAsyncIOTransport, grpc_helpers_async) - ], -) -def test_product_service_transport_create_channel(transport_class, grpc_helpers): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( - grpc_helpers, "create_channel", autospec=True - ) as create_channel: - creds = ga_credentials.AnonymousCredentials() - adc.return_value = (creds, None) - transport_class( - quota_project_id="octopus", - scopes=["1", "2"] - ) - - create_channel.assert_called_with( - "retail.googleapis.com:443", - credentials=creds, - credentials_file=None, - quota_project_id="octopus", - default_scopes=( - 'https://www.googleapis.com/auth/cloud-platform', -), - scopes=["1", "2"], - default_host="retail.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize("transport_class", [transports.ProductServiceGrpcTransport, transports.ProductServiceGrpcAsyncIOTransport]) -def test_product_service_grpc_transport_client_cert_source_for_mtls( - transport_class -): - cred = ga_credentials.AnonymousCredentials() - - # Check ssl_channel_credentials is used if provided. - with mock.patch.object(transport_class, "create_channel") as mock_create_channel: - mock_ssl_channel_creds = mock.Mock() - transport_class( - host="squid.clam.whelk", - credentials=cred, - ssl_channel_credentials=mock_ssl_channel_creds - ) - mock_create_channel.assert_called_once_with( - "squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_channel_creds, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls - # is used. - with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): - with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: - transport_class( - credentials=cred, - client_cert_source_for_mtls=client_cert_source_callback - ) - expected_cert, expected_key = client_cert_source_callback() - mock_ssl_cred.assert_called_once_with( - certificate_chain=expected_cert, - private_key=expected_key - ) - - -def test_product_service_host_no_port(): - client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), - ) - assert client.transport._host == 'retail.googleapis.com:443' - - -def test_product_service_host_with_port(): - client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), - ) - assert client.transport._host == 'retail.googleapis.com:8000' - -def test_product_service_grpc_transport_channel(): - channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.ProductServiceGrpcTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -def test_product_service_grpc_asyncio_transport_channel(): - channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.ProductServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.parametrize("transport_class", [transports.ProductServiceGrpcTransport, transports.ProductServiceGrpcAsyncIOTransport]) -def test_product_service_transport_channel_mtls_with_client_cert_source( - transport_class -): - with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: - with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - cred = ga_credentials.AnonymousCredentials() - with pytest.warns(DeprecationWarning): - with mock.patch.object(google.auth, 'default') as adc: - adc.return_value = (cred, None) - transport = transport_class( - host="squid.clam.whelk", - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - adc.assert_called_once() - - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - assert transport._ssl_channel_credentials == mock_ssl_cred - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.parametrize("transport_class", [transports.ProductServiceGrpcTransport, transports.ProductServiceGrpcAsyncIOTransport]) -def test_product_service_transport_channel_mtls_with_adc( - transport_class -): - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - mock_cred = mock.Mock() - - with pytest.warns(DeprecationWarning): - transport = transport_class( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=None, - ) - - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - - -def test_product_service_grpc_lro_client(): - client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - transport = client.transport - - # Ensure that we have a api-core operations client. - assert isinstance( - transport.operations_client, - operations_v1.OperationsClient, - ) - - # Ensure that subsequent calls to the property send the exact same object. - assert transport.operations_client is transport.operations_client - - -def test_product_service_grpc_lro_async_client(): - client = ProductServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc_asyncio', - ) - transport = client.transport - - # Ensure that we have a api-core operations client. - assert isinstance( - transport.operations_client, - operations_v1.OperationsAsyncClient, - ) - - # Ensure that subsequent calls to the property send the exact same object. - assert transport.operations_client is transport.operations_client - - -def test_branch_path(): - project = "squid" - location = "clam" - catalog = "whelk" - branch = "octopus" - expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) - actual = ProductServiceClient.branch_path(project, location, catalog, branch) - assert expected == actual - - -def test_parse_branch_path(): - expected = { - "project": "oyster", - "location": "nudibranch", - "catalog": "cuttlefish", - "branch": "mussel", - } - path = ProductServiceClient.branch_path(**expected) - - # Check that the path construction is reversible. - actual = ProductServiceClient.parse_branch_path(path) - assert expected == actual - -def test_product_path(): - project = "winkle" - location = "nautilus" - catalog = "scallop" - branch = "abalone" - product = "squid" - expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, product=product, ) - actual = ProductServiceClient.product_path(project, location, catalog, branch, product) - assert expected == actual - - -def test_parse_product_path(): - expected = { - "project": "clam", - "location": "whelk", - "catalog": "octopus", - "branch": "oyster", - "product": "nudibranch", - } - path = ProductServiceClient.product_path(**expected) - - # Check that the path construction is reversible. - actual = ProductServiceClient.parse_product_path(path) - assert expected == actual - -def test_common_billing_account_path(): - billing_account = "cuttlefish" - expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) - actual = ProductServiceClient.common_billing_account_path(billing_account) - assert expected == actual - - -def test_parse_common_billing_account_path(): - expected = { - "billing_account": "mussel", - } - path = ProductServiceClient.common_billing_account_path(**expected) - - # Check that the path construction is reversible. - actual = ProductServiceClient.parse_common_billing_account_path(path) - assert expected == actual - -def test_common_folder_path(): - folder = "winkle" - expected = "folders/{folder}".format(folder=folder, ) - actual = ProductServiceClient.common_folder_path(folder) - assert expected == actual - - -def test_parse_common_folder_path(): - expected = { - "folder": "nautilus", - } - path = ProductServiceClient.common_folder_path(**expected) - - # Check that the path construction is reversible. - actual = ProductServiceClient.parse_common_folder_path(path) - assert expected == actual - -def test_common_organization_path(): - organization = "scallop" - expected = "organizations/{organization}".format(organization=organization, ) - actual = ProductServiceClient.common_organization_path(organization) - assert expected == actual - - -def test_parse_common_organization_path(): - expected = { - "organization": "abalone", - } - path = ProductServiceClient.common_organization_path(**expected) - - # Check that the path construction is reversible. - actual = ProductServiceClient.parse_common_organization_path(path) - assert expected == actual - -def test_common_project_path(): - project = "squid" - expected = "projects/{project}".format(project=project, ) - actual = ProductServiceClient.common_project_path(project) - assert expected == actual - - -def test_parse_common_project_path(): - expected = { - "project": "clam", - } - path = ProductServiceClient.common_project_path(**expected) - - # Check that the path construction is reversible. - actual = ProductServiceClient.parse_common_project_path(path) - assert expected == actual - -def test_common_location_path(): - project = "whelk" - location = "octopus" - expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) - actual = ProductServiceClient.common_location_path(project, location) - assert expected == actual - - -def test_parse_common_location_path(): - expected = { - "project": "oyster", - "location": "nudibranch", - } - path = ProductServiceClient.common_location_path(**expected) - - # Check that the path construction is reversible. - actual = ProductServiceClient.parse_common_location_path(path) - assert expected == actual - - -def test_client_with_default_client_info(): - client_info = gapic_v1.client_info.ClientInfo() - - with mock.patch.object(transports.ProductServiceTransport, '_prep_wrapped_messages') as prep: - client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - with mock.patch.object(transports.ProductServiceTransport, '_prep_wrapped_messages') as prep: - transport_class = ProductServiceClient.get_transport_class() - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - -@pytest.mark.asyncio -async def test_transport_close_async(): - client = ProductServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - with mock.patch.object(type(getattr(client.transport, "grpc_channel")), "close") as close: - async with client: - close.assert_not_called() - close.assert_called_once() - -def test_transport_close(): - transports = { - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport - ) - with mock.patch.object(type(getattr(client.transport, close_name)), "close") as close: - with client: - close.assert_not_called() - close.assert_called_once() - -def test_client_ctx(): - transports = [ - 'grpc', - ] - for transport in transports: - client = ProductServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport - ) - # Test client calls underlying transport. - with mock.patch.object(type(client.transport), "close") as close: - close.assert_not_called() - with client: - pass - close.assert_called() - -@pytest.mark.parametrize("client_class,transport_class", [ - (ProductServiceClient, transports.ProductServiceGrpcTransport), - (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport), -]) -def test_api_key_credentials(client_class, transport_class): - with mock.patch.object( - google.auth._default, "get_api_key_credentials", create=True - ) as get_api_key_credentials: - mock_cred = mock.Mock() - get_api_key_credentials.return_value = mock_cred - options = client_options.ClientOptions() - options.api_key = "api_key" - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=mock_cred, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) diff --git a/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_search_service.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_search_service.py deleted file mode 100644 index 31eba051..00000000 --- a/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_search_service.py +++ /dev/null @@ -1,1398 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import os -import mock - -import grpc -from grpc.experimental import aio -import math -import pytest -from proto.marshal.rules.dates import DurationRule, TimestampRule - - -from google.api_core import client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers -from google.api_core import grpc_helpers_async -from google.api_core import path_template -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.cloud.retail_v2.services.search_service import SearchServiceAsyncClient -from google.cloud.retail_v2.services.search_service import SearchServiceClient -from google.cloud.retail_v2.services.search_service import pagers -from google.cloud.retail_v2.services.search_service import transports -from google.cloud.retail_v2.types import common -from google.cloud.retail_v2.types import search_service -from google.oauth2 import service_account -import google.auth - - -def client_cert_source_callback(): - return b"cert bytes", b"key bytes" - - -# If default endpoint is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint(client): - return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT - - -def test__get_default_mtls_endpoint(): - api_endpoint = "example.googleapis.com" - api_mtls_endpoint = "example.mtls.googleapis.com" - sandbox_endpoint = "example.sandbox.googleapis.com" - sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" - non_googleapi = "api.example.com" - - assert SearchServiceClient._get_default_mtls_endpoint(None) is None - assert SearchServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint - assert SearchServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint - assert SearchServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint - assert SearchServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint - assert SearchServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi - - -@pytest.mark.parametrize("client_class", [ - SearchServiceClient, - SearchServiceAsyncClient, -]) -def test_search_service_client_from_service_account_info(client_class): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: - factory.return_value = creds - info = {"valid": True} - client = client_class.from_service_account_info(info) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == 'retail.googleapis.com:443' - - -@pytest.mark.parametrize("transport_class,transport_name", [ - (transports.SearchServiceGrpcTransport, "grpc"), - (transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -def test_search_service_client_service_account_always_use_jwt(transport_class, transport_name): - with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=True) - use_jwt.assert_called_once_with(True) - - with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=False) - use_jwt.assert_not_called() - - -@pytest.mark.parametrize("client_class", [ - SearchServiceClient, - SearchServiceAsyncClient, -]) -def test_search_service_client_from_service_account_file(client_class): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: - factory.return_value = creds - client = client_class.from_service_account_file("dummy/file/path.json") - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - client = client_class.from_service_account_json("dummy/file/path.json") - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == 'retail.googleapis.com:443' - - -def test_search_service_client_get_transport_class(): - transport = SearchServiceClient.get_transport_class() - available_transports = [ - transports.SearchServiceGrpcTransport, - ] - assert transport in available_transports - - transport = SearchServiceClient.get_transport_class("grpc") - assert transport == transports.SearchServiceGrpcTransport - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc"), - (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -@mock.patch.object(SearchServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceClient)) -@mock.patch.object(SearchServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceAsyncClient)) -def test_search_service_client_client_options(client_class, transport_class, transport_name): - # Check that if channel is provided we won't create a new one. - with mock.patch.object(SearchServiceClient, 'get_transport_class') as gtc: - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ) - client = client_class(transport=transport) - gtc.assert_not_called() - - # Check that if channel is provided via str we will create a new one. - with mock.patch.object(SearchServiceClient, 'get_transport_class') as gtc: - client = client_class(transport=transport_name) - gtc.assert_called() - - # Check the case api_endpoint is provided. - options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name, client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class(transport=transport_name) - - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): - with pytest.raises(ValueError): - client = client_class(transport=transport_name) - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - -@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ - (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc", "true"), - (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), - (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc", "false"), - (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), -]) -@mock.patch.object(SearchServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceClient)) -@mock.patch.object(SearchServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceAsyncClient)) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_search_service_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): - # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default - # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. - - # Check the case client_cert_source is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - - if use_client_cert_env == "false": - expected_client_cert_source = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_client_cert_source = client_cert_source_callback - expected_host = client.DEFAULT_MTLS_ENDPOINT - - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case ADC client cert is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - with mock.patch.object(transport_class, '__init__') as patched: - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): - with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): - if use_client_cert_env == "false": - expected_host = client.DEFAULT_ENDPOINT - expected_client_cert_source = None - else: - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_client_cert_source = client_cert_source_callback - - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - with mock.patch.object(transport_class, '__init__') as patched: - with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - -@pytest.mark.parametrize("client_class", [ - SearchServiceClient, SearchServiceAsyncClient -]) -@mock.patch.object(SearchServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceClient)) -@mock.patch.object(SearchServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceAsyncClient)) -def test_search_service_client_get_mtls_endpoint_and_cert_source(client_class): - mock_client_cert_source = mock.Mock() - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - mock_api_endpoint = "foo" - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source == mock_client_cert_source - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - mock_client_cert_source = mock.Mock() - mock_api_endpoint = "foo" - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): - with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source == mock_client_cert_source - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc"), - (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -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"], - ) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=["1", "2"], - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc"), - (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -def test_search_service_client_client_options_credentials_file(client_class, transport_class, transport_name): - # Check the case credentials file is provided. - options = client_options.ClientOptions( - credentials_file="credentials.json" - ) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file="credentials.json", - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - -def test_search_service_client_client_options_from_dict(): - with mock.patch('google.cloud.retail_v2.services.search_service.transports.SearchServiceGrpcTransport.__init__') as grpc_transport: - grpc_transport.return_value = None - client = SearchServiceClient( - client_options={'api_endpoint': 'squid.clam.whelk'} - ) - grpc_transport.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - -@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, - ) - - # 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.search), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = search_service.SearchResponse( - total_size=1086, - corrected_query='corrected_query_value', - attribution_token='attribution_token_value', - next_page_token='next_page_token_value', - redirect_uri='redirect_uri_value', - ) - response = client.search(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == search_service.SearchRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.SearchPager) - assert response.total_size == 1086 - assert response.corrected_query == 'corrected_query_value' - assert response.attribution_token == 'attribution_token_value' - assert response.next_page_token == 'next_page_token_value' - assert response.redirect_uri == 'redirect_uri_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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.search), - '__call__') as call: - client.search() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == search_service.SearchRequest() - - -@pytest.mark.asyncio -async def test_search_async(transport: str = 'grpc_asyncio', request_type=search_service.SearchRequest): - client = SearchServiceAsyncClient( - 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.search), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(search_service.SearchResponse( - total_size=1086, - corrected_query='corrected_query_value', - attribution_token='attribution_token_value', - next_page_token='next_page_token_value', - redirect_uri='redirect_uri_value', - )) - response = await client.search(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == search_service.SearchRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.SearchAsyncPager) - assert response.total_size == 1086 - assert response.corrected_query == 'corrected_query_value' - assert response.attribution_token == 'attribution_token_value' - assert response.next_page_token == 'next_page_token_value' - assert response.redirect_uri == 'redirect_uri_value' - - -@pytest.mark.asyncio -async def test_search_async_from_dict(): - await test_search_async(request_type=dict) - - -def test_search_field_headers(): - 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. - request = search_service.SearchRequest() - - request.placement = 'placement/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.search), - '__call__') as call: - call.return_value = search_service.SearchResponse() - client.search(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', - 'placement=placement/value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_search_field_headers_async(): - client = SearchServiceAsyncClient( - 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 = search_service.SearchRequest() - - request.placement = 'placement/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.search), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(search_service.SearchResponse()) - await client.search(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', - 'placement=placement/value', - ) in kw['metadata'] - - -def test_search_pager(transport_name: str = "grpc"): - client = SearchServiceClient( - credentials=ga_credentials.AnonymousCredentials, - transport=transport_name, - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.search), - '__call__') as call: - # Set the response to a series of pages. - call.side_effect = ( - search_service.SearchResponse( - results=[ - search_service.SearchResponse.SearchResult(), - search_service.SearchResponse.SearchResult(), - search_service.SearchResponse.SearchResult(), - ], - next_page_token='abc', - ), - search_service.SearchResponse( - results=[], - next_page_token='def', - ), - search_service.SearchResponse( - results=[ - search_service.SearchResponse.SearchResult(), - ], - next_page_token='ghi', - ), - search_service.SearchResponse( - results=[ - search_service.SearchResponse.SearchResult(), - search_service.SearchResponse.SearchResult(), - ], - ), - RuntimeError, - ) - - metadata = () - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ('placement', ''), - )), - ) - pager = client.search(request={}) - - assert pager._metadata == metadata - - results = [i for i in pager] - assert len(results) == 6 - assert all(isinstance(i, search_service.SearchResponse.SearchResult) - for i in results) -def test_search_pages(transport_name: str = "grpc"): - client = SearchServiceClient( - credentials=ga_credentials.AnonymousCredentials, - transport=transport_name, - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.search), - '__call__') as call: - # Set the response to a series of pages. - call.side_effect = ( - search_service.SearchResponse( - results=[ - search_service.SearchResponse.SearchResult(), - search_service.SearchResponse.SearchResult(), - search_service.SearchResponse.SearchResult(), - ], - next_page_token='abc', - ), - search_service.SearchResponse( - results=[], - next_page_token='def', - ), - search_service.SearchResponse( - results=[ - search_service.SearchResponse.SearchResult(), - ], - next_page_token='ghi', - ), - search_service.SearchResponse( - results=[ - search_service.SearchResponse.SearchResult(), - search_service.SearchResponse.SearchResult(), - ], - ), - RuntimeError, - ) - pages = list(client.search(request={}).pages) - for page_, token in zip(pages, ['abc','def','ghi', '']): - assert page_.raw_page.next_page_token == token - -@pytest.mark.asyncio -async def test_search_async_pager(): - client = SearchServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials, - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.search), - '__call__', new_callable=mock.AsyncMock) as call: - # Set the response to a series of pages. - call.side_effect = ( - search_service.SearchResponse( - results=[ - search_service.SearchResponse.SearchResult(), - search_service.SearchResponse.SearchResult(), - search_service.SearchResponse.SearchResult(), - ], - next_page_token='abc', - ), - search_service.SearchResponse( - results=[], - next_page_token='def', - ), - search_service.SearchResponse( - results=[ - search_service.SearchResponse.SearchResult(), - ], - next_page_token='ghi', - ), - search_service.SearchResponse( - results=[ - search_service.SearchResponse.SearchResult(), - search_service.SearchResponse.SearchResult(), - ], - ), - RuntimeError, - ) - async_pager = await client.search(request={},) - assert async_pager.next_page_token == 'abc' - responses = [] - async for response in async_pager: - responses.append(response) - - assert len(responses) == 6 - assert all(isinstance(i, search_service.SearchResponse.SearchResult) - for i in responses) - - -@pytest.mark.asyncio -async def test_search_async_pages(): - client = SearchServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials, - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.search), - '__call__', new_callable=mock.AsyncMock) as call: - # Set the response to a series of pages. - call.side_effect = ( - search_service.SearchResponse( - results=[ - search_service.SearchResponse.SearchResult(), - search_service.SearchResponse.SearchResult(), - search_service.SearchResponse.SearchResult(), - ], - next_page_token='abc', - ), - search_service.SearchResponse( - results=[], - next_page_token='def', - ), - search_service.SearchResponse( - results=[ - search_service.SearchResponse.SearchResult(), - ], - next_page_token='ghi', - ), - search_service.SearchResponse( - results=[ - search_service.SearchResponse.SearchResult(), - search_service.SearchResponse.SearchResult(), - ], - ), - RuntimeError, - ) - pages = [] - async for page_ in (await client.search(request={})).pages: - pages.append(page_) - for page_, token in zip(pages, ['abc','def','ghi', '']): - assert page_.raw_page.next_page_token == token - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.SearchServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = SearchServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.SearchServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = SearchServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.SearchServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = SearchServiceClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = mock.Mock() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = SearchServiceClient( - client_options=options, - credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.SearchServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = SearchServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.SearchServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = SearchServiceClient(transport=transport) - assert client.transport is transport - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.SearchServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.SearchServiceGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize("transport_class", [ - transports.SearchServiceGrpcTransport, - transports.SearchServiceGrpcAsyncIOTransport, -]) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, 'default') as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - -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, - ) - -def test_search_service_base_transport_error(): - # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(core_exceptions.DuplicateCredentialArgs): - transport = transports.SearchServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - credentials_file="credentials.json" - ) - - -def test_search_service_base_transport(): - # Instantiate the base transport. - with mock.patch('google.cloud.retail_v2.services.search_service.transports.SearchServiceTransport.__init__') as Transport: - Transport.return_value = None - transport = transports.SearchServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Every method on the transport should just blindly - # raise NotImplementedError. - methods = ( - 'search', - ) - for method in methods: - with pytest.raises(NotImplementedError): - getattr(transport, method)(request=object()) - - with pytest.raises(NotImplementedError): - transport.close() - - -def test_search_service_base_transport_with_credentials_file(): - # Instantiate the base transport with a credentials file - with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('google.cloud.retail_v2.services.search_service.transports.SearchServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.SearchServiceTransport( - credentials_file="credentials.json", - quota_project_id="octopus", - ) - load_creds.assert_called_once_with("credentials.json", - scopes=None, - default_scopes=( - 'https://www.googleapis.com/auth/cloud-platform', -), - quota_project_id="octopus", - ) - - -def test_search_service_base_transport_with_adc(): - # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(google.auth, 'default', autospec=True) as adc, mock.patch('google.cloud.retail_v2.services.search_service.transports.SearchServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.SearchServiceTransport() - adc.assert_called_once() - - -def test_search_service_auth_adc(): - # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(google.auth, 'default', autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - SearchServiceClient() - adc.assert_called_once_with( - scopes=None, - default_scopes=( - 'https://www.googleapis.com/auth/cloud-platform', -), - quota_project_id=None, - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.SearchServiceGrpcTransport, - transports.SearchServiceGrpcAsyncIOTransport, - ], -) -def test_search_service_transport_auth_adc(transport_class): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, 'default', autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class(quota_project_id="octopus", scopes=["1", "2"]) - adc.assert_called_once_with( - scopes=["1", "2"], - default_scopes=( 'https://www.googleapis.com/auth/cloud-platform',), - quota_project_id="octopus", - ) - - -@pytest.mark.parametrize( - "transport_class,grpc_helpers", - [ - (transports.SearchServiceGrpcTransport, grpc_helpers), - (transports.SearchServiceGrpcAsyncIOTransport, grpc_helpers_async) - ], -) -def test_search_service_transport_create_channel(transport_class, grpc_helpers): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( - grpc_helpers, "create_channel", autospec=True - ) as create_channel: - creds = ga_credentials.AnonymousCredentials() - adc.return_value = (creds, None) - transport_class( - quota_project_id="octopus", - scopes=["1", "2"] - ) - - create_channel.assert_called_with( - "retail.googleapis.com:443", - credentials=creds, - credentials_file=None, - quota_project_id="octopus", - default_scopes=( - 'https://www.googleapis.com/auth/cloud-platform', -), - scopes=["1", "2"], - default_host="retail.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize("transport_class", [transports.SearchServiceGrpcTransport, transports.SearchServiceGrpcAsyncIOTransport]) -def test_search_service_grpc_transport_client_cert_source_for_mtls( - transport_class -): - cred = ga_credentials.AnonymousCredentials() - - # Check ssl_channel_credentials is used if provided. - with mock.patch.object(transport_class, "create_channel") as mock_create_channel: - mock_ssl_channel_creds = mock.Mock() - transport_class( - host="squid.clam.whelk", - credentials=cred, - ssl_channel_credentials=mock_ssl_channel_creds - ) - mock_create_channel.assert_called_once_with( - "squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_channel_creds, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls - # is used. - with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): - with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: - transport_class( - credentials=cred, - client_cert_source_for_mtls=client_cert_source_callback - ) - expected_cert, expected_key = client_cert_source_callback() - mock_ssl_cred.assert_called_once_with( - certificate_chain=expected_cert, - private_key=expected_key - ) - - -def test_search_service_host_no_port(): - client = SearchServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), - ) - assert client.transport._host == 'retail.googleapis.com:443' - - -def test_search_service_host_with_port(): - client = SearchServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), - ) - assert client.transport._host == 'retail.googleapis.com:8000' - -def test_search_service_grpc_transport_channel(): - channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.SearchServiceGrpcTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -def test_search_service_grpc_asyncio_transport_channel(): - channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.SearchServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.parametrize("transport_class", [transports.SearchServiceGrpcTransport, transports.SearchServiceGrpcAsyncIOTransport]) -def test_search_service_transport_channel_mtls_with_client_cert_source( - transport_class -): - with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: - with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - cred = ga_credentials.AnonymousCredentials() - with pytest.warns(DeprecationWarning): - with mock.patch.object(google.auth, 'default') as adc: - adc.return_value = (cred, None) - transport = transport_class( - host="squid.clam.whelk", - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - adc.assert_called_once() - - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - assert transport._ssl_channel_credentials == mock_ssl_cred - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.parametrize("transport_class", [transports.SearchServiceGrpcTransport, transports.SearchServiceGrpcAsyncIOTransport]) -def test_search_service_transport_channel_mtls_with_adc( - transport_class -): - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - mock_cred = mock.Mock() - - with pytest.warns(DeprecationWarning): - transport = transport_class( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=None, - ) - - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - - -def test_branch_path(): - project = "squid" - location = "clam" - catalog = "whelk" - branch = "octopus" - expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) - actual = SearchServiceClient.branch_path(project, location, catalog, branch) - assert expected == actual - - -def test_parse_branch_path(): - expected = { - "project": "oyster", - "location": "nudibranch", - "catalog": "cuttlefish", - "branch": "mussel", - } - path = SearchServiceClient.branch_path(**expected) - - # Check that the path construction is reversible. - actual = SearchServiceClient.parse_branch_path(path) - assert expected == actual - -def test_product_path(): - project = "winkle" - location = "nautilus" - catalog = "scallop" - branch = "abalone" - product = "squid" - expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, product=product, ) - actual = SearchServiceClient.product_path(project, location, catalog, branch, product) - assert expected == actual - - -def test_parse_product_path(): - expected = { - "project": "clam", - "location": "whelk", - "catalog": "octopus", - "branch": "oyster", - "product": "nudibranch", - } - path = SearchServiceClient.product_path(**expected) - - # Check that the path construction is reversible. - actual = SearchServiceClient.parse_product_path(path) - assert expected == actual - -def test_common_billing_account_path(): - billing_account = "cuttlefish" - expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) - actual = SearchServiceClient.common_billing_account_path(billing_account) - assert expected == actual - - -def test_parse_common_billing_account_path(): - expected = { - "billing_account": "mussel", - } - path = SearchServiceClient.common_billing_account_path(**expected) - - # Check that the path construction is reversible. - actual = SearchServiceClient.parse_common_billing_account_path(path) - assert expected == actual - -def test_common_folder_path(): - folder = "winkle" - expected = "folders/{folder}".format(folder=folder, ) - actual = SearchServiceClient.common_folder_path(folder) - assert expected == actual - - -def test_parse_common_folder_path(): - expected = { - "folder": "nautilus", - } - path = SearchServiceClient.common_folder_path(**expected) - - # Check that the path construction is reversible. - actual = SearchServiceClient.parse_common_folder_path(path) - assert expected == actual - -def test_common_organization_path(): - organization = "scallop" - expected = "organizations/{organization}".format(organization=organization, ) - actual = SearchServiceClient.common_organization_path(organization) - assert expected == actual - - -def test_parse_common_organization_path(): - expected = { - "organization": "abalone", - } - path = SearchServiceClient.common_organization_path(**expected) - - # Check that the path construction is reversible. - actual = SearchServiceClient.parse_common_organization_path(path) - assert expected == actual - -def test_common_project_path(): - project = "squid" - expected = "projects/{project}".format(project=project, ) - actual = SearchServiceClient.common_project_path(project) - assert expected == actual - - -def test_parse_common_project_path(): - expected = { - "project": "clam", - } - path = SearchServiceClient.common_project_path(**expected) - - # Check that the path construction is reversible. - actual = SearchServiceClient.parse_common_project_path(path) - assert expected == actual - -def test_common_location_path(): - project = "whelk" - location = "octopus" - expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) - actual = SearchServiceClient.common_location_path(project, location) - assert expected == actual - - -def test_parse_common_location_path(): - expected = { - "project": "oyster", - "location": "nudibranch", - } - path = SearchServiceClient.common_location_path(**expected) - - # Check that the path construction is reversible. - actual = SearchServiceClient.parse_common_location_path(path) - assert expected == actual - - -def test_client_with_default_client_info(): - client_info = gapic_v1.client_info.ClientInfo() - - with mock.patch.object(transports.SearchServiceTransport, '_prep_wrapped_messages') as prep: - client = SearchServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - with mock.patch.object(transports.SearchServiceTransport, '_prep_wrapped_messages') as prep: - transport_class = SearchServiceClient.get_transport_class() - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - -@pytest.mark.asyncio -async def test_transport_close_async(): - client = SearchServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - with mock.patch.object(type(getattr(client.transport, "grpc_channel")), "close") as close: - async with client: - close.assert_not_called() - close.assert_called_once() - -def test_transport_close(): - transports = { - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = SearchServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport - ) - with mock.patch.object(type(getattr(client.transport, close_name)), "close") as close: - with client: - close.assert_not_called() - close.assert_called_once() - -def test_client_ctx(): - transports = [ - 'grpc', - ] - for transport in transports: - client = SearchServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport - ) - # Test client calls underlying transport. - with mock.patch.object(type(client.transport), "close") as close: - close.assert_not_called() - with client: - pass - close.assert_called() - -@pytest.mark.parametrize("client_class,transport_class", [ - (SearchServiceClient, transports.SearchServiceGrpcTransport), - (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport), -]) -def test_api_key_credentials(client_class, transport_class): - with mock.patch.object( - google.auth._default, "get_api_key_credentials", create=True - ) as get_api_key_credentials: - mock_cred = mock.Mock() - get_api_key_credentials.return_value = mock_cred - options = client_options.ClientOptions() - options.api_key = "api_key" - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=mock_cred, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) diff --git a/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_user_event_service.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_user_event_service.py deleted file mode 100644 index 0bee3646..00000000 --- a/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_user_event_service.py +++ /dev/null @@ -1,1896 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import os -import mock - -import grpc -from grpc.experimental import aio -import math -import pytest -from proto.marshal.rules.dates import DurationRule, TimestampRule - - -from google.api import httpbody_pb2 # type: ignore -from google.api_core import client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import future -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers -from google.api_core import grpc_helpers_async -from google.api_core import operation_async # type: ignore -from google.api_core import operations_v1 -from google.api_core import path_template -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.cloud.retail_v2.services.user_event_service import UserEventServiceAsyncClient -from google.cloud.retail_v2.services.user_event_service import UserEventServiceClient -from google.cloud.retail_v2.services.user_event_service import transports -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 purge_config -from google.cloud.retail_v2.types import user_event -from google.cloud.retail_v2.types import user_event_service -from google.longrunning import operations_pb2 -from google.oauth2 import service_account -from google.protobuf import any_pb2 # type: ignore -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 -from google.type import date_pb2 # type: ignore -import google.auth - - -def client_cert_source_callback(): - return b"cert bytes", b"key bytes" - - -# If default endpoint is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint(client): - return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT - - -def test__get_default_mtls_endpoint(): - api_endpoint = "example.googleapis.com" - api_mtls_endpoint = "example.mtls.googleapis.com" - sandbox_endpoint = "example.sandbox.googleapis.com" - sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" - non_googleapi = "api.example.com" - - assert UserEventServiceClient._get_default_mtls_endpoint(None) is None - assert UserEventServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint - assert UserEventServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint - assert UserEventServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint - assert UserEventServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint - assert UserEventServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi - - -@pytest.mark.parametrize("client_class", [ - UserEventServiceClient, - UserEventServiceAsyncClient, -]) -def test_user_event_service_client_from_service_account_info(client_class): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: - factory.return_value = creds - info = {"valid": True} - client = client_class.from_service_account_info(info) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == 'retail.googleapis.com:443' - - -@pytest.mark.parametrize("transport_class,transport_name", [ - (transports.UserEventServiceGrpcTransport, "grpc"), - (transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -def test_user_event_service_client_service_account_always_use_jwt(transport_class, transport_name): - with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=True) - use_jwt.assert_called_once_with(True) - - with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=False) - use_jwt.assert_not_called() - - -@pytest.mark.parametrize("client_class", [ - UserEventServiceClient, - UserEventServiceAsyncClient, -]) -def test_user_event_service_client_from_service_account_file(client_class): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: - factory.return_value = creds - client = client_class.from_service_account_file("dummy/file/path.json") - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - client = client_class.from_service_account_json("dummy/file/path.json") - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == 'retail.googleapis.com:443' - - -def test_user_event_service_client_get_transport_class(): - transport = UserEventServiceClient.get_transport_class() - available_transports = [ - transports.UserEventServiceGrpcTransport, - ] - assert transport in available_transports - - transport = UserEventServiceClient.get_transport_class("grpc") - assert transport == transports.UserEventServiceGrpcTransport - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc"), - (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -@mock.patch.object(UserEventServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceClient)) -@mock.patch.object(UserEventServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceAsyncClient)) -def test_user_event_service_client_client_options(client_class, transport_class, transport_name): - # Check that if channel is provided we won't create a new one. - with mock.patch.object(UserEventServiceClient, 'get_transport_class') as gtc: - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ) - client = client_class(transport=transport) - gtc.assert_not_called() - - # Check that if channel is provided via str we will create a new one. - with mock.patch.object(UserEventServiceClient, 'get_transport_class') as gtc: - client = client_class(transport=transport_name) - gtc.assert_called() - - # Check the case api_endpoint is provided. - options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name, client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class(transport=transport_name) - - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): - with pytest.raises(ValueError): - client = client_class(transport=transport_name) - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - -@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ - (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc", "true"), - (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), - (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc", "false"), - (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), -]) -@mock.patch.object(UserEventServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceClient)) -@mock.patch.object(UserEventServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceAsyncClient)) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_user_event_service_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): - # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default - # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. - - # Check the case client_cert_source is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - - if use_client_cert_env == "false": - expected_client_cert_source = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_client_cert_source = client_cert_source_callback - expected_host = client.DEFAULT_MTLS_ENDPOINT - - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case ADC client cert is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - with mock.patch.object(transport_class, '__init__') as patched: - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): - with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): - if use_client_cert_env == "false": - expected_host = client.DEFAULT_ENDPOINT - expected_client_cert_source = None - else: - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_client_cert_source = client_cert_source_callback - - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - with mock.patch.object(transport_class, '__init__') as patched: - with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - -@pytest.mark.parametrize("client_class", [ - UserEventServiceClient, UserEventServiceAsyncClient -]) -@mock.patch.object(UserEventServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceClient)) -@mock.patch.object(UserEventServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceAsyncClient)) -def test_user_event_service_client_get_mtls_endpoint_and_cert_source(client_class): - mock_client_cert_source = mock.Mock() - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - mock_api_endpoint = "foo" - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source == mock_client_cert_source - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - mock_client_cert_source = mock.Mock() - mock_api_endpoint = "foo" - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): - with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source == mock_client_cert_source - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc"), - (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -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"], - ) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=["1", "2"], - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc"), - (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio"), -]) -def test_user_event_service_client_client_options_credentials_file(client_class, transport_class, transport_name): - # Check the case credentials file is provided. - options = client_options.ClientOptions( - credentials_file="credentials.json" - ) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file="credentials.json", - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - -def test_user_event_service_client_client_options_from_dict(): - with mock.patch('google.cloud.retail_v2.services.user_event_service.transports.UserEventServiceGrpcTransport.__init__') as grpc_transport: - grpc_transport.return_value = None - client = UserEventServiceClient( - client_options={'api_endpoint': 'squid.clam.whelk'} - ) - grpc_transport.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - -@pytest.mark.parametrize("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, - ) - - # 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.write_user_event), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = user_event.UserEvent( - event_type='event_type_value', - visitor_id='visitor_id_value', - session_id='session_id_value', - experiment_ids=['experiment_ids_value'], - attribution_token='attribution_token_value', - cart_id='cart_id_value', - search_query='search_query_value', - filter='filter_value', - order_by='order_by_value', - offset=647, - page_categories=['page_categories_value'], - uri='uri_value', - referrer_uri='referrer_uri_value', - page_view_id='page_view_id_value', - ) - response = client.write_user_event(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == user_event_service.WriteUserEventRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, user_event.UserEvent) - assert response.event_type == 'event_type_value' - assert response.visitor_id == 'visitor_id_value' - assert response.session_id == 'session_id_value' - assert response.experiment_ids == ['experiment_ids_value'] - assert response.attribution_token == 'attribution_token_value' - assert response.cart_id == 'cart_id_value' - assert response.search_query == 'search_query_value' - assert response.filter == 'filter_value' - assert response.order_by == 'order_by_value' - assert response.offset == 647 - assert response.page_categories == ['page_categories_value'] - assert response.uri == 'uri_value' - assert response.referrer_uri == 'referrer_uri_value' - assert response.page_view_id == 'page_view_id_value' - - -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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.write_user_event), - '__call__') as call: - client.write_user_event() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == user_event_service.WriteUserEventRequest() - - -@pytest.mark.asyncio -async def test_write_user_event_async(transport: str = 'grpc_asyncio', request_type=user_event_service.WriteUserEventRequest): - client = UserEventServiceAsyncClient( - 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.write_user_event), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(user_event.UserEvent( - event_type='event_type_value', - visitor_id='visitor_id_value', - session_id='session_id_value', - experiment_ids=['experiment_ids_value'], - attribution_token='attribution_token_value', - cart_id='cart_id_value', - search_query='search_query_value', - filter='filter_value', - order_by='order_by_value', - offset=647, - page_categories=['page_categories_value'], - uri='uri_value', - referrer_uri='referrer_uri_value', - page_view_id='page_view_id_value', - )) - response = await client.write_user_event(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == user_event_service.WriteUserEventRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, user_event.UserEvent) - assert response.event_type == 'event_type_value' - assert response.visitor_id == 'visitor_id_value' - assert response.session_id == 'session_id_value' - assert response.experiment_ids == ['experiment_ids_value'] - assert response.attribution_token == 'attribution_token_value' - assert response.cart_id == 'cart_id_value' - assert response.search_query == 'search_query_value' - assert response.filter == 'filter_value' - assert response.order_by == 'order_by_value' - assert response.offset == 647 - assert response.page_categories == ['page_categories_value'] - assert response.uri == 'uri_value' - assert response.referrer_uri == 'referrer_uri_value' - assert response.page_view_id == 'page_view_id_value' - - -@pytest.mark.asyncio -async def test_write_user_event_async_from_dict(): - await test_write_user_event_async(request_type=dict) - - -def test_write_user_event_field_headers(): - 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. - request = user_event_service.WriteUserEventRequest() - - request.parent = 'parent/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.write_user_event), - '__call__') as call: - call.return_value = user_event.UserEvent() - client.write_user_event(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'parent=parent/value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_write_user_event_field_headers_async(): - client = UserEventServiceAsyncClient( - 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 = user_event_service.WriteUserEventRequest() - - request.parent = 'parent/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.write_user_event), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(user_event.UserEvent()) - await client.write_user_event(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'parent=parent/value', - ) in kw['metadata'] - - -@pytest.mark.parametrize("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, - ) - - # 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.collect_user_event), - '__call__') 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', - ) - response = client.collect_user_event(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == user_event_service.CollectUserEventRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, httpbody_pb2.HttpBody) - assert response.content_type == 'content_type_value' - assert response.data == b'data_blob' - - -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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.collect_user_event), - '__call__') as call: - client.collect_user_event() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == user_event_service.CollectUserEventRequest() - - -@pytest.mark.asyncio -async def test_collect_user_event_async(transport: str = 'grpc_asyncio', request_type=user_event_service.CollectUserEventRequest): - client = UserEventServiceAsyncClient( - 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.collect_user_event), - '__call__') 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', - )) - response = await client.collect_user_event(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == user_event_service.CollectUserEventRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, httpbody_pb2.HttpBody) - assert response.content_type == 'content_type_value' - assert response.data == b'data_blob' - - -@pytest.mark.asyncio -async def test_collect_user_event_async_from_dict(): - await test_collect_user_event_async(request_type=dict) - - -def test_collect_user_event_field_headers(): - 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. - request = user_event_service.CollectUserEventRequest() - - request.parent = 'parent/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.collect_user_event), - '__call__') as call: - call.return_value = httpbody_pb2.HttpBody() - client.collect_user_event(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'parent=parent/value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_collect_user_event_field_headers_async(): - client = UserEventServiceAsyncClient( - 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 = user_event_service.CollectUserEventRequest() - - request.parent = 'parent/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.collect_user_event), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(httpbody_pb2.HttpBody()) - await client.collect_user_event(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'parent=parent/value', - ) in kw['metadata'] - - -@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, - ) - - # 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.purge_user_events), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation(name='operations/spam') - response = client.purge_user_events(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == purge_config.PurgeUserEventsRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.purge_user_events), - '__call__') as call: - client.purge_user_events() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == purge_config.PurgeUserEventsRequest() - - -@pytest.mark.asyncio -async def test_purge_user_events_async(transport: str = 'grpc_asyncio', request_type=purge_config.PurgeUserEventsRequest): - client = UserEventServiceAsyncClient( - 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.purge_user_events), - '__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.purge_user_events(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == purge_config.PurgeUserEventsRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -@pytest.mark.asyncio -async def test_purge_user_events_async_from_dict(): - await test_purge_user_events_async(request_type=dict) - - -def test_purge_user_events_field_headers(): - 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. - request = purge_config.PurgeUserEventsRequest() - - request.parent = 'parent/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.purge_user_events), - '__call__') as call: - call.return_value = operations_pb2.Operation(name='operations/op') - client.purge_user_events(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'parent=parent/value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_purge_user_events_field_headers_async(): - client = UserEventServiceAsyncClient( - 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 = purge_config.PurgeUserEventsRequest() - - request.parent = 'parent/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.purge_user_events), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) - await client.purge_user_events(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'parent=parent/value', - ) in kw['metadata'] - - -@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, - ) - - # 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.import_user_events), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation(name='operations/spam') - response = client.import_user_events(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == import_config.ImportUserEventsRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.import_user_events), - '__call__') as call: - client.import_user_events() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == import_config.ImportUserEventsRequest() - - -@pytest.mark.asyncio -async def test_import_user_events_async(transport: str = 'grpc_asyncio', request_type=import_config.ImportUserEventsRequest): - client = UserEventServiceAsyncClient( - 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.import_user_events), - '__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.import_user_events(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == import_config.ImportUserEventsRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -@pytest.mark.asyncio -async def test_import_user_events_async_from_dict(): - await test_import_user_events_async(request_type=dict) - - -def test_import_user_events_field_headers(): - 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. - request = import_config.ImportUserEventsRequest() - - request.parent = 'parent/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.import_user_events), - '__call__') as call: - call.return_value = operations_pb2.Operation(name='operations/op') - client.import_user_events(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'parent=parent/value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_import_user_events_field_headers_async(): - client = UserEventServiceAsyncClient( - 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 = import_config.ImportUserEventsRequest() - - request.parent = 'parent/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.import_user_events), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) - await client.import_user_events(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'parent=parent/value', - ) in kw['metadata'] - - -@pytest.mark.parametrize("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, - ) - - # 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.rejoin_user_events), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation(name='operations/spam') - response = client.rejoin_user_events(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == user_event_service.RejoinUserEventsRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -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', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.rejoin_user_events), - '__call__') as call: - client.rejoin_user_events() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == user_event_service.RejoinUserEventsRequest() - - -@pytest.mark.asyncio -async def test_rejoin_user_events_async(transport: str = 'grpc_asyncio', request_type=user_event_service.RejoinUserEventsRequest): - client = UserEventServiceAsyncClient( - 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.rejoin_user_events), - '__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.rejoin_user_events(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == user_event_service.RejoinUserEventsRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -@pytest.mark.asyncio -async def test_rejoin_user_events_async_from_dict(): - await test_rejoin_user_events_async(request_type=dict) - - -def test_rejoin_user_events_field_headers(): - 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. - request = user_event_service.RejoinUserEventsRequest() - - request.parent = 'parent/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.rejoin_user_events), - '__call__') as call: - call.return_value = operations_pb2.Operation(name='operations/op') - client.rejoin_user_events(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'parent=parent/value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_rejoin_user_events_field_headers_async(): - client = UserEventServiceAsyncClient( - 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 = user_event_service.RejoinUserEventsRequest() - - request.parent = 'parent/value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.rejoin_user_events), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) - await client.rejoin_user_events(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'parent=parent/value', - ) in kw['metadata'] - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.UserEventServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = UserEventServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.UserEventServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = UserEventServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.UserEventServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = UserEventServiceClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = mock.Mock() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = UserEventServiceClient( - client_options=options, - credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.UserEventServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = UserEventServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.UserEventServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = UserEventServiceClient(transport=transport) - assert client.transport is transport - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.UserEventServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.UserEventServiceGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize("transport_class", [ - transports.UserEventServiceGrpcTransport, - transports.UserEventServiceGrpcAsyncIOTransport, -]) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, 'default') as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - -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, - ) - -def test_user_event_service_base_transport_error(): - # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(core_exceptions.DuplicateCredentialArgs): - transport = transports.UserEventServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - credentials_file="credentials.json" - ) - - -def test_user_event_service_base_transport(): - # Instantiate the base transport. - with mock.patch('google.cloud.retail_v2.services.user_event_service.transports.UserEventServiceTransport.__init__') as Transport: - Transport.return_value = None - transport = transports.UserEventServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Every method on the transport should just blindly - # raise NotImplementedError. - methods = ( - 'write_user_event', - 'collect_user_event', - 'purge_user_events', - 'import_user_events', - 'rejoin_user_events', - ) - for method in methods: - with pytest.raises(NotImplementedError): - getattr(transport, method)(request=object()) - - with pytest.raises(NotImplementedError): - transport.close() - - # Additionally, the LRO client (a property) should - # also raise NotImplementedError - with pytest.raises(NotImplementedError): - transport.operations_client - - -def test_user_event_service_base_transport_with_credentials_file(): - # Instantiate the base transport with a credentials file - with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('google.cloud.retail_v2.services.user_event_service.transports.UserEventServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.UserEventServiceTransport( - credentials_file="credentials.json", - quota_project_id="octopus", - ) - load_creds.assert_called_once_with("credentials.json", - scopes=None, - default_scopes=( - 'https://www.googleapis.com/auth/cloud-platform', -), - quota_project_id="octopus", - ) - - -def test_user_event_service_base_transport_with_adc(): - # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(google.auth, 'default', autospec=True) as adc, mock.patch('google.cloud.retail_v2.services.user_event_service.transports.UserEventServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.UserEventServiceTransport() - adc.assert_called_once() - - -def test_user_event_service_auth_adc(): - # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(google.auth, 'default', autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - UserEventServiceClient() - adc.assert_called_once_with( - scopes=None, - default_scopes=( - 'https://www.googleapis.com/auth/cloud-platform', -), - quota_project_id=None, - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.UserEventServiceGrpcTransport, - transports.UserEventServiceGrpcAsyncIOTransport, - ], -) -def test_user_event_service_transport_auth_adc(transport_class): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, 'default', autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class(quota_project_id="octopus", scopes=["1", "2"]) - adc.assert_called_once_with( - scopes=["1", "2"], - default_scopes=( 'https://www.googleapis.com/auth/cloud-platform',), - quota_project_id="octopus", - ) - - -@pytest.mark.parametrize( - "transport_class,grpc_helpers", - [ - (transports.UserEventServiceGrpcTransport, grpc_helpers), - (transports.UserEventServiceGrpcAsyncIOTransport, grpc_helpers_async) - ], -) -def test_user_event_service_transport_create_channel(transport_class, grpc_helpers): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( - grpc_helpers, "create_channel", autospec=True - ) as create_channel: - creds = ga_credentials.AnonymousCredentials() - adc.return_value = (creds, None) - transport_class( - quota_project_id="octopus", - scopes=["1", "2"] - ) - - create_channel.assert_called_with( - "retail.googleapis.com:443", - credentials=creds, - credentials_file=None, - quota_project_id="octopus", - default_scopes=( - 'https://www.googleapis.com/auth/cloud-platform', -), - scopes=["1", "2"], - default_host="retail.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize("transport_class", [transports.UserEventServiceGrpcTransport, transports.UserEventServiceGrpcAsyncIOTransport]) -def test_user_event_service_grpc_transport_client_cert_source_for_mtls( - transport_class -): - cred = ga_credentials.AnonymousCredentials() - - # Check ssl_channel_credentials is used if provided. - with mock.patch.object(transport_class, "create_channel") as mock_create_channel: - mock_ssl_channel_creds = mock.Mock() - transport_class( - host="squid.clam.whelk", - credentials=cred, - ssl_channel_credentials=mock_ssl_channel_creds - ) - mock_create_channel.assert_called_once_with( - "squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_channel_creds, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls - # is used. - with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): - with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: - transport_class( - credentials=cred, - client_cert_source_for_mtls=client_cert_source_callback - ) - expected_cert, expected_key = client_cert_source_callback() - mock_ssl_cred.assert_called_once_with( - certificate_chain=expected_cert, - private_key=expected_key - ) - - -def test_user_event_service_host_no_port(): - client = UserEventServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), - ) - assert client.transport._host == 'retail.googleapis.com:443' - - -def test_user_event_service_host_with_port(): - client = UserEventServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), - ) - assert client.transport._host == 'retail.googleapis.com:8000' - -def test_user_event_service_grpc_transport_channel(): - channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.UserEventServiceGrpcTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -def test_user_event_service_grpc_asyncio_transport_channel(): - channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.UserEventServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.parametrize("transport_class", [transports.UserEventServiceGrpcTransport, transports.UserEventServiceGrpcAsyncIOTransport]) -def test_user_event_service_transport_channel_mtls_with_client_cert_source( - transport_class -): - with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: - with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - cred = ga_credentials.AnonymousCredentials() - with pytest.warns(DeprecationWarning): - with mock.patch.object(google.auth, 'default') as adc: - adc.return_value = (cred, None) - transport = transport_class( - host="squid.clam.whelk", - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - adc.assert_called_once() - - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - assert transport._ssl_channel_credentials == mock_ssl_cred - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.parametrize("transport_class", [transports.UserEventServiceGrpcTransport, transports.UserEventServiceGrpcAsyncIOTransport]) -def test_user_event_service_transport_channel_mtls_with_adc( - transport_class -): - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - mock_cred = mock.Mock() - - with pytest.warns(DeprecationWarning): - transport = transport_class( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=None, - ) - - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - - -def test_user_event_service_grpc_lro_client(): - client = UserEventServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - transport = client.transport - - # Ensure that we have a api-core operations client. - assert isinstance( - transport.operations_client, - operations_v1.OperationsClient, - ) - - # Ensure that subsequent calls to the property send the exact same object. - assert transport.operations_client is transport.operations_client - - -def test_user_event_service_grpc_lro_async_client(): - client = UserEventServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc_asyncio', - ) - transport = client.transport - - # Ensure that we have a api-core operations client. - assert isinstance( - transport.operations_client, - operations_v1.OperationsAsyncClient, - ) - - # Ensure that subsequent calls to the property send the exact same object. - assert transport.operations_client is transport.operations_client - - -def test_catalog_path(): - project = "squid" - location = "clam" - catalog = "whelk" - expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) - actual = UserEventServiceClient.catalog_path(project, location, catalog) - assert expected == actual - - -def test_parse_catalog_path(): - expected = { - "project": "octopus", - "location": "oyster", - "catalog": "nudibranch", - } - path = UserEventServiceClient.catalog_path(**expected) - - # Check that the path construction is reversible. - actual = UserEventServiceClient.parse_catalog_path(path) - assert expected == actual - -def test_product_path(): - project = "cuttlefish" - location = "mussel" - catalog = "winkle" - branch = "nautilus" - product = "scallop" - expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, product=product, ) - actual = UserEventServiceClient.product_path(project, location, catalog, branch, product) - assert expected == actual - - -def test_parse_product_path(): - expected = { - "project": "abalone", - "location": "squid", - "catalog": "clam", - "branch": "whelk", - "product": "octopus", - } - path = UserEventServiceClient.product_path(**expected) - - # Check that the path construction is reversible. - actual = UserEventServiceClient.parse_product_path(path) - assert expected == actual - -def test_common_billing_account_path(): - billing_account = "oyster" - expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) - actual = UserEventServiceClient.common_billing_account_path(billing_account) - assert expected == actual - - -def test_parse_common_billing_account_path(): - expected = { - "billing_account": "nudibranch", - } - path = UserEventServiceClient.common_billing_account_path(**expected) - - # Check that the path construction is reversible. - actual = UserEventServiceClient.parse_common_billing_account_path(path) - assert expected == actual - -def test_common_folder_path(): - folder = "cuttlefish" - expected = "folders/{folder}".format(folder=folder, ) - actual = UserEventServiceClient.common_folder_path(folder) - assert expected == actual - - -def test_parse_common_folder_path(): - expected = { - "folder": "mussel", - } - path = UserEventServiceClient.common_folder_path(**expected) - - # Check that the path construction is reversible. - actual = UserEventServiceClient.parse_common_folder_path(path) - assert expected == actual - -def test_common_organization_path(): - organization = "winkle" - expected = "organizations/{organization}".format(organization=organization, ) - actual = UserEventServiceClient.common_organization_path(organization) - assert expected == actual - - -def test_parse_common_organization_path(): - expected = { - "organization": "nautilus", - } - path = UserEventServiceClient.common_organization_path(**expected) - - # Check that the path construction is reversible. - actual = UserEventServiceClient.parse_common_organization_path(path) - assert expected == actual - -def test_common_project_path(): - project = "scallop" - expected = "projects/{project}".format(project=project, ) - actual = UserEventServiceClient.common_project_path(project) - assert expected == actual - - -def test_parse_common_project_path(): - expected = { - "project": "abalone", - } - path = UserEventServiceClient.common_project_path(**expected) - - # Check that the path construction is reversible. - actual = UserEventServiceClient.parse_common_project_path(path) - assert expected == actual - -def test_common_location_path(): - project = "squid" - location = "clam" - expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) - actual = UserEventServiceClient.common_location_path(project, location) - assert expected == actual - - -def test_parse_common_location_path(): - expected = { - "project": "whelk", - "location": "octopus", - } - path = UserEventServiceClient.common_location_path(**expected) - - # Check that the path construction is reversible. - actual = UserEventServiceClient.parse_common_location_path(path) - assert expected == actual - - -def test_client_with_default_client_info(): - client_info = gapic_v1.client_info.ClientInfo() - - with mock.patch.object(transports.UserEventServiceTransport, '_prep_wrapped_messages') as prep: - client = UserEventServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - with mock.patch.object(transports.UserEventServiceTransport, '_prep_wrapped_messages') as prep: - transport_class = UserEventServiceClient.get_transport_class() - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - -@pytest.mark.asyncio -async def test_transport_close_async(): - client = UserEventServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - with mock.patch.object(type(getattr(client.transport, "grpc_channel")), "close") as close: - async with client: - close.assert_not_called() - close.assert_called_once() - -def test_transport_close(): - transports = { - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = UserEventServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport - ) - with mock.patch.object(type(getattr(client.transport, close_name)), "close") as close: - with client: - close.assert_not_called() - close.assert_called_once() - -def test_client_ctx(): - transports = [ - 'grpc', - ] - for transport in transports: - client = UserEventServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport - ) - # Test client calls underlying transport. - with mock.patch.object(type(client.transport), "close") as close: - close.assert_not_called() - with client: - pass - close.assert_called() - -@pytest.mark.parametrize("client_class,transport_class", [ - (UserEventServiceClient, transports.UserEventServiceGrpcTransport), - (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport), -]) -def test_api_key_credentials(client_class, transport_class): - with mock.patch.object( - google.auth._default, "get_api_key_credentials", create=True - ) as get_api_key_credentials: - mock_cred = mock.Mock() - get_api_key_credentials.return_value = mock_cred - options = client_options.ClientOptions() - options.api_key = "api_key" - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=mock_cred, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) diff --git a/tests/unit/gapic/retail_v2/test_catalog_service.py b/tests/unit/gapic/retail_v2/test_catalog_service.py index 6f92883c..03b279a7 100644 --- a/tests/unit/gapic/retail_v2/test_catalog_service.py +++ b/tests/unit/gapic/retail_v2/test_catalog_service.py @@ -399,6 +399,87 @@ def test_catalog_service_client_mtls_env_auto( ) +@pytest.mark.parametrize( + "client_class", [CatalogServiceClient, CatalogServiceAsyncClient] +) +@mock.patch.object( + CatalogServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(CatalogServiceClient), +) +@mock.patch.object( + CatalogServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(CatalogServiceAsyncClient), +) +def test_catalog_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + @pytest.mark.parametrize( "client_class,transport_class,transport_name", [ @@ -1487,6 +1568,23 @@ def test_credentials_transport_error(): transport=transport, ) + # It is an error to provide an api_key and a transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CatalogServiceClient(client_options=options, transport=transport,) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CatalogServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + # It is an error to provide scopes and a transport instance. transport = transports.CatalogServiceGrpcTransport( credentials=ga_credentials.AnonymousCredentials(), @@ -2075,3 +2173,33 @@ def test_client_ctx(): with client: pass close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) diff --git a/tests/unit/gapic/retail_v2/test_completion_service.py b/tests/unit/gapic/retail_v2/test_completion_service.py index b051621e..0aeea305 100644 --- a/tests/unit/gapic/retail_v2/test_completion_service.py +++ b/tests/unit/gapic/retail_v2/test_completion_service.py @@ -413,6 +413,87 @@ def test_completion_service_client_mtls_env_auto( ) +@pytest.mark.parametrize( + "client_class", [CompletionServiceClient, CompletionServiceAsyncClient] +) +@mock.patch.object( + CompletionServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(CompletionServiceClient), +) +@mock.patch.object( + CompletionServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(CompletionServiceAsyncClient), +) +def test_completion_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + @pytest.mark.parametrize( "client_class,transport_class,transport_name", [ @@ -791,6 +872,23 @@ def test_credentials_transport_error(): transport=transport, ) + # It is an error to provide an api_key and a transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CompletionServiceClient(client_options=options, transport=transport,) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CompletionServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + # It is an error to provide scopes and a transport instance. transport = transports.CompletionServiceGrpcTransport( credentials=ga_credentials.AnonymousCredentials(), @@ -1382,3 +1480,36 @@ def test_client_ctx(): with client: pass close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport), + ( + CompletionServiceAsyncClient, + transports.CompletionServiceGrpcAsyncIOTransport, + ), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) diff --git a/tests/unit/gapic/retail_v2/test_prediction_service.py b/tests/unit/gapic/retail_v2/test_prediction_service.py index ecdeee74..91d3b1c6 100644 --- a/tests/unit/gapic/retail_v2/test_prediction_service.py +++ b/tests/unit/gapic/retail_v2/test_prediction_service.py @@ -415,6 +415,87 @@ def test_prediction_service_client_mtls_env_auto( ) +@pytest.mark.parametrize( + "client_class", [PredictionServiceClient, PredictionServiceAsyncClient] +) +@mock.patch.object( + PredictionServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(PredictionServiceClient), +) +@mock.patch.object( + PredictionServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(PredictionServiceAsyncClient), +) +def test_prediction_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + @pytest.mark.parametrize( "client_class,transport_class,transport_name", [ @@ -658,6 +739,23 @@ def test_credentials_transport_error(): transport=transport, ) + # It is an error to provide an api_key and a transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = PredictionServiceClient(client_options=options, transport=transport,) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = PredictionServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + # It is an error to provide scopes and a transport instance. transport = transports.PredictionServiceGrpcTransport( credentials=ga_credentials.AnonymousCredentials(), @@ -1225,3 +1323,36 @@ def test_client_ctx(): with client: pass close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport), + ( + PredictionServiceAsyncClient, + transports.PredictionServiceGrpcAsyncIOTransport, + ), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) diff --git a/tests/unit/gapic/retail_v2/test_product_service.py b/tests/unit/gapic/retail_v2/test_product_service.py index 098642e7..7d6d3803 100644 --- a/tests/unit/gapic/retail_v2/test_product_service.py +++ b/tests/unit/gapic/retail_v2/test_product_service.py @@ -408,6 +408,87 @@ def test_product_service_client_mtls_env_auto( ) +@pytest.mark.parametrize( + "client_class", [ProductServiceClient, ProductServiceAsyncClient] +) +@mock.patch.object( + ProductServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(ProductServiceClient), +) +@mock.patch.object( + ProductServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(ProductServiceAsyncClient), +) +def test_product_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + @pytest.mark.parametrize( "client_class,transport_class,transport_name", [ @@ -2684,6 +2765,23 @@ def test_credentials_transport_error(): 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,) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ProductServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + # It is an error to provide scopes and a transport instance. transport = transports.ProductServiceGrpcTransport( credentials=ga_credentials.AnonymousCredentials(), @@ -3318,3 +3416,33 @@ def test_client_ctx(): with client: pass close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (ProductServiceClient, transports.ProductServiceGrpcTransport), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) diff --git a/tests/unit/gapic/retail_v2/test_search_service.py b/tests/unit/gapic/retail_v2/test_search_service.py index 7989cde0..0ad63fef 100644 --- a/tests/unit/gapic/retail_v2/test_search_service.py +++ b/tests/unit/gapic/retail_v2/test_search_service.py @@ -396,6 +396,87 @@ def test_search_service_client_mtls_env_auto( ) +@pytest.mark.parametrize( + "client_class", [SearchServiceClient, SearchServiceAsyncClient] +) +@mock.patch.object( + SearchServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(SearchServiceClient), +) +@mock.patch.object( + SearchServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(SearchServiceAsyncClient), +) +def test_search_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + @pytest.mark.parametrize( "client_class,transport_class,transport_name", [ @@ -809,6 +890,23 @@ def test_credentials_transport_error(): transport=transport, ) + # It is an error to provide an api_key and a transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = SearchServiceClient(client_options=options, transport=transport,) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = SearchServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + # It is an error to provide scopes and a transport instance. transport = transports.SearchServiceGrpcTransport( credentials=ga_credentials.AnonymousCredentials(), @@ -1400,3 +1498,33 @@ def test_client_ctx(): with client: pass close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (SearchServiceClient, transports.SearchServiceGrpcTransport), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) 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 ee8b1dc4..5805d995 100644 --- a/tests/unit/gapic/retail_v2/test_user_event_service.py +++ b/tests/unit/gapic/retail_v2/test_user_event_service.py @@ -423,6 +423,87 @@ def test_user_event_service_client_mtls_env_auto( ) +@pytest.mark.parametrize( + "client_class", [UserEventServiceClient, UserEventServiceAsyncClient] +) +@mock.patch.object( + UserEventServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(UserEventServiceClient), +) +@mock.patch.object( + UserEventServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(UserEventServiceAsyncClient), +) +def test_user_event_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + @pytest.mark.parametrize( "client_class,transport_class,transport_name", [ @@ -1273,6 +1354,23 @@ def test_credentials_transport_error(): transport=transport, ) + # It is an error to provide an api_key and a transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = UserEventServiceClient(client_options=options, transport=transport,) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = UserEventServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + # It is an error to provide scopes and a transport instance. transport = transports.UserEventServiceGrpcTransport( credentials=ga_credentials.AnonymousCredentials(), @@ -1901,3 +1999,33 @@ def test_client_ctx(): with client: pass close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + )